Merge branch 'mlx4'

Or Gerlitz says:

====================
Here's a batch of fixes to the mlx4 core and ethernet drivers for 3.9

The commit that disabled RFS when running in SRIOV mode fixes a regression which was
introduced in 3.9-rc1 but actually present also in the 3.8 -stable series. It turns out
that a slightly different fix is needed there and we will generate and submit it there.

Patches done against net commit 66d29cbc59 "benet: Wait f/w POST until timeout"
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-03-07 15:52:33 -05:00
commit c5b1567947
12 changed files with 75 additions and 59 deletions

View File

@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn) static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
{ {
u64 in_param; u64 in_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {

View File

@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv)
struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_dev *dev = mdev->dev; struct mlx4_dev *dev = mdev->dev;
int qpn = priv->base_qpn; int qpn = priv->base_qpn;
u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); u64 mac;
if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
priv->dev->dev_addr); priv->dev->dev_addr);
mlx4_unregister_mac(dev, priv->port, mac); mlx4_unregister_mac(dev, priv->port, mac);
} else {
if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) {
struct mlx4_mac_entry *entry; struct mlx4_mac_entry *entry;
struct hlist_node *tmp; struct hlist_node *tmp;
struct hlist_head *bucket; struct hlist_head *bucket;
unsigned int mac_hash; unsigned int i;
mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX]; for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) {
bucket = &priv->mac_hash[mac_hash]; bucket = &priv->mac_hash[i];
hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
if (ether_addr_equal_64bits(entry->mac, mac = mlx4_en_mac_to_u64(entry->mac);
priv->dev->dev_addr)) { en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n", entry->mac);
priv->port, priv->dev->dev_addr, qpn);
mlx4_en_uc_steer_release(priv, entry->mac, mlx4_en_uc_steer_release(priv, entry->mac,
qpn, entry->reg_id); qpn, entry->reg_id);
mlx4_qp_release_range(dev, qpn, 1);
mlx4_unregister_mac(dev, priv->port, mac);
hlist_del_rcu(&entry->hlist); hlist_del_rcu(&entry->hlist);
kfree_rcu(entry, rcu); kfree_rcu(entry, rcu);
break;
} }
} }
en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n",
priv->port, qpn);
mlx4_qp_release_range(dev, qpn, 1);
priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC;
} }
} }
@ -650,28 +654,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr)
return mac; return mac;
} }
static int mlx4_en_set_mac(struct net_device *dev, void *addr) static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)
{ {
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
struct sockaddr *saddr = addr;
if (!is_valid_ether_addr(saddr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
queue_work(mdev->workqueue, &priv->mac_task);
return 0;
}
static void mlx4_en_do_set_mac(struct work_struct *work)
{
struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
mac_task);
struct mlx4_en_dev *mdev = priv->mdev;
int err = 0; int err = 0;
mutex_lock(&mdev->state_lock);
if (priv->port_up) { if (priv->port_up) {
/* Remove old MAC and insert the new one */ /* Remove old MAC and insert the new one */
err = mlx4_en_replace_mac(priv, priv->base_qpn, err = mlx4_en_replace_mac(priv, priv->base_qpn,
@ -683,7 +669,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
} else } else
en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); en_dbg(HW, priv, "Port is down while registering mac, exiting...\n");
return err;
}
static int mlx4_en_set_mac(struct net_device *dev, void *addr)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
struct sockaddr *saddr = addr;
int err;
if (!is_valid_ether_addr(saddr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
mutex_lock(&mdev->state_lock);
err = mlx4_en_do_set_mac(priv);
mutex_unlock(&mdev->state_lock); mutex_unlock(&mdev->state_lock);
return err;
} }
static void mlx4_en_clear_list(struct net_device *dev) static void mlx4_en_clear_list(struct net_device *dev)
@ -1348,7 +1353,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
} }
if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
queue_work(mdev->workqueue, &priv->mac_task); mlx4_en_do_set_mac(priv);
mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0; mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
} }
mutex_unlock(&mdev->state_lock); mutex_unlock(&mdev->state_lock);
@ -1828,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
} }
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
if (priv->mdev->dev->caps.comp_pool) {
priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
if (!priv->dev->rx_cpu_rmap) if (!priv->dev->rx_cpu_rmap)
goto err; goto err;
}
#endif #endif
return 0; return 0;
@ -2078,7 +2085,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->msg_enable = MLX4_EN_MSG_LEVEL; priv->msg_enable = MLX4_EN_MSG_LEVEL;
spin_lock_init(&priv->stats_lock); spin_lock_init(&priv->stats_lock);
INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);
INIT_WORK(&priv->watchdog_task, mlx4_en_restart); INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);

