Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242640
b: refs/heads/master
c: 1679200
h: refs/heads/master
v: v3
  • Loading branch information
Yevgeny Petrilin authored and David S. Miller committed Mar 23, 2011
1 parent bb79789 commit 939d690
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 62 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b12d93d63c3217f0ec923ff938b12a744e242ffa
refs/heads/master: 1679200f91da6a054b06954c9bd3eeed29b6731f
133 changes: 106 additions & 27 deletions trunk/drivers/net/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
mutex_lock(&mdev->state_lock);
if (priv->port_up) {
/* Remove old MAC and insert the new one */
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
err = mlx4_register_mac(mdev->dev, priv->port,
priv->mac, &priv->mac_index);
err = mlx4_replace_mac(mdev->dev, priv->port,
priv->base_qpn, priv->mac, 0);
if (err)
en_err(priv, "Failed changing HW MAC address\n");
} else
Expand Down Expand Up @@ -214,6 +213,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
struct mlx4_en_dev *mdev = priv->mdev;
struct net_device *dev = priv->dev;
u64 mcast_addr = 0;
u8 mc_list[16] = {0};
int err;

mutex_lock(&mdev->state_lock);
Expand All @@ -239,8 +239,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
priv->flags |= MLX4_EN_FLAG_PROMISC;

/* Enable promiscouos mode */
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 1);
if (!mdev->dev->caps.vep_uc_steering)
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 1);
else
err = mlx4_unicast_promisc_add(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed enabling "
"promiscous mode\n");
Expand All @@ -252,10 +256,21 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
en_err(priv, "Failed disabling "
"multicast filter\n");

/* Disable port VLAN filter */
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
if (err)
en_err(priv, "Failed disabling VLAN filter\n");
/* Add the default qp number as multicast promisc */
if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed entering multicast promisc mode\n");
priv->flags |= MLX4_EN_FLAG_MC_PROMISC;
}

if (priv->vlgrp) {
/* Disable port VLAN filter */
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
if (err)
en_err(priv, "Failed disabling VLAN filter\n");
}
}
goto out;
}
Expand All @@ -270,11 +285,24 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
priv->flags &= ~MLX4_EN_FLAG_PROMISC;

/* Disable promiscouos mode */
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 0);
if (!mdev->dev->caps.vep_uc_steering)
err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
priv->base_qpn, 0);
else
err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed disabling promiscous mode\n");

/* Disable Multicast promisc */
if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed disabling multicast promiscous mode\n");
priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC;
}

/* Enable port VLAN filter */
err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
if (err)
Expand All @@ -287,14 +315,38 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
0, MLX4_MCAST_DISABLE);
if (err)
en_err(priv, "Failed disabling multicast filter\n");

/* Add the default qp number as multicast promisc */
if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed entering multicast promisc mode\n");
priv->flags |= MLX4_EN_FLAG_MC_PROMISC;
}
} else {
int i;
/* Disable Multicast promisc */
if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn,
priv->port);
if (err)
en_err(priv, "Failed disabling multicast promiscous mode\n");
priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC;
}

err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_DISABLE);
if (err)
en_err(priv, "Failed disabling multicast filter\n");

/* Detach our qp from all the multicast addresses */
for (i = 0; i < priv->mc_addrs_cnt; i++) {
memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
mc_list[5] = priv->port;
mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
mc_list, MLX4_PROT_ETH);
}
/* Flush mcast filter and init it with broadcast address */
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
1, MLX4_MCAST_CONFIG);
Expand All @@ -307,15 +359,17 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
for (i = 0; i < priv->mc_addrs_cnt; i++) {
mcast_addr =
mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN);
memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
mc_list[5] = priv->port;
mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp,
mc_list, 0, MLX4_PROT_ETH);
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port,
mcast_addr, 0, MLX4_MCAST_CONFIG);
}
err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
0, MLX4_MCAST_ENABLE);
if (err)
en_err(priv, "Failed enabling multicast filter\n");

mlx4_en_clear_list(dev);
}
out:
mutex_unlock(&mdev->state_lock);
Expand Down Expand Up @@ -557,6 +611,7 @@ int mlx4_en_start_port(struct net_device *dev)
int err = 0;
int i;
int j;
u8 mc_list[16] = {0};
char name[32];

if (priv->port_up) {
Expand Down Expand Up @@ -596,10 +651,20 @@ int mlx4_en_start_port(struct net_device *dev)
++rx_index;
}

/* Set port mac number */
en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
err = mlx4_register_mac(mdev->dev, priv->port,
priv->mac, &priv->base_qpn, 0);
if (err) {
en_err(priv, "Failed setting port mac\n");
goto cq_err;
}
mdev->mac_removed[priv->port] = 0;

err = mlx4_en_config_rss_steer(priv);
if (err) {
en_err(priv, "Failed configuring rss steering\n");
goto cq_err;
goto mac_err;
}

if (mdev->dev->caps.comp_pool && !priv->tx_vector) {
Expand Down Expand Up @@ -661,40 +726,38 @@ int mlx4_en_start_port(struct net_device *dev)
en_err(priv, "Failed setting default qp numbers\n");
goto tx_err;
}
/* Set port mac number */
en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
err = mlx4_register_mac(mdev->dev, priv->port,
priv->mac, &priv->mac_index);
if (err) {
en_err(priv, "Failed setting port mac\n");
goto tx_err;
}
mdev->mac_removed[priv->port] = 0;

/* Init port */
en_dbg(HW, priv, "Initializing port\n");
err = mlx4_INIT_PORT(mdev->dev, priv->port);
if (err) {
en_err(priv, "Failed Initializing port\n");
goto mac_err;
goto tx_err;
}

