X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Faf_packet%2Frte_eth_af_packet.c;h=b9723e9619ccae64033a8b2b64d0badee21faa5a;hb=1af745211344622b50ffd7d67a618dcdce85fef8;hp=dce76b04e553d3805819a193da84564983a1ca09;hpb=9970a9ad07db7745ca6bc441819b287940ae86ea;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 dce76b04e5..b9723e9619 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -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(af_packet_logtype, pmd.net.packet, NOTICE); #define PMD_LOG(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, af_packet_logtype, \ @@ -244,8 +243,14 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } /* kick-off transmits */ - if (sendto(pkt_q->sockfd, NULL, 0, MSG_DONTWAIT, NULL, 0) == -1) { - /* error sending -- no packets transmitted */ + if (sendto(pkt_q->sockfd, NULL, 0, MSG_DONTWAIT, NULL, 0) == -1 && + errno != ENOBUFS && errno != EAGAIN) { + /* + * In case of a ENOBUFS/EAGAIN error all of the enqueued + * packets will be considered successful even though only some + * are sent. + */ + num_tx = 0; num_tx_bytes = 0; } @@ -310,6 +315,8 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_rx_queues = (uint16_t)internals->nb_queues; dev_info->max_tx_queues = (uint16_t)internals->nb_queues; dev_info->min_rx_bufsize = 0; + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS | + DEV_TX_OFFLOAD_VLAN_INSERT; return 0; } @@ -460,6 +467,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) { @@ -509,6 +542,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, @@ -593,9 +627,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); @@ -613,20 +662,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); @@ -650,7 +699,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; @@ -794,15 +843,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; @@ -838,8 +891,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); @@ -1011,6 +1063,8 @@ rte_pmd_af_packet_remove(struct rte_vdev_device *dev) rte_free(internals->tx_queue[q].rd); } free(internals->if_name); + rte_free(internals->rx_queue); + rte_free(internals->tx_queue); rte_eth_dev_release_port(eth_dev); @@ -1031,10 +1085,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); -}