diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 147 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 2 |
9 files changed, 150 insertions, 80 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 03447da..911d488 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -35,6 +35,8 @@ #include <linux/ethtool.h> #include <linux/netdevice.h> #include <linux/mlx4/driver.h> +#include <linux/in.h> +#include <net/ip.h> #include "mlx4_en.h" #include "en_port.h" @@ -494,7 +496,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev, mutex_lock(&mdev->state_lock); if (priv->port_up) { port_up = 1; - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 1); } mlx4_en_free_resources(priv); @@ -589,7 +591,7 @@ static int mlx4_en_set_rxfh_indir(struct net_device *dev, mutex_lock(&mdev->state_lock); if (priv->port_up) { port_up = 1; - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 1); } priv->prof->rss_rings = rss_rings; @@ -664,27 +666,88 @@ static int mlx4_en_validate_flow(struct net_device *dev, if ((cmd->fs.flow_type & FLOW_EXT)) { if (cmd->fs.m_ext.vlan_etype || - !(cmd->fs.m_ext.vlan_tci == 0 || - cmd->fs.m_ext.vlan_tci == cpu_to_be16(0xfff))) + !((cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) == + 0 || + (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) == + cpu_to_be16(VLAN_VID_MASK))) return -EINVAL; + + if (cmd->fs.m_ext.vlan_tci) { + if (be16_to_cpu(cmd->fs.h_ext.vlan_tci) >= VLAN_N_VID) + return -EINVAL; + + } } return 0; } +static int mlx4_en_ethtool_add_mac_rule(struct ethtool_rxnfc *cmd, + struct list_head *rule_list_h, + struct mlx4_spec_list *spec_l2, + unsigned char *mac) +{ + int err = 0; + __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); + + spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH; + memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN); + memcpy(spec_l2->eth.dst_mac, mac, ETH_ALEN); + + if ((cmd->fs.flow_type & FLOW_EXT) && + (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK))) { + spec_l2->eth.vlan_id = cmd->fs.h_ext.vlan_tci; + spec_l2->eth.vlan_id_msk = cpu_to_be16(VLAN_VID_MASK); + } + + list_add_tail(&spec_l2->list, rule_list_h); + + return err; +} + +static int mlx4_en_ethtool_add_mac_rule_by_ipv4(struct mlx4_en_priv *priv, + struct ethtool_rxnfc *cmd, + struct list_head *rule_list_h, + struct mlx4_spec_list *spec_l2, + __be32 ipv4_dst) +{ + __be64 be_mac = 0; + unsigned char mac[ETH_ALEN]; + + if (!ipv4_is_multicast(ipv4_dst)) { + if (cmd->fs.flow_type & FLOW_MAC_EXT) { + memcpy(&mac, cmd->fs.h_ext.h_dest, ETH_ALEN); + } else { + be_mac = cpu_to_be64((priv->mac & MLX4_MAC_MASK) << 16); + memcpy(&mac, &be_mac, ETH_ALEN); + } + } else { + ip_eth_mc_map(ipv4_dst, mac); + } + + return mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2, &mac[0]); +} + static int add_ip_rule(struct mlx4_en_priv *priv, - struct ethtool_rxnfc *cmd, - struct list_head *list_h) + struct ethtool_rxnfc *cmd, + struct list_head *list_h) { - struct mlx4_spec_list *spec_l3; + struct mlx4_spec_list *spec_l2 = NULL; + struct mlx4_spec_list *spec_l3 = NULL; struct ethtool_usrip4_spec *l3_mask = &cmd->fs.m_u.usr_ip4_spec; - spec_l3 = kzalloc(sizeof *spec_l3, GFP_KERNEL); - if (!spec_l3) { + spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL); + spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); + if (!spec_l2 || !spec_l3) { en_err(priv, "Fail to alloc ethtool rule.\n"); + kfree(spec_l2); + kfree(spec_l3); return -ENOMEM; } + mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h, spec_l2, + cmd->fs.h_u. + usr_ip4_spec.ip4dst); spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4; spec_l3->ipv4.src_ip = cmd->fs.h_u.usr_ip4_spec.ip4src; if (l3_mask->ip4src) @@ -701,14 +764,17 @@ static int add_tcp_udp_rule(struct mlx4_en_priv *priv, struct ethtool_rxnfc *cmd, struct list_head *list_h, int proto) { - struct mlx4_spec_list *spec_l3; - struct mlx4_spec_list *spec_l4; + struct mlx4_spec_list *spec_l2 = NULL; + struct mlx4_spec_list *spec_l3 = NULL; + struct mlx4_spec_list *spec_l4 = NULL; struct ethtool_tcpip4_spec *l4_mask = &cmd->fs.m_u.tcp_ip4_spec; - spec_l3 = kzalloc(sizeof *spec_l3, GFP_KERNEL); - spec_l4 = kzalloc(sizeof *spec_l4, GFP_KERNEL); - if (!spec_l4 || !spec_l3) { + spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); + spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL); + spec_l4 = kzalloc(sizeof(*spec_l4), GFP_KERNEL); + if (!spec_l2 || !spec_l3 || !spec_l4) { en_err(priv, "Fail to alloc ethtool rule.\n"); + kfree(spec_l2); kfree(spec_l3); kfree(spec_l4); return -ENOMEM; @@ -717,12 +783,20 @@ static int add_tcp_udp_rule(struct mlx4_en_priv *priv, spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4; if (proto == TCP_V4_FLOW) { + mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h, + spec_l2, + cmd->fs.h_u. + tcp_ip4_spec.ip4dst); spec_l4->id = MLX4_NET_TRANS_RULE_ID_TCP; spec_l3->ipv4.src_ip = cmd->fs.h_u.tcp_ip4_spec.ip4src; spec_l3->ipv4.dst_ip = cmd->fs.h_u.tcp_ip4_spec.ip4dst; spec_l4->tcp_udp.src_port = cmd->fs.h_u.tcp_ip4_spec.psrc; spec_l4->tcp_udp.dst_port = cmd->fs.h_u.tcp_ip4_spec.pdst; } else { + mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h, + spec_l2, + cmd->fs.h_u. + udp_ip4_spec.ip4dst); spec_l4->id = MLX4_NET_TRANS_RULE_ID_UDP; spec_l3->ipv4.src_ip = cmd->fs.h_u.udp_ip4_spec.ip4src; spec_l3->ipv4.dst_ip = cmd->fs.h_u.udp_ip4_spec.ip4dst; @@ -751,43 +825,23 @@ static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, struct list_head *rule_list_h) { int err; - __be64 be_mac; struct ethhdr *eth_spec; - struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_spec_list *spec_l2; - __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); + struct mlx4_en_priv *priv = netdev_priv(dev); err = mlx4_en_validate_flow(dev, cmd); if (err) return err; - spec_l2 = kzalloc(sizeof *spec_l2, GFP_KERNEL); - if (!spec_l2) - return -ENOMEM; - - if (cmd->fs.flow_type & FLOW_MAC_EXT) { - memcpy(&be_mac, cmd->fs.h_ext.h_dest, ETH_ALEN); - } else { - u64 mac = priv->mac & MLX4_MAC_MASK; - be_mac = cpu_to_be64(mac << 16); - } - - spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH; - memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN); - if ((cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) != ETHER_FLOW) - memcpy(spec_l2->eth.dst_mac, &be_mac, ETH_ALEN); - - if ((cmd->fs.flow_type & FLOW_EXT) && cmd->fs.m_ext.vlan_tci) { - spec_l2->eth.vlan_id = cmd->fs.h_ext.vlan_tci; - spec_l2->eth.vlan_id_msk = cpu_to_be16(0xfff); - } - - list_add_tail(&spec_l2->list, rule_list_h); - switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { case ETHER_FLOW: + spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); + if (!spec_l2) + return -ENOMEM; + eth_spec = &cmd->fs.h_u.ether_spec; - memcpy(&spec_l2->eth.dst_mac, eth_spec->h_dest, ETH_ALEN); + mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2, + ð_spec->h_dest[0]); spec_l2->eth.ether_type = eth_spec->h_proto; if (eth_spec->h_proto) spec_l2->eth.ether_type_enable = 1; @@ -861,6 +915,7 @@ static int mlx4_en_flow_replace(struct net_device *dev, loc_rule->id = 0; memset(&loc_rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec)); + list_del(&loc_rule->list); } err = mlx4_flow_attach(priv->mdev->dev, &rule, ®_id); if (err) { @@ -871,6 +926,7 @@ static int mlx4_en_flow_replace(struct net_device *dev, loc_rule->id = reg_id; memcpy(&loc_rule->flow_spec, &cmd->fs, sizeof(struct ethtool_rx_flow_spec)); + list_add_tail(&loc_rule->list, &priv->ethtool_list); out_free_list: list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) { @@ -904,6 +960,7 @@ static int mlx4_en_flow_detach(struct net_device *dev, } rule->id = 0; memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec)); + list_del(&rule->list); out: return err; @@ -952,7 +1009,8 @@ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, if ((cmd->cmd == ETHTOOL_GRXCLSRLCNT || cmd->cmd == ETHTOOL_GRXCLSRULE || cmd->cmd == ETHTOOL_GRXCLSRLALL) && - mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) + (mdev->dev->caps.steering_mode != + MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up)) return -EINVAL; switch (cmd->cmd) { @@ -988,7 +1046,8 @@ static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; - if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) + if (mdev->dev->caps.steering_mode != + MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up) return -EINVAL; switch (cmd->cmd) { @@ -1037,7 +1096,7 @@ static int mlx4_en_set_channels(struct net_device *dev, mutex_lock(&mdev->state_lock); if (priv->port_up) { port_up = 1; - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 1); } mlx4_en_free_resources(priv); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 9c42812..ac1c14f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1039,6 +1039,9 @@ int mlx4_en_start_port(struct net_device *dev) INIT_LIST_HEAD(&priv->mc_list); INIT_LIST_HEAD(&priv->curr_list); + INIT_LIST_HEAD(&priv->ethtool_list); + memset(&priv->ethtool_rules[0], 0, + sizeof(struct ethtool_flow_id) * MAX_NUM_OF_FS_RULES); /* Calculate Rx buf size */ dev->mtu = min(dev->mtu, priv->max_mtu); @@ -1175,6 +1178,8 @@ int mlx4_en_start_port(struct net_device *dev) priv->port_up = true; netif_tx_start_all_queues(dev); + netif_device_attach(dev); + return 0; tx_err: @@ -1197,11 +1202,12 @@ cq_err: } -void mlx4_en_stop_port(struct net_device *dev) +void mlx4_en_stop_port(struct net_device *dev, int detach) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_mc_list *mclist, *tmp; + struct ethtool_flow_id *flow, *tmp_flow; int i; u8 mc_list[16] = {0}; @@ -1212,9 +1218,13 @@ void mlx4_en_stop_port(struct net_device *dev) /* Synchronize with tx routine */ netif_tx_lock_bh(dev); + if (detach) + netif_device_detach(dev); netif_tx_stop_all_queues(dev); netif_tx_unlock_bh(dev); + netif_tx_disable(dev); + /* Set port as not active */ priv->port_up = false; @@ -1281,7 +1291,19 @@ void mlx4_en_stop_port(struct net_device *dev) /* Unregister Mac address for the port */ mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn); - mdev->mac_removed[priv->port] = 1; + if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN)) + mdev->mac_removed[priv->port] = 1; + + /* Remove flow steering rules for the port*/ + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + ASSERT_RTNL(); + list_for_each_entry_safe(flow, tmp_flow, + &priv->ethtool_list, list) { + mlx4_flow_detach(mdev->dev, flow->id); + list_del(&flow->list); + } + } /* Free RX Rings */ for (i = 0; i < priv->rx_ring_num; i++) { @@ -1307,7 +1329,7 @@ static void mlx4_en_restart(struct work_struct *work) mutex_lock(&mdev->state_lock); if (priv->port_up) { - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 1); for (i = 0; i < priv->tx_ring_num; i++) netdev_tx_reset_queue(priv->tx_ring[i].tx_queue); if (mlx4_en_start_port(dev)) @@ -1379,7 +1401,7 @@ static int mlx4_en_close(struct net_device *dev) mutex_lock(&mdev->state_lock); - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 0); netif_carrier_off(dev); mutex_unlock(&mdev->state_lock); @@ -1517,7 +1539,7 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu) * the port */ en_dbg(DRV, priv, "Change MTU called with card down!?\n"); } else { - mlx4_en_stop_port(dev); + mlx4_en_stop_port(dev, 1); err = mlx4_en_start_port(dev); if (err) { en_err(priv, "Failed restarting port:%d\n", diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 8b3d051..38b62c7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -127,7 +127,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [0] = "RSS support", [1] = "RSS Toeplitz Hash Function support", [2] = "RSS XOR Hash Function support", - [3] = "Device manage flow steering support" + [3] = "Device manage flow steering support", + [4] = "Automatic mac reassignment support" }; int i; @@ -478,6 +479,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_BMME_FLAGS_OFFSET 0x94 #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 +#define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d dev_cap->flags2 = 0; mailbox = mlx4_alloc_cmd_mailbox(dev); @@ -637,6 +639,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) QUERY_DEV_CAP_BMME_FLAGS_OFFSET); MLX4_GET(dev_cap->reserved_lkey, outbox, QUERY_DEV_CAP_RSVD_LKEY_OFFSET); + MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC); + if (field & 1<<6) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN; MLX4_GET(dev_cap->max_icm_sz, outbox, QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS) @@ -1287,14 +1292,14 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) /* Enable Ethernet flow steering * with udp unicast and tcp unicast */ - MLX4_PUT(inbox, param->fs_hash_enable_bits, + MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), INIT_HCA_FS_ETH_BITS_OFFSET); MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); /* Enable IPoIB flow steering * with udp unicast and tcp unicast */ - MLX4_PUT(inbox, param->fs_hash_enable_bits, + MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), INIT_HCA_FS_IB_BITS_OFFSET); MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index dbf2f69..3af33ff 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -171,7 +171,6 @@ struct mlx4_init_hca_param { u8 log_mpt_sz; u8 log_uar_sz; u8 uar_page_sz; /* log pg sz in 4k chunks */ - u8 fs_hash_enable_bits; u8 steering_mode; /* for QUERY_HCA */ u64 dev_cap_enabled; }; diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index f1ee52d..e38c6b2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1415,22 +1415,6 @@ static int mlx4_init_hca(struct mlx4_dev *dev) if (mlx4_is_master(dev)) mlx4_parav_master_pf_caps(dev); - priv->fs_hash_mode = MLX4_FS_L2_HASH; - - switch (priv->fs_hash_mode) { - case MLX4_FS_L2_HASH: - init_hca.fs_hash_enable_bits = 0; - break; - - case MLX4_FS_L2_L3_L4_HASH: - /* Enable flow steering with - * udp unicast and tcp unicast - */ - init_hca.fs_hash_enable_bits = - MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN; - break; - } - profile = default_profile; if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 1ee4db3..5268552 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -664,7 +664,7 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, dw |= ctrl->priority << 16; hw->ctrl = cpu_to_be32(dw); - hw->vf_vep_port = cpu_to_be32(ctrl->port); + hw->port = ctrl->port; hw->qpn = cpu_to_be32(ctrl->qpn); } @@ -1157,7 +1157,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], .priority = MLX4_DOMAIN_NIC, }; - rule.allow_loopback = ~block_mcast_loopback; + rule.allow_loopback = !block_mcast_loopback; rule.port = port; rule.qpn = qp->qpn; INIT_LIST_HEAD(&rule.list); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 116c5c2..172daaa 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -60,11 +60,6 @@ #define MLX4_FS_MGM_LOG_ENTRY_SIZE 7 #define MLX4_FS_NUM_MCG (1 << 17) -enum { - MLX4_FS_L2_HASH = 0, - MLX4_FS_L2_L3_L4_HASH, -}; - #define MLX4_NUM_UP 8 #define MLX4_NUM_TC 8 #define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */ @@ -696,9 +691,12 @@ struct mlx4_steer { struct mlx4_net_trans_rule_hw_ctrl { __be32 ctrl; - __be32 vf_vep_port; + u8 rsvd1; + u8 funcid; + u8 vep; + u8 port; __be32 qpn; - __be32 reserved; + __be32 rsvd2; }; struct mlx4_net_trans_rule_hw_ib { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8d54412..43f0165 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -427,6 +427,7 @@ struct mlx4_en_frag_info { #endif struct ethtool_flow_id { + struct list_head list; struct ethtool_rx_flow_spec flow_spec; u64 id; }; @@ -441,6 +442,8 @@ struct mlx4_en_priv { struct mlx4_en_port_state port_state; spinlock_t stats_lock; struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES]; + /* To allow rules removal while port is going down */ + struct list_head ethtool_list; unsigned long last_moder_packets[MAX_RX_RINGS]; unsigned long last_moder_tx_packets; @@ -536,7 +539,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, struct mlx4_en_port_profile *prof); int mlx4_en_start_port(struct net_device *dev); -void mlx4_en_stop_port(struct net_device *dev); +void mlx4_en_stop_port(struct net_device *dev, int detach); void mlx4_en_free_resources(struct mlx4_en_priv *priv); int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 561ed2a..5997adc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -3018,7 +3018,7 @@ static int add_eth_header(struct mlx4_dev *dev, int slave, __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; - port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; + port = ctrl->port; eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); /* Clear a space in the inbox for eth header */ |