X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Faf_packet%2Frte_eth_af_packet.c;h=2e90e2985c19ded1856c29aa902e7ad27f363659;hb=902fa8b50d609150f717394ba0c5b72890c66d9b;hp=f5806bf42c46aed4ee51ce36bfba9dfbbe76c61d;hpb=60b05125c42248fb86af4876828599431a5629f3;p=dpdk.git diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index f5806bf42c..2e90e2985c 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -37,8 +38,6 @@ #define DFLT_FRAME_SIZE (1 << 11) #define DFLT_FRAME_COUNT (1 << 9) -#define RTE_PMD_AF_PACKET_MAX_RINGS 16 - struct pkt_rx_queue { int sockfd; @@ -77,8 +76,8 @@ struct pmd_internals { struct tpacket_req req; - struct pkt_rx_queue rx_queue[RTE_PMD_AF_PACKET_MAX_RINGS]; - struct pkt_tx_queue tx_queue[RTE_PMD_AF_PACKET_MAX_RINGS]; + struct pkt_rx_queue *rx_queue; + struct pkt_tx_queue *tx_queue; }; static const char *valid_arguments[] = { @@ -98,7 +97,7 @@ static struct rte_eth_link pmd_link = { .link_autoneg = ETH_LINK_FIXED, }; -static int af_packet_logtype; +RTE_LOG_REGISTER_DEFAULT(af_packet_logtype, NOTICE); #define PMD_LOG(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, af_packet_logtype, \ @@ -273,7 +272,7 @@ eth_dev_start(struct rte_eth_dev *dev) /* * This function gets called when the current port gets stopped. */ -static void +static int eth_dev_stop(struct rte_eth_dev *dev) { unsigned i; @@ -297,6 +296,7 @@ eth_dev_stop(struct rte_eth_dev *dev) } dev->data->dev_link.link_status = ETH_LINK_DOWN; + return 0; } static int @@ -377,9 +377,34 @@ eth_stats_reset(struct rte_eth_dev *dev) return 0; } -static void -eth_dev_close(struct rte_eth_dev *dev __rte_unused) +static int +eth_dev_close(struct rte_eth_dev *dev) { + struct pmd_internals *internals; + struct tpacket_req *req; + unsigned int q; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + PMD_LOG(INFO, "Closing AF_PACKET ethdev on NUMA socket %u", + rte_socket_id()); + + internals = dev->data->dev_private; + req = &internals->req; + for (q = 0; q < internals->nb_queues; q++) { + munmap(internals->rx_queue[q].map, + 2 * req->tp_block_size * req->tp_block_nr); + rte_free(internals->rx_queue[q].rd); + rte_free(internals->tx_queue[q].rd); + } + free(internals->if_name); + rte_free(internals->rx_queue); + rte_free(internals->tx_queue); + + /* mac_addrs must not be freed alone because part of dev_private */ + dev->data->mac_addrs = NULL; + return 0; } static void @@ -468,6 +493,32 @@ eth_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return 0; } +static int +eth_dev_macaddr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr) +{ + struct pmd_internals *internals = dev->data->dev_private; + struct ifreq ifr = { }; + int sockfd = internals->rx_queue[0].sockfd; + int ret; + + if (sockfd == -1) { + PMD_LOG(ERR, "receive socket not found"); + return -EINVAL; + } + + strlcpy(ifr.ifr_name, internals->if_name, IFNAMSIZ); + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, addr, sizeof(*addr)); + ret = ioctl(sockfd, SIOCSIFHWADDR, &ifr); + + if (ret < 0) { + PMD_LOG_ERRNO(ERR, "ioctl(SIOCSIFHWADDR) failed"); + return -EINVAL; + } + + return 0; +} + static int eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask) { @@ -517,6 +568,7 @@ static const struct eth_dev_ops ops = { .dev_close = eth_dev_close, .dev_configure = eth_dev_configure, .dev_infos_get = eth_dev_info, + .mac_addr_set = eth_dev_macaddr_set, .mtu_set = eth_dev_mtu_set, .promiscuous_enable = eth_dev_promiscuous_enable, .promiscuous_disable = eth_dev_promiscuous_disable, @@ -601,9 +653,24 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, if (*internals == NULL) return -1; + + (*internals)->rx_queue = rte_calloc_socket("af_packet_rx", + nb_queues, + sizeof(struct pkt_rx_queue), + 0, numa_node); + (*internals)->tx_queue = rte_calloc_socket("af_packet_tx", + nb_queues, + sizeof(struct pkt_tx_queue), + 0, numa_node); + if (!(*internals)->rx_queue || !(*internals)->tx_queue) { + goto free_internals; + } + for (q = 0; q < nb_queues; q++) { (*internals)->rx_queue[q].map = MAP_FAILED; (*internals)->tx_queue[q].map = MAP_FAILED; + (*internals)->rx_queue[q].sockfd = -1; + (*internals)->tx_queue[q].sockfd = -1; } req = &((*internals)->req); @@ -621,20 +688,20 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG(ERR, "%s: I/F name too long (%s)", name, pair->value); - return -1; + goto free_internals; } if (ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1) { PMD_LOG_ERRNO(ERR, "%s: ioctl failed (SIOCGIFINDEX)", name); - return -1; + goto free_internals; } (*internals)->if_name = strdup(pair->value); if ((*internals)->if_name == NULL) - return -1; + goto free_internals; (*internals)->if_index = ifr.ifr_ifindex; if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1) { PMD_LOG_ERRNO(ERR, "%s: ioctl failed (SIOCGIFHWADDR)", name); - return -1; + goto free_internals; } memcpy(&(*internals)->eth_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); @@ -658,7 +725,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG_ERRNO(ERR, "%s: could not open AF_PACKET socket", name); - return -1; + goto error; } tpver = TPACKET_V2; @@ -793,6 +860,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, data->nb_tx_queues = (uint16_t)nb_queues; data->dev_link = pmd_link; data->mac_addrs = &(*internals)->eth_addr; + data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; (*eth_dev)->dev_ops = &ops; @@ -802,15 +870,19 @@ error: if (qsockfd != -1) close(qsockfd); for (q = 0; q < nb_queues; q++) { - munmap((*internals)->rx_queue[q].map, - 2 * req->tp_block_size * req->tp_block_nr); + if ((*internals)->rx_queue[q].map != MAP_FAILED) + munmap((*internals)->rx_queue[q].map, + 2 * req->tp_block_size * req->tp_block_nr); rte_free((*internals)->rx_queue[q].rd); rte_free((*internals)->tx_queue[q].rd); - if (((*internals)->rx_queue[q].sockfd != 0) && + if (((*internals)->rx_queue[q].sockfd >= 0) && ((*internals)->rx_queue[q].sockfd != qsockfd)) close((*internals)->rx_queue[q].sockfd); } +free_internals: + rte_free((*internals)->rx_queue); + rte_free((*internals)->tx_queue); free((*internals)->if_name); rte_free(*internals); return -1; @@ -846,8 +918,7 @@ rte_eth_from_packet(struct rte_vdev_device *dev, pair = &kvlist->pairs[k_idx]; if (strstr(pair->key, ETH_AF_PACKET_NUM_Q_ARG) != NULL) { qpairs = atoi(pair->value); - if (qpairs < 1 || - qpairs > RTE_PMD_AF_PACKET_MAX_RINGS) { + if (qpairs < 1) { PMD_LOG(ERR, "%s: invalid qpairs value", name); @@ -988,13 +1059,7 @@ exit: static int rte_pmd_af_packet_remove(struct rte_vdev_device *dev) { - struct rte_eth_dev *eth_dev = NULL; - struct pmd_internals *internals; - struct tpacket_req *req; - unsigned q; - - PMD_LOG(INFO, "Closing AF_PACKET ethdev on numa socket %u", - rte_socket_id()); + struct rte_eth_dev *eth_dev; if (dev == NULL) return -1; @@ -1002,24 +1067,9 @@ rte_pmd_af_packet_remove(struct rte_vdev_device *dev) /* find the ethdev entry */ eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev)); if (eth_dev == NULL) - return -1; - - /* mac_addrs must not be freed alone because part of dev_private */ - eth_dev->data->mac_addrs = NULL; - - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return rte_eth_dev_release_port(eth_dev); - - internals = eth_dev->data->dev_private; - req = &internals->req; - for (q = 0; q < internals->nb_queues; q++) { - munmap(internals->rx_queue[q].map, - 2 * req->tp_block_size * req->tp_block_nr); - rte_free(internals->rx_queue[q].rd); - rte_free(internals->tx_queue[q].rd); - } - free(internals->if_name); + return 0; /* port already released */ + eth_dev_close(eth_dev); rte_eth_dev_release_port(eth_dev); return 0; @@ -1039,10 +1089,3 @@ RTE_PMD_REGISTER_PARAM_STRING(net_af_packet, "framesz= " "framecnt= " "qdisc_bypass=<0|1>"); - -RTE_INIT(af_packet_init_log) -{ - af_packet_logtype = rte_log_register("pmd.net.packet"); - if (af_packet_logtype >= 0) - rte_log_set_level(af_packet_logtype, RTE_LOG_NOTICE); -}