X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx4%2Fmlx4_ethdev.c;h=9ff05c6738831fcb0dae28ff829626b044e1b54b;hb=30410493759f4bae3f65497737661e27b93c2d0e;hp=d0efa7d0624aa504d0f39c518bf5cfa637b44202;hpb=714bf46ebb52152d7b17199578b35c76f835da79;p=dpdk.git diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c index d0efa7d062..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 @@ -59,7 +58,7 @@ * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE]) +mlx4_get_ifname(const struct mlx4_priv *priv, char (*ifname)[IF_NAMESIZE]) { DIR *dir; struct dirent *dent; @@ -146,7 +145,7 @@ try_dev_id: * 0 on success, negative errno value otherwise and rte_errno is set. */ static int -mlx4_ifreq(const struct priv *priv, int req, struct ifreq *ifr) +mlx4_ifreq(const struct mlx4_priv *priv, int req, struct ifreq *ifr) { int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); int ret; @@ -176,14 +175,14 @@ mlx4_ifreq(const struct priv *priv, int req, struct ifreq *ifr) * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_get_mac(struct 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; } @@ -199,7 +198,7 @@ mlx4_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN]) * 0 on success, negative errno value otherwise and rte_errno is set. */ int -mlx4_mtu_get(struct priv *priv, uint16_t *mtu) +mlx4_mtu_get(struct mlx4_priv *priv, uint16_t *mtu) { struct ifreq request; int ret = mlx4_ifreq(priv, SIOCGIFMTU, &request); @@ -224,7 +223,7 @@ mlx4_mtu_get(struct priv *priv, uint16_t *mtu) int mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct ifreq request = { .ifr_mtu = mtu, }; int ret = mlx4_ifreq(priv, SIOCSIFMTU, &request); @@ -248,7 +247,7 @@ mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) * 0 on success, negative errno value otherwise and rte_errno is set. */ static int -mlx4_set_flags(struct priv *priv, unsigned int keep, unsigned int flags) +mlx4_set_flags(struct mlx4_priv *priv, unsigned int keep, unsigned int flags) { struct ifreq request; int ret = mlx4_ifreq(priv, SIOCGIFFLAGS, &request); @@ -272,7 +271,7 @@ mlx4_set_flags(struct priv *priv, unsigned int keep, unsigned int flags) * 0 on success, negative errno value otherwise and rte_errno is set. */ static int -mlx4_dev_set_link(struct priv *priv, int up) +mlx4_dev_set_link(struct mlx4_priv *priv, int up) { int err; @@ -300,7 +299,7 @@ mlx4_dev_set_link(struct priv *priv, int up) int mlx4_dev_set_link_down(struct rte_eth_dev *dev) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; return mlx4_dev_set_link(priv, 0); } @@ -317,7 +316,7 @@ mlx4_dev_set_link_down(struct rte_eth_dev *dev) int mlx4_dev_set_link_up(struct rte_eth_dev *dev) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; return mlx4_dev_set_link(priv, 1); } @@ -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 priv *priv = dev->data->dev_private; + 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); } /** @@ -430,10 +449,10 @@ mlx4_allmulticast_disable(struct rte_eth_dev *dev) void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) { - struct priv *priv = dev->data->dev_private; + 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,15 +482,15 @@ 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 priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct rte_flow_error error; 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. * @@ -503,7 +579,7 @@ mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr, int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct rte_flow_error error; unsigned int vidx = vlan_id / 64; unsigned int vbit = vlan_id % 64; @@ -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 priv *priv = dev->data->dev_private; + 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; } /** @@ -607,7 +682,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) */ int mlx4_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct ibv_device_attr *attr = &priv->device_attr; size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1; @@ -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; } /** @@ -714,7 +793,7 @@ mlx4_stats_reset(struct rte_eth_dev *dev) int mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete) { - const struct priv *priv = dev->data->dev_private; + const struct mlx4_priv *priv = dev->data->dev_private; struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET, }; @@ -767,7 +846,7 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete) int mlx4_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct ifreq ifr; struct ethtool_pauseparam ethpause = { .cmd = ETHTOOL_GPAUSEPARAM, @@ -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; } @@ -811,7 +890,7 @@ out: int mlx4_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; struct ifreq ifr; struct ethtool_pauseparam ethpause = { .cmd = ETHTOOL_SPAUSEPARAM, @@ -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; } @@ -879,7 +958,7 @@ mlx4_dev_supported_ptypes_get(struct rte_eth_dev *dev) RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, RTE_PTYPE_UNKNOWN }; - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; if (dev->rx_pkt_burst == mlx4_rx_burst) { if (priv->hw_csum_l2tun) @@ -903,7 +982,7 @@ int mlx4_is_removed(struct rte_eth_dev *dev) { struct ibv_device_attr device_attr; - struct priv *priv = dev->data->dev_private; + struct mlx4_priv *priv = dev->data->dev_private; if (mlx4_glue->query_device(priv->ctx, &device_attr) == EIO) return 1;