/* Attach rx QP to bradcast address */
memset(&mc_list[10], 0xff, ETH_ALEN);
mc_list[5] = priv->port;
if (mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
0, MLX4_PROT_ETH))
mlx4_warn(mdev, "Failed Attaching Broadcast\n");

/* Schedule multicast task to populate multicast list */
queue_work(mdev->workqueue, &priv->mcast_task);

priv->port_up = true;
netif_tx_start_all_queues(dev);
return 0;

mac_err:
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
tx_err:
while (tx_index--) {
mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]);
mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]);
}

mlx4_en_release_rss_steer(priv);
mac_err:
mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn);
cq_err:
while (rx_index--)
mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
Expand All @@ -710,6 +773,7 @@ void mlx4_en_stop_port(struct net_device *dev)
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
int i;
u8 mc_list[16] = {0};

if (!priv->port_up) {
en_dbg(DRV, priv, "stop port called while port already down\n");
Expand All @@ -724,8 +788,23 @@ void mlx4_en_stop_port(struct net_device *dev)
/* Set port as not active */
priv->port_up = false;

/* Detach All multicasts */
memset(&mc_list[10], 0xff, ETH_ALEN);
mc_list[5] = priv->port;
mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
MLX4_PROT_ETH);
for (i = 0; i < priv->mc_addrs_cnt; i++) {
memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN);
mc_list[5] = priv->port;
mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
mc_list, MLX4_PROT_ETH);
}
mlx4_en_clear_list(dev);
/* Flush multicast filter */
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);

/* Unregister Mac address for the port */
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
mlx4_unregister_mac(mdev->dev, priv->port, priv->base_qpn);
mdev->mac_removed[priv->port] = 1;

/* Free TX Rings */
Expand Down
11 changes: 9 additions & 2 deletions trunk/drivers/net/mlx4/en_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
struct mlx4_set_port_rqp_calc_context *context;
int err;
u32 in_mod;
u32 m_promisc = (dev->caps.vep_mc_steering) ? MCAST_DIRECT : MCAST_DEFAULT;

if (dev->caps.vep_mc_steering && dev->caps.vep_uc_steering)
return 0;

mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
Expand All @@ -127,8 +131,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
memset(context, 0, sizeof *context);

context->base_qpn = cpu_to_be32(base_qpn);
context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_EN_SHIFT | base_qpn);
context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_MODE_SHIFT | base_qpn);
context->n_mac = 0x7;
context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
base_qpn);
context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
base_qpn);
context->intra_no_vlan = 0;
context->no_vlan = MLX4_NO_VLAN_IDX;
context->intra_vlan_miss = 0;
Expand Down
19 changes: 14 additions & 5 deletions trunk/drivers/net/mlx4/en_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,21 @@


#define SET_PORT_GEN_ALL_VALID 0x7
#define SET_PORT_PROMISC_EN_SHIFT 31
#define SET_PORT_PROMISC_MODE_SHIFT 30
#define SET_PORT_PROMISC_SHIFT 31
#define SET_PORT_MC_PROMISC_SHIFT 30

enum {
MLX4_CMD_SET_VLAN_FLTR = 0x47,
MLX4_CMD_SET_MCAST_FLTR = 0x48,
MLX4_CMD_DUMP_ETH_STATS = 0x49,
};

enum {
MCAST_DIRECT_ONLY = 0,
MCAST_DIRECT = 1,
MCAST_DEFAULT = 2
};

struct mlx4_set_port_general_context {
u8 reserved[3];
u8 flags;
Expand All @@ -60,14 +66,17 @@ struct mlx4_set_port_general_context {

struct mlx4_set_port_rqp_calc_context {
__be32 base_qpn;
__be32 flags;
u8 reserved[3];
u8 rererved;
u8 n_mac;
u8 n_vlan;
u8 n_prio;
u8 reserved2[3];
u8 mac_miss;
u8 intra_no_vlan;
u8 no_vlan;
u8 intra_vlan_miss;
u8 vlan_miss;
u8 reserved2[3];
u8 reserved3[3];
u8 no_vlan_prio;
__be32 promisc;
__be32 mcast;
Expand Down
11 changes: 1 addition & 10 deletions trunk/drivers/net/mlx4/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,16 +845,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
}

/* Configure RSS indirection qp */
err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &priv->base_qpn);
if (err) {
en_err(priv, "Failed to reserve range for RSS "
"indirection qp\n");
goto rss_err;
}
err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp);
if (err) {
en_err(priv, "Failed to allocate RSS indirection QP\n");
goto reserve_err;
goto rss_err;
}
rss_map->indir_qp.event = mlx4_en_sqp_event;
mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
Expand All @@ -881,8 +875,6 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
reserve_err:
mlx4_qp_release_range(mdev->dev, priv->base_qpn, 1);
rss_err:
for (i = 0; i < good_qps; i++) {
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
Expand All @@ -904,7 +896,6 @@ void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv)
MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
mlx4_qp_release_range(mdev->dev, priv->base_qpn, 1);

for (i = 0; i < priv->rx_ring_num; i++) {
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/mlx4/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
#define INIT_HCA_MC_BASE_OFFSET (INIT_HCA_MCAST_OFFSET + 0x00)
#define INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x12)
#define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x16)
#define INIT_HCA_UC_STEERING_OFFSET (INIT_HCA_MCAST_OFFSET + 0x18)
#define INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b)
#define INIT_HCA_TPT_OFFSET 0x0f0
#define INIT_HCA_DMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x00)
Expand Down Expand Up @@ -800,6 +801,8 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET);
MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET);
MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET);
if (dev->caps.vep_mc_steering)
MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET);
MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET);

/* TPT attributes */
Expand Down
Loading

0 comments on commit 939d690

Please sign in to comment.