X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Faxgbe%2Faxgbe_ethdev.c;h=0c25739f829aeb8c35f78d7def95526ebaabadd5;hb=675911d0330b0802e845657c3f4edc5886cf8685;hp=867058845ee12b0e3b5b9705e55c0e393f83db3a;hpb=0962b6055c080699f93ef986327e536d4707853a;p=dpdk.git diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c index 867058845e..0c25739f82 100644 --- a/drivers/net/axgbe/axgbe_ethdev.c +++ b/drivers/net/axgbe/axgbe_ethdev.c @@ -60,6 +60,16 @@ axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, const uint64_t *ids, unsigned int size); static int axgbe_dev_xstats_reset(struct rte_eth_dev *dev); +static int axgbe_dev_rss_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size); +static int axgbe_dev_rss_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size); +static int axgbe_dev_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); +static int axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); static int axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info); static int axgbe_flow_ctrl_get(struct rte_eth_dev *dev, @@ -73,6 +83,7 @@ static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_txq_info *qinfo); const uint32_t *axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev); +static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); struct axgbe_xstats { char name[RTE_ETH_XSTATS_NAME_SIZE]; @@ -132,9 +143,6 @@ static const struct axgbe_xstats axgbe_xstats_strings[] = { #define AMD_PCI_AXGBE_DEVICE_V2A 0x1458 #define AMD_PCI_AXGBE_DEVICE_V2B 0x1459 -int axgbe_logtype_init; -int axgbe_logtype_driver; - static const struct rte_pci_id pci_id_axgbe_map[] = { {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2A)}, {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2B)}, @@ -201,6 +209,10 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = { .xstats_get_names = axgbe_dev_xstats_get_names, .xstats_get_names_by_id = axgbe_dev_xstats_get_names_by_id, .xstats_get_by_id = axgbe_dev_xstats_get_by_id, + .reta_update = axgbe_dev_rss_reta_update, + .reta_query = axgbe_dev_rss_reta_query, + .rss_hash_update = axgbe_dev_rss_hash_update, + .rss_hash_conf_get = axgbe_dev_rss_hash_conf_get, .dev_infos_get = axgbe_dev_info_get, .rx_queue_setup = axgbe_dev_rx_queue_setup, .rx_queue_release = axgbe_dev_rx_queue_release, @@ -214,6 +226,7 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = { .dev_supported_ptypes_get = axgbe_dev_supported_ptypes_get, .rx_descriptor_status = axgbe_dev_rx_descriptor_status, .tx_descriptor_status = axgbe_dev_tx_descriptor_status, + .mtu_set = axgb_mtu_set, }; static int axgbe_phy_reset(struct axgbe_port *pdata) @@ -327,8 +340,8 @@ axgbe_dev_start(struct rte_eth_dev *dev) axgbe_dev_enable_tx(dev); axgbe_dev_enable_rx(dev); - axgbe_clear_bit(AXGBE_STOPPED, &pdata->dev_state); - axgbe_clear_bit(AXGBE_DOWN, &pdata->dev_state); + rte_bit_relaxed_clear32(AXGBE_STOPPED, &pdata->dev_state); + rte_bit_relaxed_clear32(AXGBE_DOWN, &pdata->dev_state); if ((dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) || max_pkt_len > pdata->rx_buf_size) dev_data->scattered_rx = 1; @@ -352,17 +365,17 @@ axgbe_dev_stop(struct rte_eth_dev *dev) rte_intr_disable(&pdata->pci_dev->intr_handle); - if (axgbe_test_bit(AXGBE_STOPPED, &pdata->dev_state)) + if (rte_bit_relaxed_get32(AXGBE_STOPPED, &pdata->dev_state)) return; - axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state); + rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state); axgbe_dev_disable_tx(dev); axgbe_dev_disable_rx(dev); pdata->phy_if.phy_stop(pdata); pdata->hw_if.exit(pdata); memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link)); - axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state); + rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state); } /* Clear all resources like TX/RX queues. */ @@ -450,6 +463,136 @@ axgbe_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, return 0; } +static int +axgbe_dev_rss_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + struct axgbe_port *pdata = dev->data->dev_private; + unsigned int i, idx, shift; + int ret; + + if (!pdata->rss_enable) { + PMD_DRV_LOG(ERR, "RSS not enabled\n"); + return -ENOTSUP; + } + + if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) { + PMD_DRV_LOG(ERR, "reta_size %d is not supported\n", reta_size); + return -EINVAL; + } + + for (i = 0; i < reta_size; i++) { + idx = i / RTE_RETA_GROUP_SIZE; + shift = i % RTE_RETA_GROUP_SIZE; + if ((reta_conf[idx].mask & (1ULL << shift)) == 0) + continue; + pdata->rss_table[i] = reta_conf[idx].reta[shift]; + } + + /* Program the lookup table */ + ret = axgbe_write_rss_lookup_table(pdata); + return ret; +} + +static int +axgbe_dev_rss_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + struct axgbe_port *pdata = dev->data->dev_private; + unsigned int i, idx, shift; + + if (!pdata->rss_enable) { + PMD_DRV_LOG(ERR, "RSS not enabled\n"); + return -ENOTSUP; + } + + if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) { + PMD_DRV_LOG(ERR, "reta_size %d is not supported\n", reta_size); + return -EINVAL; + } + + for (i = 0; i < reta_size; i++) { + idx = i / RTE_RETA_GROUP_SIZE; + shift = i % RTE_RETA_GROUP_SIZE; + if ((reta_conf[idx].mask & (1ULL << shift)) == 0) + continue; + reta_conf[idx].reta[shift] = pdata->rss_table[i]; + } + return 0; +} + +static int +axgbe_dev_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct axgbe_port *pdata = dev->data->dev_private; + int ret; + + if (!pdata->rss_enable) { + PMD_DRV_LOG(ERR, "RSS not enabled\n"); + return -ENOTSUP; + } + + if (rss_conf == NULL) { + PMD_DRV_LOG(ERR, "rss_conf value isn't valid\n"); + return -EINVAL; + } + + if (rss_conf->rss_key != NULL && + rss_conf->rss_key_len == AXGBE_RSS_HASH_KEY_SIZE) { + rte_memcpy(pdata->rss_key, rss_conf->rss_key, + AXGBE_RSS_HASH_KEY_SIZE); + /* Program the hash key */ + ret = axgbe_write_rss_hash_key(pdata); + if (ret != 0) + return ret; + } + + pdata->rss_hf = rss_conf->rss_hf & AXGBE_RSS_OFFLOAD; + + if (pdata->rss_hf & (ETH_RSS_IPV4 | ETH_RSS_IPV6)) + AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1); + if (pdata->rss_hf & + (ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV6_TCP)) + AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1); + if (pdata->rss_hf & + (ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP)) + AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); + + /* Set the RSS options */ + AXGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options); + + return 0; +} + +static int +axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct axgbe_port *pdata = dev->data->dev_private; + + if (!pdata->rss_enable) { + PMD_DRV_LOG(ERR, "RSS not enabled\n"); + return -ENOTSUP; + } + + if (rss_conf == NULL) { + PMD_DRV_LOG(ERR, "rss_conf value isn't valid\n"); + return -EINVAL; + } + + if (rss_conf->rss_key != NULL && + rss_conf->rss_key_len >= AXGBE_RSS_HASH_KEY_SIZE) { + rte_memcpy(rss_conf->rss_key, pdata->rss_key, + AXGBE_RSS_HASH_KEY_SIZE); + } + rss_conf->rss_key_len = AXGBE_RSS_HASH_KEY_SIZE; + rss_conf->rss_hf = pdata->rss_hf; + return 0; +} + static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) { @@ -1254,7 +1397,35 @@ axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev) return ptypes; return NULL; } - +static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +{ + struct rte_eth_dev_info dev_info; + struct axgbe_port *pdata = dev->data->dev_private; + uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; + unsigned int val = 0; + axgbe_dev_info_get(dev, &dev_info); + /* check that mtu is within the allowed range */ + if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) + return -EINVAL; + /* mtu setting is forbidden if port is start */ + if (dev->data->dev_started) { + PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", + dev->data->port_id); + return -EBUSY; + } + if (frame_size > RTE_ETHER_MAX_LEN) { + dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_JUMBO_FRAME; + val = 1; + } else { + dev->data->dev_conf.rxmode.offloads &= + ~DEV_RX_OFFLOAD_JUMBO_FRAME; + val = 0; + } + AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val); + dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size; + return 0; +} static void axgbe_get_all_hw_features(struct axgbe_port *pdata) { unsigned int mac_hfr0, mac_hfr1, mac_hfr2; @@ -1470,8 +1641,8 @@ eth_axgbe_dev_init(struct rte_eth_dev *eth_dev) pdata = eth_dev->data->dev_private; /* initial state */ - axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state); - axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state); + rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state); + rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state); pdata->eth_dev = eth_dev; pci_dev = RTE_DEV_TO_PCI(eth_dev->device); @@ -1668,13 +1839,5 @@ static struct rte_pci_driver rte_axgbe_pmd = { RTE_PMD_REGISTER_PCI(net_axgbe, rte_axgbe_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_axgbe, pci_id_axgbe_map); RTE_PMD_REGISTER_KMOD_DEP(net_axgbe, "* igb_uio | uio_pci_generic | vfio-pci"); - -RTE_INIT(axgbe_init_log) -{ - axgbe_logtype_init = rte_log_register("pmd.net.axgbe.init"); - if (axgbe_logtype_init >= 0) - rte_log_set_level(axgbe_logtype_init, RTE_LOG_NOTICE); - axgbe_logtype_driver = rte_log_register("pmd.net.axgbe.driver"); - if (axgbe_logtype_driver >= 0) - rte_log_set_level(axgbe_logtype_driver, RTE_LOG_NOTICE); -} +RTE_LOG_REGISTER(axgbe_logtype_init, pmd.net.axgbe.init, NOTICE); +RTE_LOG_REGISTER(axgbe_logtype_driver, pmd.net.axgbe.driver, NOTICE);