View File

@ -787,6 +787,14 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
/* turn off device-managed steering capability if not enabled */
if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) {
MLX4_GET(field, outbox->buf,
QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
field &= 0x7f;
MLX4_PUT(outbox->buf, field,
QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
}
return 0; return 0;
} }

View File

@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
{ {
u64 in_param; u64 in_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, idx); set_param_l(&in_param, idx);

View File

@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
static inline void set_param_l(u64 *arg, u32 val) static inline void set_param_l(u64 *arg, u32 val)
{ {
*((u32 *)arg) = val; *arg = (*arg & 0xffffffff00000000ULL) | (u64) val;
} }
static inline void set_param_h(u64 *arg, u32 val) static inline void set_param_h(u64 *arg, u32 val)

View File

@ -509,7 +509,6 @@ struct mlx4_en_priv {
struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
struct mlx4_qp drop_qp; struct mlx4_qp drop_qp;
struct work_struct rx_mode_task; struct work_struct rx_mode_task;
struct work_struct mac_task;
struct work_struct watchdog_task; struct work_struct watchdog_task;
struct work_struct linkstate_task; struct work_struct linkstate_task;
struct delayed_work stats_task; struct delayed_work stats_task;

View File

@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
{ {
u64 in_param; u64 in_param = 0;
u64 out_param; u64 out_param;
int err; int err;
@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order) static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
{ {
u64 in_param; u64 in_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
{ {
u64 in_param; u64 in_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, index); set_param_l(&in_param, index);
@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index) static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
{ {
u64 param; u64 param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&param, index); set_param_l(&param, index);
@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
{ {
u64 in_param; u64 in_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, index); set_param_l(&in_param, index);

View File

@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
{ {
u64 in_param; u64 in_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {

View File

@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{ {
u64 out_param; u64 out_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{ {
u64 out_param; u64 out_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&out_param, port); set_param_l(&out_param, port);
@ -361,7 +361,7 @@ out:
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
{ {
u64 out_param; u64 out_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
@ -406,7 +406,7 @@ out:
void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
{ {
u64 in_param; u64 in_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {

View File

@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base) int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
{ {
u64 in_param; u64 in_param = 0;
u64 out_param; u64 out_param;
int err; int err;
@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt) void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
{ {
u64 in_param; u64 in_param = 0;
int err; int err;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
@ -319,7 +319,7 @@ err_out:
static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn) static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
{ {
u64 param; u64 param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&param, qpn); set_param_l(&param, qpn);
@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
{ {
u64 in_param; u64 in_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, qpn); set_param_l(&in_param, qpn);

View File

@ -2990,6 +2990,9 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
u8 steer_type_mask = 2; u8 steer_type_mask = 2;
enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1; enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0)
return -EINVAL;
qpn = vhcr->in_modifier & 0xffffff; qpn = vhcr->in_modifier & 0xffffff;
err = get_res(dev, slave, qpn, RES_QP, &rqp); err = get_res(dev, slave, qpn, RES_QP, &rqp);
if (err) if (err)

View File

@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn) static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
{ {
u64 in_param; u64 in_param = 0;
if (mlx4_is_mfunc(dev)) { if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, srqn); set_param_l(&in_param, srqn);