X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Focteontx%2Focteontx_ethdev.c;h=e8aa4ec78b1056ee4ffae28e362523aa90a77181;hb=e505ac7f91b59e1165c143f14b208885658d2f94;hp=5431b44dc01c403e1878f98fa4565d05b0ea6475;hpb=4852aa8f6e2125664698afc43b820bd787b02756;p=dpdk.git diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c index 5431b44dc0..e8aa4ec78b 100644 --- a/drivers/net/octeontx/octeontx_ethdev.c +++ b/drivers/net/octeontx/octeontx_ethdev.c @@ -142,7 +142,8 @@ octeontx_port_open(struct octeontx_nic *nic) nic->mcast_mode = bgx_port_conf.mcast_mode; nic->speed = bgx_port_conf.mode; - memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN); + memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], + RTE_ETHER_ADDR_LEN); octeontx_log_dbg("port opened %d", nic->port_id); return res; @@ -173,7 +174,7 @@ octeontx_port_stop(struct octeontx_nic *nic) return octeontx_bgx_port_stop(nic->port_id); } -static void +static int octeontx_port_promisc_set(struct octeontx_nic *nic, int en) { struct rte_eth_dev *dev; @@ -184,15 +185,19 @@ octeontx_port_promisc_set(struct octeontx_nic *nic, int en) dev = nic->dev; res = octeontx_bgx_port_promisc_set(nic->port_id, en); - if (res < 0) + if (res < 0) { octeontx_log_err("failed to set promiscuous mode %d", nic->port_id); + return res; + } /* Set proper flag for the mode */ dev->data->promiscuous = (en != 0) ? 1 : 0; octeontx_log_dbg("port %d : promiscuous mode %s", nic->port_id, en ? "set" : "unset"); + + return 0; } static int @@ -223,12 +228,12 @@ octeontx_port_stats(struct octeontx_nic *nic, struct rte_eth_stats *stats) return 0; } -static void +static int octeontx_port_stats_clr(struct octeontx_nic *nic) { PMD_INIT_FUNC_TRACE(); - octeontx_bgx_port_stats_clr(nic->port_id); + return octeontx_bgx_port_stats_clr(nic->port_id); } static inline void @@ -303,7 +308,7 @@ octeontx_dev_configure(struct rte_eth_dev *dev) nic->num_tx_queues = dev->data->nb_tx_queues; - ret = octeontx_pko_channel_open(nic->port_id * PKO_VF_NUM_DQ, + ret = octeontx_pko_channel_open(nic->pko_vfid * PKO_VF_NUM_DQ, nic->num_tx_queues, nic->base_ochan); if (ret) { @@ -346,6 +351,10 @@ octeontx_dev_close(struct rte_eth_dev *dev) rte_free(txq); } + /* Free MAC address table */ + rte_free(dev->data->mac_addrs); + dev->data->mac_addrs = NULL; + dev->tx_pkt_burst = NULL; dev->rx_pkt_burst = NULL; } @@ -443,22 +452,22 @@ octeontx_dev_stop(struct rte_eth_dev *dev) } } -static void +static int octeontx_dev_promisc_enable(struct rte_eth_dev *dev) { struct octeontx_nic *nic = octeontx_pmd_priv(dev); PMD_INIT_FUNC_TRACE(); - octeontx_port_promisc_set(nic, 1); + return octeontx_port_promisc_set(nic, 1); } -static void +static int octeontx_dev_promisc_disable(struct rte_eth_dev *dev) { struct octeontx_nic *nic = octeontx_pmd_priv(dev); PMD_INIT_FUNC_TRACE(); - octeontx_port_promisc_set(nic, 0); + return octeontx_port_promisc_set(nic, 0); } static int @@ -544,35 +553,76 @@ octeontx_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) return octeontx_port_stats(nic, stats); } -static void +static int octeontx_dev_stats_reset(struct rte_eth_dev *dev) { struct octeontx_nic *nic = octeontx_pmd_priv(dev); PMD_INIT_FUNC_TRACE(); - octeontx_port_stats_clr(nic); + return octeontx_port_stats_clr(nic); +} + +static void +octeontx_dev_mac_addr_del(struct rte_eth_dev *dev, uint32_t index) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + int ret; + + ret = octeontx_bgx_port_mac_del(nic->port_id, index); + if (ret != 0) + octeontx_log_err("failed to del MAC address filter on port %d", + nic->port_id); +} + +static int +octeontx_dev_mac_addr_add(struct rte_eth_dev *dev, + struct rte_ether_addr *mac_addr, + uint32_t index, + __rte_unused uint32_t vmdq) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + int ret; + + ret = octeontx_bgx_port_mac_add(nic->port_id, mac_addr->addr_bytes, + index); + if (ret < 0) { + octeontx_log_err("failed to add MAC address filter on port %d", + nic->port_id); + return ret; + } + + return 0; } static int octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev, - struct ether_addr *addr) + struct rte_ether_addr *addr) { struct octeontx_nic *nic = octeontx_pmd_priv(dev); + uint8_t prom_mode = dev->data->promiscuous; int ret; + dev->data->promiscuous = 0; ret = octeontx_bgx_port_mac_set(nic->port_id, addr->addr_bytes); - if (ret != 0) + if (ret == 0) { + /* Update same mac address to BGX CAM table */ + ret = octeontx_bgx_port_mac_add(nic->port_id, addr->addr_bytes, + 0); + } + if (ret < 0) { + dev->data->promiscuous = prom_mode; octeontx_log_err("failed to set MAC address on port %d", - nic->port_id); + nic->port_id); + } return ret; } -static void +static int octeontx_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { - RTE_SET_USED(dev); + struct octeontx_nic *nic = octeontx_pmd_priv(dev); /* Autonegotiation may be disabled */ dev_info->speed_capa = ETH_LINK_SPEED_FIXED; @@ -580,7 +630,8 @@ octeontx_dev_info(struct rte_eth_dev *dev, ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G; - dev_info->max_mac_addrs = 1; + dev_info->max_mac_addrs = + octeontx_bgx_port_mac_entries_get(nic->port_id); dev_info->max_rx_pktlen = PKI_MAX_PKTLEN; dev_info->max_rx_queues = 1; dev_info->max_tx_queues = PKO_MAX_NUM_DQ; @@ -599,6 +650,10 @@ octeontx_dev_info(struct rte_eth_dev *dev, dev_info->rx_offload_capa = OCTEONTX_RX_OFFLOADS; dev_info->tx_offload_capa = OCTEONTX_TX_OFFLOADS; + dev_info->rx_queue_offload_capa = OCTEONTX_RX_OFFLOADS; + dev_info->tx_queue_offload_capa = OCTEONTX_TX_OFFLOADS; + + return 0; } static void @@ -712,7 +767,7 @@ octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, RTE_SET_USED(nb_desc); RTE_SET_USED(socket_id); - dq_num = (nic->port_id * PKO_VF_NUM_DQ) + qidx; + dq_num = (nic->pko_vfid * PKO_VF_NUM_DQ) + qidx; /* Socket id check */ if (socket_id != (unsigned int)SOCKET_ID_ANY && @@ -844,10 +899,11 @@ octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, pktbuf_conf.mmask.f_cache_mode = 1; pktbuf_conf.wqe_skip = OCTTX_PACKET_WQE_SKIP; - pktbuf_conf.first_skip = OCTTX_PACKET_FIRST_SKIP; + pktbuf_conf.first_skip = OCTTX_PACKET_FIRST_SKIP(mb_pool); pktbuf_conf.later_skip = OCTTX_PACKET_LATER_SKIP; pktbuf_conf.mbuff_size = (mb_pool->elt_size - RTE_PKTMBUF_HEADROOM - + rte_pktmbuf_priv_size(mb_pool) - sizeof(struct rte_mbuf)); pktbuf_conf.cache_mode = PKI_OPC_MODE_STF2_STT; @@ -976,6 +1032,8 @@ static const struct eth_dev_ops octeontx_dev_ops = { .link_update = octeontx_dev_link_update, .stats_get = octeontx_dev_stats_get, .stats_reset = octeontx_dev_stats_reset, + .mac_addr_remove = octeontx_dev_mac_addr_del, + .mac_addr_add = octeontx_dev_mac_addr_add, .mac_addr_set = octeontx_dev_default_mac_addr_set, .tx_queue_start = octeontx_dev_tx_queue_start, .tx_queue_stop = octeontx_dev_tx_queue_stop, @@ -993,11 +1051,13 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, int socket_id) { int res; + size_t pko_vfid; char octtx_name[OCTEONTX_MAX_NAME_LEN]; struct octeontx_nic *nic = NULL; struct rte_eth_dev *eth_dev = NULL; struct rte_eth_dev_data *data; const char *name = rte_vdev_device_name(dev); + int max_entries; PMD_INIT_FUNC_TRACE(); @@ -1015,13 +1075,31 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, return 0; } + /* Reserve an ethdev entry */ + eth_dev = rte_eth_dev_allocate(octtx_name); + if (eth_dev == NULL) { + octeontx_log_err("failed to allocate rte_eth_dev"); + res = -ENOMEM; + goto err; + } + data = eth_dev->data; + nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id); if (nic == NULL) { octeontx_log_err("failed to allocate nic structure"); res = -ENOMEM; goto err; } + data->dev_private = nic; + pko_vfid = octeontx_pko_get_vfid(); + if (pko_vfid == SIZE_MAX) { + octeontx_log_err("failed to get pko vfid"); + res = -ENODEV; + goto err; + } + + nic->pko_vfid = pko_vfid; nic->port_id = port; nic->evdev = evdev; @@ -1037,21 +1115,11 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, goto err; } - /* Reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(octtx_name); - if (eth_dev == NULL) { - octeontx_log_err("failed to allocate rte_eth_dev"); - res = -ENOMEM; - goto err; - } - eth_dev->device = &dev->device; eth_dev->intr_handle = NULL; eth_dev->data->kdrv = RTE_KDRV_NONE; eth_dev->data->numa_node = dev->device.numa_node; - data = eth_dev->data; - data->dev_private = nic; data->port_id = eth_dev->data->port_id; nic->ev_queues = 1; @@ -1063,7 +1131,16 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, data->all_multicast = 0; data->scattered_rx = 0; - data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0, + /* Get maximum number of supported MAC entries */ + max_entries = octeontx_bgx_port_mac_entries_get(nic->port_id); + if (max_entries < 0) { + octeontx_log_err("Failed to get max entries for mac addr"); + res = -ENOTSUP; + goto err; + } + + data->mac_addrs = rte_zmalloc_socket(octtx_name, max_entries * + RTE_ETHER_ADDR_LEN, 0, socket_id); if (data->mac_addrs == NULL) { octeontx_log_err("failed to allocate memory for mac_addrs"); @@ -1080,11 +1157,14 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)", data->port_id, nic->port_id); res = -EINVAL; - goto err; + goto free_mac_addrs; } /* Update port_id mac to eth_dev */ - memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN); + memcpy(data->mac_addrs, nic->mac_addr, RTE_ETHER_ADDR_LEN); + + /* Update same mac address to BGX CAM table at index 0 */ + octeontx_bgx_port_mac_add(nic->port_id, nic->mac_addr, 0); PMD_INIT_LOG(DEBUG, "ethdev info: "); PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d", @@ -1099,16 +1179,13 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, rte_eth_dev_probing_finish(eth_dev); return data->port_id; +free_mac_addrs: + rte_free(data->mac_addrs); err: if (nic) octeontx_port_close(nic); - if (eth_dev != NULL) { - rte_free(eth_dev->data->mac_addrs); - rte_free(data); - rte_free(nic); - rte_eth_dev_release_port(eth_dev); - } + rte_eth_dev_release_port(eth_dev); return res; } @@ -1134,7 +1211,7 @@ octeontx_remove(struct rte_vdev_device *dev) return -ENODEV; if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - rte_eth_dev_release_port_secondary(eth_dev); + rte_eth_dev_release_port(eth_dev); continue; } @@ -1142,8 +1219,6 @@ octeontx_remove(struct rte_vdev_device *dev) rte_event_dev_stop(nic->evdev); PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name); - rte_free(eth_dev->data->mac_addrs); - rte_free(eth_dev->data->dev_private); rte_eth_dev_release_port(eth_dev); rte_event_dev_close(nic->evdev); } @@ -1180,7 +1255,7 @@ octeontx_probe(struct rte_vdev_device *dev) strlen(rte_vdev_device_args(dev)) == 0) { eth_dev = rte_eth_dev_attach_secondary(dev_name); if (!eth_dev) { - RTE_LOG(ERR, PMD, "Failed to probe %s\n", dev_name); + PMD_INIT_LOG(ERR, "Failed to probe %s", dev_name); return -1; } /* TODO: request info from primary to set up Rx and Tx */ @@ -1244,15 +1319,8 @@ octeontx_probe(struct rte_vdev_device *dev) res = -EINVAL; goto parse_error; } - if (pnum > qnum) { - /* - * We don't poll on event ports - * that do not have any queues assigned. - */ - pnum = qnum; - PMD_INIT_LOG(INFO, - "reducing number of active event ports to %d", pnum); - } + + /* Enable all queues available */ for (i = 0; i < qnum; i++) { res = rte_event_queue_setup(evdev, i, NULL); if (res < 0) { @@ -1262,6 +1330,7 @@ octeontx_probe(struct rte_vdev_device *dev) } } + /* Enable all ports available */ for (i = 0; i < pnum; i++) { res = rte_event_port_setup(evdev, i, NULL); if (res < 0) { @@ -1270,6 +1339,14 @@ octeontx_probe(struct rte_vdev_device *dev) i, res); goto parse_error; } + } + + /* + * Do 1:1 links for ports & queues. All queues would be mapped to + * one port. If there are more ports than queues, then some ports + * won't be linked to any queue. + */ + for (i = 0; i < qnum; i++) { /* Link one queue to one event port */ qlist = i; res = rte_event_port_link(evdev, i, &qlist, NULL, 1);