diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/addr.c | 53 | ||||
-rw-r--r-- | drivers/infiniband/core/cma.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 15 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 220 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 32 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 |
10 files changed, 151 insertions, 221 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index e9cf51b1343..1612cfd50f3 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -178,6 +178,25 @@ static void queue_req(struct addr_req *req) mutex_unlock(&lock); } +static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr) +{ + struct neighbour *n; + int ret; + + rcu_read_lock(); + n = dst_get_neighbour_noref(dst); + if (!n || !(n->nud_state & NUD_VALID)) { + if (n) + neigh_event_send(n, NULL); + ret = -ENODATA; + } else { + ret = rdma_copy_addr(addr, dst->dev, n->ha); + } + rcu_read_unlock(); + + return ret; +} + static int addr4_resolve(struct sockaddr_in *src_in, struct sockaddr_in *dst_in, struct rdma_dev_addr *addr) @@ -185,7 +204,6 @@ static int addr4_resolve(struct sockaddr_in *src_in, __be32 src_ip = src_in->sin_addr.s_addr; __be32 dst_ip = dst_in->sin_addr.s_addr; struct rtable *rt; - struct neighbour *neigh; struct flowi4 fl4; int ret; @@ -214,20 +232,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, goto put; } - neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); - if (!neigh || !(neigh->nud_state & NUD_VALID)) { - rcu_read_lock(); - neigh_event_send(dst_get_neighbour(&rt->dst), NULL); - rcu_read_unlock(); - ret = -ENODATA; - if (neigh) - goto release; - goto put; - } - - ret = rdma_copy_addr(addr, neigh->dev, neigh->ha); -release: - neigh_release(neigh); + ret = dst_fetch_ha(&rt->dst, addr); put: ip_rt_put(rt); out: @@ -240,13 +245,12 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, struct rdma_dev_addr *addr) { struct flowi6 fl6; - struct neighbour *neigh; struct dst_entry *dst; int ret; memset(&fl6, 0, sizeof fl6); - ipv6_addr_copy(&fl6.daddr, &dst_in->sin6_addr); - ipv6_addr_copy(&fl6.saddr, &src_in->sin6_addr); + fl6.daddr = dst_in->sin6_addr; + fl6.saddr = src_in->sin6_addr; fl6.flowi6_oif = addr->bound_dev_if; dst = ip6_route_output(&init_net, NULL, &fl6); @@ -260,7 +264,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; src_in->sin6_family = AF_INET6; - ipv6_addr_copy(&src_in->sin6_addr, &fl6.saddr); + src_in->sin6_addr = fl6.saddr; } if (dst->dev->flags & IFF_LOOPBACK) { @@ -276,16 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - rcu_read_lock(); - neigh = dst_get_neighbour(dst); - if (!neigh || !(neigh->nud_state & NUD_VALID)) { - if (neigh) - neigh_event_send(neigh, NULL); - ret = -ENODATA; - } else { - ret = rdma_copy_addr(addr, dst->dev, neigh->ha); - } - rcu_read_unlock(); + ret = dst_fetch_ha(dst, addr); put: dst_release(dst); return ret; diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d0d4aa9f480..236a88c1ca8 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2005,11 +2005,11 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) if (cma_zero_addr(src)) { dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr; if ((src->sa_family = dst->sa_family) == AF_INET) { - ((struct sockaddr_in *) src)->sin_addr.s_addr = - ((struct sockaddr_in *) dst)->sin_addr.s_addr; + ((struct sockaddr_in *)src)->sin_addr = + ((struct sockaddr_in *)dst)->sin_addr; } else { - ipv6_addr_copy(&((struct sockaddr_in6 *) src)->sin6_addr, - &((struct sockaddr_in6 *) dst)->sin6_addr); + ((struct sockaddr_in6 *)src)->sin6_addr = + ((struct sockaddr_in6 *)dst)->sin6_addr; } } diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index c88b12beef2..740dcc065cf 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -1338,7 +1338,6 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) struct iwch_ep *child_ep, *parent_ep = ctx; struct cpl_pass_accept_req *req = cplhdr(skb); unsigned int hwtid = GET_TID(req); - struct neighbour *neigh; struct dst_entry *dst; struct l2t_entry *l2t; struct rtable *rt; @@ -1375,10 +1374,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) goto reject; } dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(dst); - l2t = t3_l2t_get(tdev, neigh, neigh->dev); - rcu_read_unlock(); + l2t = t3_l2t_get(tdev, dst, NULL); if (!l2t) { printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", __func__); @@ -1889,7 +1885,6 @@ static int is_loopback_dst(struct iw_cm_id *cm_id) int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { struct iwch_dev *h = to_iwch_dev(cm_id->device); - struct neighbour *neigh; struct iwch_ep *ep; struct rtable *rt; int err = 0; @@ -1947,13 +1942,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) goto fail3; } ep->dst = &rt->dst; - - rcu_read_lock(); - neigh = dst_get_neighbour(ep->dst); - - /* get a l2t entry */ - ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev); - rcu_read_unlock(); + ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst, NULL); if (!ep->l2t) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); err = -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 0747004313a..0668bb3472d 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1556,6 +1556,67 @@ static void get_4tuple(struct cpl_pass_accept_req *req, return; } +static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, + struct c4iw_dev *cdev, bool clear_mpa_v1) +{ + struct neighbour *n; + int err, step; + + rcu_read_lock(); + n = dst_get_neighbour_noref(dst); + err = -ENODEV; + if (!n) + goto out; + err = -ENOMEM; + if (n->dev->flags & IFF_LOOPBACK) { + struct net_device *pdev; + + pdev = ip_dev_find(&init_net, peer_ip); + ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, + n, pdev, 0); + if (!ep->l2t) + goto out; + ep->mtu = pdev->mtu; + ep->tx_chan = cxgb4_port_chan(pdev); + ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; + step = cdev->rdev.lldi.ntxq / + cdev->rdev.lldi.nchan; + ep->txq_idx = cxgb4_port_idx(pdev) * step; + step = cdev->rdev.lldi.nrxq / + cdev->rdev.lldi.nchan; + ep->ctrlq_idx = cxgb4_port_idx(pdev); + ep->rss_qid = cdev->rdev.lldi.rxq_ids[ + cxgb4_port_idx(pdev) * step]; + dev_put(pdev); + } else { + ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, + n, n->dev, 0); + if (!ep->l2t) + goto out; + ep->mtu = dst_mtu(ep->dst); + ep->tx_chan = cxgb4_port_chan(n->dev); + ep->smac_idx = (cxgb4_port_viid(n->dev) & 0x7F) << 1; + step = cdev->rdev.lldi.ntxq / + cdev->rdev.lldi.nchan; + ep->txq_idx = cxgb4_port_idx(n->dev) * step; + ep->ctrlq_idx = cxgb4_port_idx(n->dev); + step = cdev->rdev.lldi.nrxq / + cdev->rdev.lldi.nchan; + ep->rss_qid = cdev->rdev.lldi.rxq_ids[ + cxgb4_port_idx(n->dev) * step]; + + if (clear_mpa_v1) { + ep->retry_with_mpa_v1 = 0; + ep->tried_with_mpa_v1 = 0; + } + } + err = 0; +out: + rcu_read_unlock(); + + return err; +} + static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) { struct c4iw_ep *child_ep, *parent_ep; @@ -1563,18 +1624,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid)); struct tid_info *t = dev->rdev.lldi.tids; unsigned int hwtid = GET_TID(req); - struct neighbour *neigh; struct dst_entry *dst; - struct l2t_entry *l2t; struct rtable *rt; __be32 local_ip, peer_ip; __be16 local_port, peer_port; - struct net_device *pdev; - u32 tx_chan, smac_idx; - u16 rss_qid; - u32 mtu; - int step; - int txq_idx, ctrlq_idx; + int err; parent_ep = lookup_stid(t, stid); PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid); @@ -1596,49 +1650,24 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) goto reject; } dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(dst); - if (neigh->dev->flags & IFF_LOOPBACK) { - pdev = ip_dev_find(&init_net, peer_ip); - BUG_ON(!pdev); - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, pdev, 0); - mtu = pdev->mtu; - tx_chan = cxgb4_port_chan(pdev); - smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; - step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan; - txq_idx = cxgb4_port_idx(pdev) * step; - ctrlq_idx = cxgb4_port_idx(pdev); - step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; - rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step]; - dev_put(pdev); - } else { - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, neigh->dev, 0); - mtu = dst_mtu(dst); - tx_chan = cxgb4_port_chan(neigh->dev); - smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; - step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan; - txq_idx = cxgb4_port_idx(neigh->dev) * step; - ctrlq_idx = cxgb4_port_idx(neigh->dev); - step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; - rss_qid = dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(neigh->dev) * step]; - } - rcu_read_unlock(); - if (!l2t) { - printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", + + child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL); + if (!child_ep) { + printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n", __func__); dst_release(dst); goto reject; } - child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL); - if (!child_ep) { - printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n", + err = import_ep(child_ep, peer_ip, dst, dev, false); + if (err) { + printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", __func__); - cxgb4_l2t_release(l2t); dst_release(dst); + kfree(child_ep); goto reject; } + state_set(&child_ep->com, CONNECTING); child_ep->com.dev = dev; child_ep->com.cm_id = NULL; @@ -1651,18 +1680,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) c4iw_get_ep(&parent_ep->com); child_ep->parent_ep = parent_ep; child_ep->tos = GET_POPEN_TOS(ntohl(req->tos_stid)); - child_ep->l2t = l2t; child_ep->dst = dst; child_ep->hwtid = hwtid; - child_ep->tx_chan = tx_chan; - child_ep->smac_idx = smac_idx; - child_ep->rss_qid = rss_qid; - child_ep->mtu = mtu; - child_ep->txq_idx = txq_idx; - child_ep->ctrlq_idx = ctrlq_idx; PDBG("%s tx_chan %u smac_idx %u rss_qid %u\n", __func__, - tx_chan, smac_idx, rss_qid); + child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid); init_timer(&child_ep->timer); cxgb4_insert_tid(t, child_ep, hwtid); @@ -1792,11 +1814,8 @@ static int is_neg_adv_abort(unsigned int status) static int c4iw_reconnect(struct c4iw_ep *ep) { - int err = 0; struct rtable *rt; - struct net_device *pdev; - struct neighbour *neigh; - int step; + int err = 0; PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id); init_timer(&ep->timer); @@ -1824,47 +1843,10 @@ static int c4iw_reconnect(struct c4iw_ep *ep) } ep->dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(ep->dst); - - /* get a l2t entry */ - if (neigh->dev->flags & IFF_LOOPBACK) { - PDBG("%s LOOPBACK\n", __func__); - pdev = ip_dev_find(&init_net, - ep->com.cm_id->remote_addr.sin_addr.s_addr); - ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, pdev, 0); - ep->mtu = pdev->mtu; - ep->tx_chan = cxgb4_port_chan(pdev); - ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; - step = ep->com.dev->rdev.lldi.ntxq / - ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(pdev) * step; - step = ep->com.dev->rdev.lldi.nrxq / - ep->com.dev->rdev.lldi.nchan; - ep->ctrlq_idx = cxgb4_port_idx(pdev); - ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(pdev) * step]; - dev_put(pdev); - } else { - ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, neigh->dev, 0); - ep->mtu = dst_mtu(ep->dst); - ep->tx_chan = cxgb4_port_chan(neigh->dev); - ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; - step = ep->com.dev->rdev.lldi.ntxq / - ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(neigh->dev) * step; - ep->ctrlq_idx = cxgb4_port_idx(neigh->dev); - step = ep->com.dev->rdev.lldi.nrxq / - ep->com.dev->rdev.lldi.nchan; - ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(neigh->dev) * step]; - } - rcu_read_unlock(); - if (!ep->l2t) { + err = import_ep(ep, ep->com.cm_id->remote_addr.sin_addr.s_addr, + ep->dst, ep->com.dev, false); + if (err) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); - err = -ENOMEM; goto fail4; } @@ -2240,13 +2222,10 @@ err: int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { - int err = 0; struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); struct c4iw_ep *ep; struct rtable *rt; - struct net_device *pdev; - struct neighbour *neigh; - int step; + int err = 0; if ((conn_param->ord > c4iw_max_read_depth) || (conn_param->ird > c4iw_max_read_depth)) { @@ -2307,49 +2286,10 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } ep->dst = &rt->dst; - rcu_read_lock(); - neigh = dst_get_neighbour(ep->dst); - - /* get a l2t entry */ - if (neigh->dev->flags & IFF_LOOPBACK) { - PDBG("%s LOOPBACK\n", __func__); - pdev = ip_dev_find(&init_net, - cm_id->remote_addr.sin_addr.s_addr); - ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, pdev, 0); - ep->mtu = pdev->mtu; - ep->tx_chan = cxgb4_port_chan(pdev); - ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; - step = ep->com.dev->rdev.lldi.ntxq / - ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(pdev) * step; - step = ep->com.dev->rdev.lldi.nrxq / - ep->com.dev->rdev.lldi.nchan; - ep->ctrlq_idx = cxgb4_port_idx(pdev); - ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(pdev) * step]; - dev_put(pdev); - } else { - ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - neigh, neigh->dev, 0); - ep->mtu = dst_mtu(ep->dst); - ep->tx_chan = cxgb4_port_chan(neigh->dev); - ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; - step = ep->com.dev->rdev.lldi.ntxq / - ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(neigh->dev) * step; - ep->ctrlq_idx = cxgb4_port_idx(neigh->dev); - step = ep->com.dev->rdev.lldi.nrxq / - ep->com.dev->rdev.lldi.nchan; - ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(neigh->dev) * step]; - ep->retry_with_mpa_v1 = 0; - ep->tried_with_mpa_v1 = 0; - } - rcu_read_unlock(); - if (!ep->l2t) { + err = import_ep(ep, cm_id->remote_addr.sin_addr.s_addr, + ep->dst, ep->com.dev, true); + if (err) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); - err = -ENOMEM; goto fail4; } diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index f36da994a85..95c94d8f025 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -109,7 +109,8 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, err = mlx4_cmd_box(dev->dev, inmailbox->dma, outmailbox->dma, in_modifier, op_modifier, - MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); + MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); if (!err) memcpy(response_mad, outmailbox->buf, 256); @@ -330,7 +331,8 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, return IB_MAD_RESULT_FAILURE; err = mlx4_cmd_box(dev->dev, 0, mailbox->dma, inmod, 0, - MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C); + MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_WRAPPED); if (err) err = IB_MAD_RESULT_FAILURE; else { diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 18836cdf1e1..7b445df6a66 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -177,7 +177,7 @@ mlx4_ib_port_link_layer(struct ib_device *device, u8 port_num) { struct mlx4_dev *dev = to_mdev(device)->dev; - return dev->caps.port_mask & (1 << (port_num - 1)) ? + return dev->caps.port_mask[port_num] == MLX4_PORT_TYPE_IB ? IB_LINK_LAYER_INFINIBAND : IB_LINK_LAYER_ETHERNET; } @@ -434,7 +434,7 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, memset(mailbox->buf, 0, 256); memcpy(mailbox->buf, props->node_desc, 64); mlx4_cmd(to_mdev(ibdev)->dev, mailbox->dma, 1, 0, - MLX4_CMD_SET_NODE, MLX4_CMD_TIME_CLASS_A); + MLX4_CMD_SET_NODE, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); mlx4_free_cmd_mailbox(to_mdev(ibdev)->dev, mailbox); @@ -463,7 +463,7 @@ static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, int reset_qkey_viols, } err = mlx4_cmd(dev->dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT, - MLX4_CMD_TIME_CLASS_B); + MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); mlx4_free_cmd_mailbox(dev->dev, mailbox); return err; @@ -899,7 +899,8 @@ static void update_gids_task(struct work_struct *work) memcpy(gids, gw->gids, sizeof gw->gids); err = mlx4_cmd(dev, mailbox->dma, MLX4_SET_PORT_GID_TABLE << 8 | gw->port, - 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B); + 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, + MLX4_CMD_NATIVE); if (err) printk(KERN_WARNING "set port command failed\n"); else { @@ -1074,6 +1075,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) printk_once(KERN_INFO "%s", mlx4_ib_version); + if (mlx4_is_mfunc(dev)) { + printk(KERN_WARNING "IB not yet supported in SRIOV\n"); + return NULL; + } + mlx4_foreach_ib_transport_port(i, dev) num_ports++; diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 0a52d72371e..b1e6cae5f47 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1348,7 +1348,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi else netdev = nesvnic->netdev; - neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev); + rcu_read_lock(); + neigh = dst_get_neighbour_noref(&rt->dst); if (neigh) { if (neigh->nud_state & NUD_VALID) { nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" @@ -1359,7 +1360,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, neigh->ha, ETH_ALEN)) { /* Mac address same as in nes_arp_table */ - neigh_release(neigh); ip_rt_put(rt); return rc; } @@ -1373,15 +1373,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi dst_ip, NES_ARP_ADD); rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL, NES_ARP_RESOLVE); + } else { + neigh_event_send(neigh, NULL); } - neigh_release(neigh); - } - - if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) { - rcu_read_lock(); - neigh_event_send(dst_get_neighbour(&rt->dst), NULL); - rcu_read_unlock(); } + rcu_read_unlock(); ip_rt_put(rt); return rc; } diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index c00d2f3f896..4b3fa711a24 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1589,7 +1589,7 @@ static const struct ethtool_ops nes_ethtool_ops = { .set_pauseparam = nes_netdev_set_pauseparam, }; -static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, u32 features) +static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, netdev_features_t features) { struct nes_adapter *nesadapter = nesdev->nesadapter; u32 u32temp; @@ -1610,7 +1610,7 @@ static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, spin_unlock_irqrestore(&nesadapter->phy_lock, flags); } -static u32 nes_fix_features(struct net_device *netdev, u32 features) +static netdev_features_t nes_fix_features(struct net_device *netdev, netdev_features_t features) { /* * Since there is no support for separate rx/tx vlan accel @@ -1624,7 +1624,7 @@ static u32 nes_fix_features(struct net_device *netdev, u32 features) return features; } -static int nes_set_features(struct net_device *netdev, u32 features) +static int nes_set_features(struct net_device *netdev, netdev_features_t features) { struct nes_vnic *nesvnic = netdev_priv(netdev); struct nes_device *nesdev = nesvnic->nesdev; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 83695b48b01..3514ca05dee 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -171,7 +171,7 @@ static int ipoib_stop(struct net_device *dev) return 0; } -static u32 ipoib_fix_features(struct net_device *dev, u32 features) +static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_features_t features) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -556,15 +556,13 @@ static int path_rec_start(struct net_device *dev, } /* called with rcu_read_lock */ -static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) +static void neigh_add_path(struct sk_buff *skb, struct neighbour *n, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; struct ipoib_neigh *neigh; - struct neighbour *n; unsigned long flags; - n = dst_get_neighbour(skb_dst(skb)); neigh = ipoib_neigh_alloc(n, skb->dev); if (!neigh) { ++dev->stats.tx_dropped; @@ -638,16 +636,13 @@ err_drop: } /* called with rcu_read_lock */ -static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) +static void ipoib_path_lookup(struct sk_buff *skb, struct neighbour *n, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(skb->dev); - struct dst_entry *dst = skb_dst(skb); - struct neighbour *n; /* Look up path record for unicasts */ - n = dst_get_neighbour(dst); if (n->ha[4] != 0xff) { - neigh_add_path(skb, dev); + neigh_add_path(skb, n, dev); return; } @@ -723,12 +718,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; rcu_read_lock(); - if (likely(skb_dst(skb))) - n = dst_get_neighbour(skb_dst(skb)); - + if (likely(skb_dst(skb))) { + n = dst_get_neighbour_noref(skb_dst(skb)); + if (!n) { + ++dev->stats.tx_dropped; + dev_kfree_skb_any(skb); + goto unlock; + } + } if (likely(n)) { if (unlikely(!*to_ipoib_neigh(n))) { - ipoib_path_lookup(skb, dev); + ipoib_path_lookup(skb, n, dev); goto unlock; } @@ -751,7 +751,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) list_del(&neigh->list); ipoib_neigh_free(dev, neigh); spin_unlock_irqrestore(&priv->lock, flags); - ipoib_path_lookup(skb, dev); + ipoib_path_lookup(skb, n, dev); goto unlock; } @@ -841,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb, dst = skb_dst(skb); n = NULL; if (dst) - n = dst_get_neighbour_raw(dst); + n = dst_get_neighbour_noref_raw(dst); if ((!dst || !n) && daddr) { struct ipoib_pseudoheader *phdr = (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); @@ -1222,6 +1222,8 @@ static struct net_device *ipoib_add_port(const char *format, priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; + priv->dev->neigh_priv_len = sizeof(struct ipoib_neigh); + result = ib_query_pkey(hca, port, 0, &priv->pkey); if (result) { printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 873bff97e69..f7ff9dd66cd 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -269,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, skb->dev = dev; if (dst) - n = dst_get_neighbour_raw(dst); + n = dst_get_neighbour_noref_raw(dst); if (!dst || !n) { /* put pseudoheader back on for next time */ skb_push(skb, sizeof (struct ipoib_pseudoheader)); @@ -728,7 +728,7 @@ out: rcu_read_lock(); if (dst) - n = dst_get_neighbour(dst); + n = dst_get_neighbour_noref(dst); if (n && !*to_ipoib_neigh(n)) { struct ipoib_neigh *neigh = ipoib_neigh_alloc(n, skb->dev); |