X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx4%2Fmlx4_ethdev.c;h=9ff05c6738831fcb0dae28ff829626b044e1b54b;hb=6db1fde3891c493b9d352487fc8b6384cc6d06f3;hp=4dae67a1bd59f97035f1e7de44e6b1c9bb400dac;hpb=dbeba4cf18a5e1d9f7aaa284457bf15c351eb965;p=dpdk.git diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c index 4dae67a1bd..9ff05c6738 100644 --- a/drivers/net/mlx4/mlx4_ethdev.c +++ b/drivers/net/mlx4/mlx4_ethdev.c @@ -8,7 +8,6 @@ * Miscellaneous control operations for mlx4 driver. */ -#include #include #include #include @@ -176,14 +175,14 @@ mlx4_ifreq(const struct mlx4_priv *priv, int req, struct ifreq *ifr) * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_get_mac(struct mlx4_priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN]) +mlx4_get_mac(struct mlx4_priv *priv, uint8_t (*mac)[RTE_ETHER_ADDR_LEN]) { struct ifreq request; int ret = mlx4_ifreq(priv, SIOCGIFHWADDR, &request); if (ret) return ret; - memcpy(mac, request.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + memcpy(mac, request.ifr_hwaddr.sa_data, RTE_ETHER_ADDR_LEN); return 0; } @@ -341,13 +340,17 @@ enum rxmode_toggle { * Pointer to Ethernet device structure. * @param toggle * Toggle to set. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -static void +static int mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle) { struct mlx4_priv *priv = dev->data->dev_private; const char *mode; struct rte_flow_error error; + int ret; switch (toggle) { case RXMODE_TOGGLE_PROMISC_OFF: @@ -363,12 +366,16 @@ mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle) default: mode = "undefined"; } - if (!mlx4_flow_sync(priv, &error)) - return; + + ret = mlx4_flow_sync(priv, &error); + if (!ret) + return 0; + ERROR("cannot toggle %s mode (code %d, \"%s\")," " flow error type %d, cause %p, message: %s", mode, rte_errno, strerror(rte_errno), error.type, error.cause, error.message ? error.message : "(unspecified)"); + return ret; } /** @@ -376,11 +383,14 @@ mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle) * * @param dev * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -void +int mlx4_promiscuous_enable(struct rte_eth_dev *dev) { - mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_ON); + return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_ON); } /** @@ -388,11 +398,14 @@ mlx4_promiscuous_enable(struct rte_eth_dev *dev) * * @param dev * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -void +int mlx4_promiscuous_disable(struct rte_eth_dev *dev) { - mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_OFF); + return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_OFF); } /** @@ -400,11 +413,14 @@ mlx4_promiscuous_disable(struct rte_eth_dev *dev) * * @param dev * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -void +int mlx4_allmulticast_enable(struct rte_eth_dev *dev) { - mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_ON); + return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_ON); } /** @@ -412,11 +428,14 @@ mlx4_allmulticast_enable(struct rte_eth_dev *dev) * * @param dev * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -void +int mlx4_allmulticast_disable(struct rte_eth_dev *dev) { - mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_OFF); + return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_OFF); } /** @@ -433,7 +452,7 @@ mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) struct mlx4_priv *priv = dev->data->dev_private; struct rte_flow_error error; - if (index >= RTE_DIM(priv->mac)) { + if (index >= RTE_DIM(priv->mac) - priv->mac_mc) { rte_errno = EINVAL; return; } @@ -463,7 +482,7 @@ mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr, +mlx4_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, uint32_t index, uint32_t vmdq) { struct mlx4_priv *priv = dev->data->dev_private; @@ -471,7 +490,7 @@ mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr, int ret; (void)vmdq; - if (index >= RTE_DIM(priv->mac)) { + if (index >= RTE_DIM(priv->mac) - priv->mac_mc) { rte_errno = EINVAL; return -rte_errno; } @@ -487,6 +506,63 @@ mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr, return ret; } +/** + * DPDK callback to configure multicast addresses. + * + * @param dev + * Pointer to Ethernet device structure. + * @param list + * List of MAC addresses to register. + * @param num + * Number of entries in list. + * + * @return + * 0 on success, negative errno value otherwise and rte_errno is set. + */ +int +mlx4_set_mc_addr_list(struct rte_eth_dev *dev, struct rte_ether_addr *list, + uint32_t num) +{ + struct mlx4_priv *priv = dev->data->dev_private; + struct rte_flow_error error; + int ret; + + if (num > RTE_DIM(priv->mac)) { + rte_errno = EINVAL; + return -rte_errno; + } + /* + * Make sure there is enough room to increase the number of + * multicast entries without overwriting standard entries. + */ + if (num > priv->mac_mc) { + unsigned int i; + + for (i = RTE_DIM(priv->mac) - num; + i != RTE_DIM(priv->mac) - priv->mac_mc; + ++i) + if (!rte_is_zero_ether_addr(&priv->mac[i])) { + rte_errno = EBUSY; + return -rte_errno; + } + } else if (num < priv->mac_mc) { + /* Clear unused entries. */ + memset(priv->mac + RTE_DIM(priv->mac) - priv->mac_mc, + 0, + sizeof(priv->mac[0]) * (priv->mac_mc - num)); + } + memcpy(priv->mac + RTE_DIM(priv->mac) - num, list, sizeof(*list) * num); + priv->mac_mc = num; + ret = mlx4_flow_sync(priv, &error); + if (!ret) + return 0; + ERROR("failed to synchronize flow rules after modifying MC list," + " (code %d, \"%s\"), flow error type %d, cause %p, message: %s", + rte_errno, strerror(rte_errno), error.type, error.cause, + error.message ? error.message : "(unspecified)"); + return ret; +} + /** * DPDK callback to configure a VLAN filter. * @@ -541,7 +617,7 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) +mlx4_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) { return mlx4_mac_addr_add(dev, mac_addr, 0, 0); } @@ -554,12 +630,11 @@ mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) * @param[out] info * Info structure output buffer. */ -void +int mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) { struct mlx4_priv *priv = dev->data->dev_private; unsigned int max; - char ifname[IF_NAMESIZE]; /* FIXME: we should ask the device for these values. */ info->min_rx_bufsize = 32; @@ -570,9 +645,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) */ max = ((priv->device_attr.max_cq > priv->device_attr.max_qp) ? priv->device_attr.max_qp : priv->device_attr.max_cq); - /* If max >= 65535 then max = 0, max_rx_queues is uint16_t. */ - if (max >= 65535) - max = 65535; + /* max_rx_queues is uint16_t. */ + max = RTE_MIN(max, (unsigned int)UINT16_MAX); info->max_rx_queues = max; info->max_tx_queues = max; info->max_mac_addrs = RTE_DIM(priv->mac); @@ -580,8 +654,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->rx_queue_offload_capa = mlx4_get_rx_queue_offloads(priv); info->rx_offload_capa = (mlx4_get_rx_port_offloads(priv) | info->rx_queue_offload_capa); - if (mlx4_get_ifname(priv, &ifname) == 0) - info->if_index = if_nametoindex(ifname); + info->if_index = priv->if_index; info->hash_key_size = MLX4_RSS_HASH_KEY_SIZE; info->speed_capa = ETH_LINK_SPEED_1G | @@ -590,6 +663,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) ETH_LINK_SPEED_40G | ETH_LINK_SPEED_56G; info->flow_type_rss_offloads = mlx4_conv_rss_types(priv, 0, 1); + + return 0; } /** @@ -661,7 +736,6 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { tmp.q_opackets[idx] += txq->stats.opackets; tmp.q_obytes[idx] += txq->stats.obytes; - tmp.q_errors[idx] += txq->stats.odropped; } tmp.opackets += txq->stats.opackets; tmp.obytes += txq->stats.obytes; @@ -676,8 +750,11 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) * * @param dev * Pointer to Ethernet device structure. + * + * @return + * alwasy 0 on success */ -void +int mlx4_stats_reset(struct rte_eth_dev *dev) { unsigned int i; @@ -698,6 +775,8 @@ mlx4_stats_reset(struct rte_eth_dev *dev) .idx = txq->stats.idx, }; } + + return 0; } /** @@ -793,7 +872,7 @@ mlx4_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) fc_conf->mode = RTE_FC_NONE; ret = 0; out: - assert(ret >= 0); + MLX4_ASSERT(ret >= 0); return -ret; } @@ -839,7 +918,7 @@ mlx4_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) } ret = 0; out: - assert(ret >= 0); + MLX4_ASSERT(ret >= 0); return -ret; }