Commit 0534c8cb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  RDMA/nes: Add support for new SFP+ PHY
  RDMA/nes: Add wide_ppm_offset parm for switch compatibility
  RDMA/nes: Fix SFP+ PHY initialization
  RDMA/nes: Fix nes_nic_cm_xmit() error handling
  RDMA/nes: Fix error handling issues
  RDMA/nes: Fix incorrect casts on 32-bit architectures
  IPoIB: Document newish features
  RDMA/cma: Create cm id even when IB port is down
  RDMA/cma: Use rate from IPoIB broadcast when joining IPoIB multicast groups
  IPoIB: Avoid free_netdev() BUG when destroying a child interface
  mlx4_core: Don't leak mailbox for SET_PORT on Ethernet ports
  RDMA/cxgb3: Release dependent resources only when endpoint memory is freed.
  RDMA/cxgb3: Handle EEH events
  IB/mlx4: Use pgprot_writecombine() for BlueFlame pages
parents 54f93b74 07306c0b
...@@ -24,6 +24,49 @@ Partitions and P_Keys ...@@ -24,6 +24,49 @@ Partitions and P_Keys
The P_Key for any interface is given by the "pkey" file, and the The P_Key for any interface is given by the "pkey" file, and the
main interface for a subinterface is in "parent." main interface for a subinterface is in "parent."
Datagram vs Connected modes
The IPoIB driver supports two modes of operation: datagram and
connected. The mode is set and read through an interface's
/sys/class/net/<intf name>/mode file.
In datagram mode, the IB UD (Unreliable Datagram) transport is used
and so the interface MTU has is equal to the IB L2 MTU minus the
IPoIB encapsulation header (4 bytes). For example, in a typical IB
fabric with a 2K MTU, the IPoIB MTU will be 2048 - 4 = 2044 bytes.
In connected mode, the IB RC (Reliable Connected) transport is used.
Connected mode is to takes advantage of the connected nature of the
IB transport and allows an MTU up to the maximal IP packet size of
64K, which reduces the number of IP packets needed for handling
large UDP datagrams, TCP segments, etc and increases the performance
for large messages.
In connected mode, the interface's UD QP is still used for multicast
and communication with peers that don't support connected mode. In
this case, RX emulation of ICMP PMTU packets is used to cause the
networking stack to use the smaller UD MTU for these neighbours.
Stateless offloads
If the IB HW supports IPoIB stateless offloads, IPoIB advertises
TCP/IP checksum and/or Large Send (LSO) offloading capability to the
network stack.
Large Receive (LRO) offloading is also implemented and may be turned
on/off using ethtool calls. Currently LRO is supported only for
checksum offload capable devices.
Stateless offloads are supported only in datagram mode.
Interrupt moderation
If the underlying IB device supports CQ event moderation, one can
use ethtool to set interrupt mitigation parameters and thus reduce
the overhead incurred by handling interrupts. The main code path of
IPoIB doesn't use events for TX completion signaling so only RX
moderation is supported.
Debugging Information Debugging Information
By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set
...@@ -55,3 +98,5 @@ References ...@@ -55,3 +98,5 @@ References
http://ietf.org/rfc/rfc4391.txt http://ietf.org/rfc/rfc4391.txt
IP over InfiniBand (IPoIB) Architecture (RFC 4392) IP over InfiniBand (IPoIB) Architecture (RFC 4392)
http://ietf.org/rfc/rfc4392.txt http://ietf.org/rfc/rfc4392.txt
IP over InfiniBand: Connected Mode (RFC 4755)
http://ietf.org/rfc/rfc4755.txt
...@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv) ...@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
id_priv->cma_dev = NULL; id_priv->cma_dev = NULL;
} }
static int cma_set_qkey(struct ib_device *device, u8 port_num, static int cma_set_qkey(struct rdma_id_private *id_priv)
enum rdma_port_space ps,
struct rdma_dev_addr *dev_addr, u32 *qkey)
{ {
struct ib_sa_mcmember_rec rec; struct ib_sa_mcmember_rec rec;
int ret = 0; int ret = 0;
switch (ps) { if (id_priv->qkey)
return 0;
switch (id_priv->id.ps) {
case RDMA_PS_UDP: case RDMA_PS_UDP:
*qkey = RDMA_UDP_QKEY; id_priv->qkey = RDMA_UDP_QKEY;
break; break;
case RDMA_PS_IPOIB: case RDMA_PS_IPOIB:
ib_addr_get_mgid(dev_addr, &rec.mgid); ib_addr_get_mgid(&id_priv->id.route.addr.dev_addr, &rec.mgid);
ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec); ret = ib_sa_get_mcmember_rec(id_priv->id.device,
*qkey = be32_to_cpu(rec.qkey); id_priv->id.port_num, &rec.mgid,
&rec);
if (!ret)
id_priv->qkey = be32_to_cpu(rec.qkey);
break; break;
default: default:
break; break;
...@@ -341,11 +345,6 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) ...@@ -341,11 +345,6 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
ret = ib_find_cached_gid(cma_dev->device, &gid, ret = ib_find_cached_gid(cma_dev->device, &gid,
&id_priv->id.port_num, NULL); &id_priv->id.port_num, NULL);
if (!ret) { if (!ret) {
ret = cma_set_qkey(cma_dev->device,
id_priv->id.port_num,
id_priv->id.ps, dev_addr,
&id_priv->qkey);
if (!ret)
cma_attach_to_dev(id_priv, cma_dev); cma_attach_to_dev(id_priv, cma_dev);
break; break;
} }
...@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv, ...@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT; *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
if (cma_is_ud_ps(id_priv->id.ps)) { if (cma_is_ud_ps(id_priv->id.ps)) {
ret = cma_set_qkey(id_priv);
if (ret)
return ret;
qp_attr->qkey = id_priv->qkey; qp_attr->qkey = id_priv->qkey;
*qp_attr_mask |= IB_QP_QKEY; *qp_attr_mask |= IB_QP_QKEY;
} else { } else {
...@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, ...@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
event.status = ib_event->param.sidr_rep_rcvd.status; event.status = ib_event->param.sidr_rep_rcvd.status;
break; break;
} }
ret = cma_set_qkey(id_priv);
if (ret) {
event.event = RDMA_CM_EVENT_ADDR_ERROR;
event.status = -EINVAL;
break;
}
if (id_priv->qkey != rep->qkey) { if (id_priv->qkey != rep->qkey) {
event.event = RDMA_CM_EVENT_UNREACHABLE; event.event = RDMA_CM_EVENT_UNREACHABLE;
event.status = -EINVAL; event.status = -EINVAL;
...@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv, ...@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
const void *private_data, int private_data_len) const void *private_data, int private_data_len)
{ {
struct ib_cm_sidr_rep_param rep; struct ib_cm_sidr_rep_param rep;
int ret;
memset(&rep, 0, sizeof rep); memset(&rep, 0, sizeof rep);
rep.status = status; rep.status = status;
if (status == IB_SIDR_SUCCESS) { if (status == IB_SIDR_SUCCESS) {
ret = cma_set_qkey(id_priv);
if (ret)
return ret;
rep.qp_num = id_priv->qp_num; rep.qp_num = id_priv->qp_num;
rep.qkey = id_priv->qkey; rep.qkey = id_priv->qkey;
} }
...@@ -2713,6 +2726,10 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv, ...@@ -2713,6 +2726,10 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
IB_SA_MCMEMBER_REC_FLOW_LABEL | IB_SA_MCMEMBER_REC_FLOW_LABEL |
IB_SA_MCMEMBER_REC_TRAFFIC_CLASS; IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
if (id_priv->id.ps == RDMA_PS_IPOIB)
comp_mask |= IB_SA_MCMEMBER_REC_RATE |
IB_SA_MCMEMBER_REC_RATE_SELECTOR;
mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device, mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
id_priv->id.port_num, &rec, id_priv->id.port_num, &rec,
comp_mask, GFP_KERNEL, comp_mask, GFP_KERNEL,
......
...@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid) ...@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid)
sge_cmd = qpid << 8 | 3; sge_cmd = qpid << 8 | 3;
wqe->sge_cmd = cpu_to_be64(sge_cmd); wqe->sge_cmd = cpu_to_be64(sge_cmd);
skb->priority = CPL_PRIORITY_CONTROL; skb->priority = CPL_PRIORITY_CONTROL;
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
} }
int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
...@@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p) ...@@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
(unsigned long long) rdev_p->ctrl_qp.dma_addr, (unsigned long long) rdev_p->ctrl_qp.dma_addr,
rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2); rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
skb->priority = CPL_PRIORITY_CONTROL; skb->priority = CPL_PRIORITY_CONTROL;
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
err: err:
kfree_skb(skb); kfree_skb(skb);
return err; return err;
...@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, ...@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
u32 stag_idx; u32 stag_idx;
u32 wptr; u32 wptr;
if (rdev_p->flags) if (cxio_fatal_error(rdev_p))
return -EIO; return -EIO;
stag_state = stag_state > 0; stag_state = stag_state > 0;
...@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) ...@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size); wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
wqe->irs = cpu_to_be32(attr->irs); wqe->irs = cpu_to_be32(attr->irs);
skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */ skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
} }
void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb) void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb)
...@@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p) ...@@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p)
cxio_hal_pblpool_destroy(rdev_p); cxio_hal_pblpool_destroy(rdev_p);
cxio_hal_rqtpool_destroy(rdev_p); cxio_hal_rqtpool_destroy(rdev_p);
list_del(&rdev_p->entry); list_del(&rdev_p->entry);
rdev_p->t3cdev_p->ulp = NULL;
cxio_hal_destroy_ctrl_qp(rdev_p); cxio_hal_destroy_ctrl_qp(rdev_p);
cxio_hal_destroy_resource(rdev_p->rscp); cxio_hal_destroy_resource(rdev_p->rscp);
rdev_p->t3cdev_p->ulp = NULL;
} }
} }
......
...@@ -115,6 +115,11 @@ struct cxio_rdev { ...@@ -115,6 +115,11 @@ struct cxio_rdev {
#define CXIO_ERROR_FATAL 1 #define CXIO_ERROR_FATAL 1
}; };
static inline int cxio_fatal_error(struct cxio_rdev *rdev_p)
{
return rdev_p->flags & CXIO_ERROR_FATAL;
}
static inline int cxio_num_stags(struct cxio_rdev *rdev_p) static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
{ {
return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5)); return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
...@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); ...@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
void cxio_flush_hw_cq(struct t3_cq *cq); void cxio_flush_hw_cq(struct t3_cq *cq);
int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
u8 *cqe_flushed, u64 *cookie, u32 *credit); u8 *cqe_flushed, u64 *cookie, u32 *credit);
int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb);
#define MOD "iw_cxgb3: " #define MOD "iw_cxgb3: "
#define PDBG(fmt, args...) pr_debug(MOD fmt, ## args) #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args)
......
...@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev) ...@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev)
static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error) static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
{ {
struct cxio_rdev *rdev = tdev->ulp; struct cxio_rdev *rdev = tdev->ulp;
struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev);
struct ib_event event;
if (status == OFFLOAD_STATUS_DOWN) if (status == OFFLOAD_STATUS_DOWN) {
rdev->flags = CXIO_ERROR_FATAL; rdev->flags = CXIO_ERROR_FATAL;
return; event.device = &rnicp->ibdev;
event.event = IB_EVENT_DEVICE_FATAL;
event.element.port_num = 0;
ib_dispatch_event(&event);
}
return;
} }
static int __init iwch_init_module(void) static int __init iwch_init_module(void)
......
...@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev) ...@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev)
return container_of(ibdev, struct iwch_dev, ibdev); return container_of(ibdev, struct iwch_dev, ibdev);
} }
static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev)
{
return container_of(rdev, struct iwch_dev, rdev);
}
static inline int t3b_device(const struct iwch_dev *rhp) static inline int t3b_device(const struct iwch_dev *rhp)
{ {
return rhp->rdev.t3cdev_p->type == T3B; return rhp->rdev.t3cdev_p->type == T3B;
......
...@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep) ...@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep)
put_ep(&ep->com); put_ep(&ep->com);
} }
int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e)
{
int error = 0;
struct cxio_rdev *rdev;
rdev = (struct cxio_rdev *)tdev->ulp;
if (cxio_fatal_error(rdev)) {
kfree_skb(skb);
return -EIO;
}
error = l2t_send(tdev, skb, l2e);
if (error)
kfree_skb(skb);
return error;
}
int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
{
int error = 0;
struct cxio_rdev *rdev;
rdev = (struct cxio_rdev *)tdev->ulp;
if (cxio_fatal_error(rdev)) {
kfree_skb(skb);
return -EIO;
}
error = cxgb3_ofld_send(tdev, skb);
if (error)
kfree_skb(skb);
return error;
}
static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
{ {
struct cpl_tid_release *req; struct cpl_tid_release *req;
...@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) ...@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
skb->priority = CPL_PRIORITY_SETUP; skb->priority = CPL_PRIORITY_SETUP;
cxgb3_ofld_send(tdev, skb); iwch_cxgb3_ofld_send(tdev, skb);
return; return;
} }
...@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) ...@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
skb->priority = CPL_PRIORITY_DATA; skb->priority = CPL_PRIORITY_DATA;
cxgb3_ofld_send(ep->com.tdev, skb); return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
} }
int iwch_resume_tid(struct iwch_ep *ep) int iwch_resume_tid(struct iwch_ep *ep)
...@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep) ...@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
req->val = 0; req->val = 0;
skb->priority = CPL_PRIORITY_DATA; skb->priority = CPL_PRIORITY_DATA;
cxgb3_ofld_send(ep->com.tdev, skb); return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
} }
static void set_emss(struct iwch_ep *ep, u16 opt) static void set_emss(struct iwch_ep *ep, u16 opt)
...@@ -252,18 +282,22 @@ static void *alloc_ep(int size, gfp_t gfp) ...@@ -252,18 +282,22 @@ static void *alloc_ep(int size, gfp_t gfp)
void __free_ep(struct kref *kref) void __free_ep(struct kref *kref)
{ {
struct iwch_ep_common *epc; struct iwch_ep *ep;
epc = container_of(kref, struct iwch_ep_common, kref); ep = container_of(container_of(kref, struct iwch_ep_common, kref),
PDBG("%s ep %p state %s\n", __func__, epc, states[state_read(epc)]); struct iwch_ep, com);
kfree(epc); PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
if (ep->com.flags & RELEASE_RESOURCES) {
cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
dst_release(ep->dst);
l2t_release(L2DATA(ep->com.tdev), ep->l2t);
}
kfree(ep);
} }
static void release_ep_resources(struct iwch_ep *ep) static void release_ep_resources(struct iwch_ep *ep)
{ {
PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid); PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid);
cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); ep->com.flags |= RELEASE_RESOURCES;
dst_release(ep->dst);
l2t_release(L2DATA(ep->com.tdev), ep->l2t);
put_ep(&ep->com); put_ep(&ep->com);
} }
...@@ -382,7 +416,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb) ...@@ -382,7 +416,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
PDBG("%s t3cdev %p\n", __func__, dev); PDBG("%s t3cdev %p\n", __func__, dev);
req->cmd = CPL_ABORT_NO_RST; req->cmd = CPL_ABORT_NO_RST;
cxgb3_ofld_send(dev, skb); iwch_cxgb3_ofld_send(dev, skb);
} }
static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
...@@ -402,8 +436,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) ...@@ -402,8 +436,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
l2t_send(ep->com.tdev, skb, ep->l2t); return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return 0;
} }
static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
...@@ -424,8 +457,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) ...@@ -424,8 +457,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
req->cmd = CPL_ABORT_SEND_RST; req->cmd = CPL_ABORT_SEND_RST;
l2t_send(ep->com.tdev, skb, ep->l2t); return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return 0;
} }
static int send_connect(struct iwch_ep *ep) static int send_connect(struct iwch_ep *ep)
...@@ -469,8 +501,7 @@ static int send_connect(struct iwch_ep *ep) ...@@ -469,8 +501,7 @@ static int send_connect(struct iwch_ep *ep)
req->opt0l = htonl(opt0l); req->opt0l = htonl(opt0l);
req->params = 0; req->params = 0;
req->opt2 = htonl(opt2); req->opt2 = htonl(opt2);
l2t_send(ep->com.tdev, skb, ep->l2t); return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return 0;
} }
static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
...@@ -527,7 +558,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) ...@@ -527,7 +558,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
req->sndseq = htonl(ep->snd_seq); req->sndseq = htonl(ep->snd_seq);
BUG_ON(ep->mpa_skb); BUG_ON(ep->mpa_skb);
ep->mpa_skb = skb; ep->mpa_skb = skb;
l2t_send(ep->com.tdev, skb, ep->l2t); iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
start_ep_timer(ep); start_ep_timer(ep);
state_set(&ep->com, MPA_REQ_SENT); state_set(&ep->com, MPA_REQ_SENT);
return; return;
...@@ -578,8 +609,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) ...@@ -578,8 +609,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
req->sndseq = htonl(ep->snd_seq); req->sndseq = htonl(ep->snd_seq);
BUG_ON(ep->mpa_skb); BUG_ON(ep->mpa_skb);
ep->mpa_skb = skb; ep->mpa_skb = skb;
l2t_send(ep->com.tdev, skb, ep->l2t); return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return 0;
} }
static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
...@@ -630,8 +660,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) ...@@ -630,8 +660,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
req->sndseq = htonl(ep->snd_seq); req->sndseq = htonl(ep->snd_seq);
ep->mpa_skb = skb; ep->mpa_skb = skb;
state_set(&ep->com, MPA_REP_SENT); state_set(&ep->com, MPA_REP_SENT);
l2t_send(ep->com.tdev, skb, ep->l2t); return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return 0;
} }
static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
...@@ -795,7 +824,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) ...@@ -795,7 +824,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits)
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
skb->priority = CPL_PRIORITY_ACK; skb->priority = CPL_PRIORITY_ACK;
cxgb3_ofld_send(ep->com.tdev, skb); iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return credits; return credits;
} }
...@@ -1127,8 +1156,8 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) ...@@ -1127,8 +1156,8 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
* We get 2 abort replies from the HW. The first one must * We get 2 abort replies from the HW. The first one must
* be ignored except for scribbling that we need one more. * be ignored except for scribbling that we need one more.
*/ */
if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) { if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) {
ep->flags |= ABORT_REQ_IN_PROGRESS; ep->com.flags |= ABORT_REQ_IN_PROGRESS;
return CPL_RET_BUF_DONE; return CPL_RET_BUF_DONE;
} }
...@@ -1203,8 +1232,7 @@ static int listen_start(struct iwch_listen_ep *ep) ...@@ -1203,8 +1232,7 @@ static int listen_start(struct iwch_listen_ep *ep)
req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
skb->priority = 1; skb->priority = 1;
cxgb3_ofld_send(ep->com.tdev, skb); return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
} }
static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
...@@ -1237,8 +1265,7 @@ static int listen_stop(struct iwch_listen_ep *ep) ...@@ -1237,8 +1265,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
req->cpu_idx = 0; req->cpu_idx = 0;
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
skb->priority = 1; skb->priority = 1;
cxgb3_ofld_send(ep->com.tdev, skb); return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
} }
static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb, static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb,
...@@ -1286,7 +1313,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) ...@@ -1286,7 +1313,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb)
rpl->opt2 = htonl(opt2); rpl->opt2 = htonl(opt2);
rpl->rsvd = rpl->opt2; /* workaround for HW bug */ rpl->rsvd = rpl->opt2; /* workaround for HW bug */
skb->priority = CPL_PRIORITY_SETUP; skb->priority = CPL_PRIORITY_SETUP;
l2t_send(ep->com.tdev, skb, ep->l2t); iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return; return;
} }
...@@ -1315,7 +1342,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, ...@@ -1315,7 +1342,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
rpl->opt2 = 0; rpl->opt2 = 0;
rpl->rsvd = rpl->opt2; rpl->rsvd = rpl->opt2;
cxgb3_ofld_send(tdev, skb); iwch_cxgb3_ofld_send(tdev, skb);
} }
} }
...@@ -1534,8 +1561,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) ...@@ -1534,8 +1561,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
* We get 2 peer aborts from the HW. The first one must * We get 2 peer aborts from the HW. The first one must
* be ignored except for scribbling that we need one more. * be ignored except for scribbling that we need one more.
*/ */
if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) { if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) {
ep->flags |= PEER_ABORT_IN_PROGRESS; ep->com.flags |= PEER_ABORT_IN_PROGRESS;
return CPL_RET_BUF_DONE; return CPL_RET_BUF_DONE;
} }
...@@ -1613,7 +1640,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) ...@@ -1613,7 +1640,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
rpl->cmd = CPL_ABORT_NO_RST; rpl->cmd = CPL_ABORT_NO_RST;
cxgb3_ofld_send(ep->com.tdev, rpl_skb); iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb);
out: out:
if (release) if (release)
release_ep_resources(ep); release_ep_resources(ep);
...@@ -2017,8 +2044,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id) ...@@ -2017,8 +2044,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id)
ep->com.rpl_done = 0; ep->com.rpl_done = 0;
ep->com.rpl_err = 0; ep->com.rpl_err = 0;
err = listen_stop(ep); err = listen_stop(ep);
if (err)
goto done;
wait_event(ep->com.waitq, ep->com.rpl_done); wait_event(ep->com.waitq, ep->com.rpl_done);
cxgb3_free_stid(ep->com.tdev, ep->stid); cxgb3_free_stid(ep->com.tdev, ep->stid);
done:
err = ep->com.rpl_err; err = ep->com.rpl_err;
cm_id->rem_ref(cm_id); cm_id->rem_ref(cm_id);
put_ep(&ep->com); put_ep(&ep->com);
...@@ -2030,12 +2060,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) ...@@ -2030,12 +2060,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
int ret=0; int ret=0;
unsigned long flags; unsigned long flags;
int close = 0; int close = 0;
int fatal = 0;
struct t3cdev *tdev;
struct cxio_rdev *rdev;
spin_lock_irqsave(&ep->com.lock, flags); spin_lock_irqsave(&ep->com.lock, flags);
PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
states[ep->com.state], abrupt); states[ep->com.state], abrupt);
tdev = (struct t3cdev *)ep->com.tdev;
rdev = (struct cxio_rdev *)tdev->ulp;
if (cxio_fatal_error(rdev)) {
fatal = 1;
close_complete_upcall(ep);
ep->com.state = DEAD;
}
switch (ep->com.state) { switch (ep->com.state) {
case MPA_REQ_WAIT: case MPA_REQ_WAIT:
case MPA_REQ_SENT: case MPA_REQ_SENT:
...@@ -2075,7 +2115,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) ...@@ -2075,7 +2115,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
ret = send_abort(ep, NULL, gfp); ret = send_abort(ep, NULL, gfp);
else else
ret = send_halfclose(ep, gfp); ret = send_halfclose(ep, gfp);
if (ret)
fatal = 1;
} }
if (fatal)
release_ep_resources(ep);
return ret; return ret;
} }
......
...@@ -147,6 +147,7 @@ enum iwch_ep_state { ...@@ -147,6 +147,7 @@ enum iwch_ep_state {
enum iwch_ep_flags { enum iwch_ep_flags {
PEER_ABORT_IN_PROGRESS = (1 << 0), PEER_ABORT_IN_PROGRESS = (1 << 0),
ABORT_REQ_IN_PROGRESS = (1 << 1), ABORT_REQ_IN_PROGRESS = (1 << 1),
RELEASE_RESOURCES = (1 << 2),
}; };
struct iwch_ep_common { struct iwch_ep_common {
...@@ -161,6 +162,7 @@ struct iwch_ep_common { ...@@ -161,6 +162,7 @@ struct iwch_ep_common {
wait_queue_head_t waitq; wait_queue_head_t waitq;
int rpl_done; int rpl_done;
int rpl_err; int rpl_err;
u32 flags;
}; };
struct iwch_listen_ep { struct iwch_listen_ep {
...@@ -188,7 +190,6 @@ struct iwch_ep { ...@@ -188,7 +190,6 @@ struct iwch_ep {
u16 plen; u16 plen;
u32 ird; u32 ird;
u32 ord; u32 ord;
u32 flags;
}; };
static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id) static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
......
...@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp) ...@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp)
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
V_FW_RIWR_LEN(flit_cnt)); V_FW_RIWR_LEN(flit_cnt));
skb->priority = CPL_PRIORITY_DATA; skb->priority = CPL_PRIORITY_DATA;
return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
} }
/* /*
...@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg) ...@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG)); V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)); wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
skb->priority = CPL_PRIORITY_DATA; skb->priority = CPL_PRIORITY_DATA;
return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
} }
/* /*
......
...@@ -394,8 +394,7 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) ...@@ -394,8 +394,7 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
PAGE_SIZE, vma->vm_page_prot)) PAGE_SIZE, vma->vm_page_prot))
return -EAGAIN; return -EAGAIN;
} else if (vma->vm_pgoff == 1 && dev->dev->caps.bf_reg_size != 0) { } else if (vma->vm_pgoff == 1 && dev->dev->caps.bf_reg_size != 0) {
/* FIXME want pgprot_writecombine() for BlueFlame pages */ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (io_remap_pfn_range(vma, vma->vm_start, if (io_remap_pfn_range(vma, vma->vm_start,
to_mucontext(context)->uar.pfn + to_mucontext(context)->uar.pfn +
......
...@@ -289,8 +289,8 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad) ...@@ -289,8 +289,8 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
static inline void static inline void
set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value) set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
{ {
wqe_words[index] = cpu_to_le32((u32) ((unsigned long)value)); wqe_words[index] = cpu_to_le32((u32) value);
wqe_words[index + 1] = cpu_to_le32((u32)(upper_32_bits((unsigned long)value))); wqe_words[index + 1] = cpu_to_le32(upper_32_bits(value));
} }
static inline void static inline void
......
...@@ -426,6 +426,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, ...@@ -426,6 +426,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (type == NES_TIMER_TYPE_CLOSE) { if (type == NES_TIMER_TYPE_CLOSE) {
new_send->timetosend += (HZ/10); new_send->timetosend += (HZ/10);
if (cm_node->recv_entry) { if (cm_node->recv_entry) {
kfree(new_send);
WARN_ON(1); WARN_ON(1);
return -EINVAL; return -EINVAL;
} }
...@@ -445,8 +446,8 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, ...@@ -445,8 +446,8 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (ret != NETDEV_TX_OK) { if (ret != NETDEV_TX_OK) {
nes_debug(NES_DBG_CM, "Error sending packet %p " nes_debug(NES_DBG_CM, "Error sending packet %p "
"(jiffies = %lu)\n", new_send, jiffies); "(jiffies = %lu)\n", new_send, jiffies);
atomic_dec(&new_send->skb->users);
new_send->timetosend = jiffies; new_send->timetosend = jiffies;
ret = NETDEV_TX_OK;
} else { } else {
cm_packets_sent++; cm_packets_sent++;
if (!send_retrans) { if (!send_retrans) {
...@@ -630,7 +631,6 @@ static void nes_cm_timer_tick(unsigned long pass) ...@@ -630,7 +631,6 @@ static void nes_cm_timer_tick(unsigned long pass)
nes_debug(NES_DBG_CM, "rexmit failed for " nes_debug(NES_DBG_CM, "rexmit failed for "
"node=%p\n", cm_node); "node=%p\n", cm_node);
cm_packets_bounced++; cm_packets_bounced++;
atomic_dec(&send_entry->skb->users);
send_entry->retrycount--; send_entry->retrycount--;
nexttimeout = jiffies + NES_SHORT_TIME; nexttimeout = jiffies + NES_SHORT_TIME;
settimer = 1; settimer = 1;
...@@ -666,11 +666,6 @@ static void nes_cm_timer_tick(unsigned long pass) ...@@ -666,11 +666,6 @@ static void nes_cm_timer_tick(unsigned long pass)
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
rem_ref_cm_node(cm_node->cm_core, cm_node); rem_ref_cm_node(cm_node->cm_core, cm_node);
if (ret != NETDEV_TX_OK) {
nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
cm_node);
break;
}
} }
if (settimer) { if (settimer) {
...@@ -1262,7 +1257,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core, ...@@ -1262,7 +1257,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
cm_node->nesqp = NULL; cm_node->nesqp = NULL;
} }
cm_node->freed = 1;
kfree(cm_node); kfree(cm_node);
return 0; return 0;
} }
...@@ -1999,13 +1993,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, ...@@ -1999,13 +1993,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
if (loopbackremotelistener == NULL) { if (loopbackremotelistener == NULL) {
create_event(cm_node, NES_CM_EVENT_ABORTED); create_event(cm_node, NES_CM_EVENT_ABORTED);
} else { } else {
atomic_inc(&cm_loopbacks);
loopback_cm_info = *cm_info; loopback_cm_info = *cm_info;
loopback_cm_info.loc_port = cm_info->rem_port; loopback_cm_info.loc_port = cm_info->rem_port;
loopback_cm_info.rem_port = cm_info->loc_port; loopback_cm_info.rem_port = cm_info->loc_port;
loopback_cm_info.cm_id = loopbackremotelistener->cm_id; loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
loopbackremotenode = make_cm_node(cm_core, nesvnic, loopbackremotenode = make_cm_node(cm_core, nesvnic,
&loopback_cm_info, loopbackremotelistener); &loopback_cm_info, loopbackremotelistener);
if (!loopbackremotenode) {
rem_ref_cm_node(cm_node->cm_core, cm_node);
return NULL;
}
atomic_inc(&cm_loopbacks);
loopbackremotenode->loopbackpartner = cm_node; loopbackremotenode->loopbackpartner = cm_node;
loopbackremotenode->tcp_cntxt.rcv_wscale = loopbackremotenode->tcp_cntxt.rcv_wscale =
NES_CM_DEFAULT_RCV_WND_SCALE; NES_CM_DEFAULT_RCV_WND_SCALE;
...@@ -2690,6 +2688,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -2690,6 +2688,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct ib_mr *ibmr = NULL; struct ib_mr *ibmr = NULL;
struct ib_phys_buf ibphysbuf; struct ib_phys_buf ibphysbuf;
struct nes_pd *nespd; struct nes_pd *nespd;
u64 tagged_offset;
...@@ -2755,10 +2754,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -2755,10 +2754,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ibphysbuf.addr = nesqp->ietf_frame_pbase; ibphysbuf.addr = nesqp->ietf_frame_pbase;
ibphysbuf.size = conn_param->private_data_len + ibphysbuf.size = conn_param->private_data_len +
sizeof(struct ietf_mpa_frame); sizeof(struct ietf_mpa_frame);
tagged_offset = (u64)(unsigned long)nesqp->ietf_frame;
ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
&ibphysbuf, 1, &ibphysbuf, 1,
IB_ACCESS_LOCAL_WRITE, IB_ACCESS_LOCAL_WRITE,
(u64 *)&nesqp->ietf_frame); &tagged_offset);
if (!ibmr) { if (!ibmr) {
nes_debug(NES_DBG_CM, "Unable to register memory region" nes_debug(NES_DBG_CM, "Unable to register memory region"
"for lSMM for cm_node = %p \n", "for lSMM for cm_node = %p \n",
...@@ -2782,7 +2782,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ...@@ -2782,7 +2782,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
sizeof(struct ietf_mpa_frame)); sizeof(struct ietf_mpa_frame));
set_wqe_64bit_value(wqe->wqe_words, set_wqe_64bit_value(wqe->wqe_words,
NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
(u64)nesqp->ietf_frame); (u64)(unsigned long)nesqp->ietf_frame);
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
cpu_to_le32(conn_param->private_data_len + cpu_to_le32(conn_param->private_data_len +
sizeof(struct ietf_mpa_frame)); sizeof(struct ietf_mpa_frame));
......
...@@ -298,7 +298,6 @@ struct nes_cm_node { ...@@ -298,7 +298,6 @@ struct nes_cm_node {
struct nes_vnic *nesvnic; struct nes_vnic *nesvnic;
int apbvt_set; int apbvt_set;
int accept_pend; int accept_pend;
int freed;
struct list_head timer_entry; struct list_head timer_entry;
struct list_head reset_entry; struct list_head reset_entry;
struct nes_qp *nesqp; struct nes_qp *nesqp;
......
This diff is collapsed.
...@@ -35,12 +35,14 @@ ...@@ -35,12 +35,14 @@
#include <linux/inet_lro.h> #include <linux/inet_lro.h>
#define NES_PHY_TYPE_CX4 1
#define NES_PHY_TYPE_1G 2 #define NES_PHY_TYPE_1G 2
#define NES_PHY_TYPE_IRIS 3 #define NES_PHY_TYPE_IRIS 3
#define NES_PHY_TYPE_ARGUS 4 #define NES_PHY_TYPE_ARGUS 4
#define NES_PHY_TYPE_PUMA_1G 5 #define NES_PHY_TYPE_PUMA_1G 5
#define NES_PHY_TYPE_PUMA_10G 6 #define NES_PHY_TYPE_PUMA_10G 6
#define NES_PHY_TYPE_GLADIUS 7 #define NES_PHY_TYPE_GLADIUS 7
#define NES_PHY_TYPE_SFP_D 8
#define NES_MULTICAST_PF_MAX 8 #define NES_MULTICAST_PF_MAX 8
......
...@@ -1426,49 +1426,55 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd ...@@ -1426,49 +1426,55 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
struct nes_vnic *nesvnic = netdev_priv(netdev); struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev; struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesdev->nesadapter; struct nes_adapter *nesadapter = nesdev->nesadapter;
u32 mac_index = nesdev->mac_index;
u8 phy_type = nesadapter->phy_type[mac_index];
u8 phy_index = nesadapter->phy_index[mac_index];
u16 phy_data; u16 phy_data;
et_cmd->duplex = DUPLEX_FULL; et_cmd->duplex = DUPLEX_FULL;
et_cmd->port = PORT_MII; et_cmd->port = PORT_MII;
et_cmd->maxtxpkt = 511;
et_cmd->maxrxpkt = 511;
if (nesadapter->OneG_Mode) { if (nesadapter->OneG_Mode) {
et_cmd->speed = SPEED_1000; et_cmd->speed = SPEED_1000;
if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { if (phy_type == NES_PHY_TYPE_PUMA_1G) {
et_cmd->supported = SUPPORTED_1000baseT_Full; et_cmd->supported = SUPPORTED_1000baseT_Full;
et_cmd->advertising = ADVERTISED_1000baseT_Full; et_cmd->advertising = ADVERTISED_1000baseT_Full;
et_cmd->autoneg = AUTONEG_DISABLE; et_cmd->autoneg = AUTONEG_DISABLE;
et_cmd->transceiver = XCVR_INTERNAL; et_cmd->transceiver = XCVR_INTERNAL;
et_cmd->phy_address = nesdev->mac_index; et_cmd->phy_address = mac_index;
} else { } else {
et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg; et_cmd->supported = SUPPORTED_1000baseT_Full
et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg; | SUPPORTED_Autoneg;
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data); et_cmd->advertising = ADVERTISED_1000baseT_Full
| ADVERTISED_Autoneg;
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
if (phy_data & 0x1000) if (phy_data & 0x1000)
et_cmd->autoneg = AUTONEG_ENABLE; et_cmd->autoneg = AUTONEG_ENABLE;
else else
et_cmd->autoneg = AUTONEG_DISABLE; et_cmd->autoneg = AUTONEG_DISABLE;
et_cmd->transceiver = XCVR_EXTERNAL; et_cmd->transceiver = XCVR_EXTERNAL;
et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; et_cmd->phy_address = phy_index;
} }
} else { return 0;
if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) || }
(nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) { if ((phy_type == NES_PHY_TYPE_IRIS) ||
(phy_type == NES_PHY_TYPE_ARGUS) ||
(phy_type == NES_PHY_TYPE_SFP_D)) {
et_cmd->transceiver = XCVR_EXTERNAL; et_cmd->transceiver = XCVR_EXTERNAL;
et_cmd->port = PORT_FIBRE; et_cmd->port = PORT_FIBRE;
et_cmd->supported = SUPPORTED_FIBRE; et_cmd->supported = SUPPORTED_FIBRE;
et_cmd->advertising = ADVERTISED_FIBRE; et_cmd->advertising = ADVERTISED_FIBRE;
et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; et_cmd->phy_address = phy_index;
} else { } else {
et_cmd->transceiver = XCVR_INTERNAL; et_cmd->transceiver = XCVR_INTERNAL;
et_cmd->supported = SUPPORTED_10000baseT_Full; et_cmd->supported = SUPPORTED_10000baseT_Full;
et_cmd->advertising = ADVERTISED_10000baseT_Full; et_cmd->advertising = ADVERTISED_10000baseT_Full;
et_cmd->phy_address = nesdev->mac_index; et_cmd->phy_address = mac_index;
} }
et_cmd->speed = SPEED_10000; et_cmd->speed = SPEED_10000;
et_cmd->autoneg = AUTONEG_DISABLE; et_cmd->autoneg = AUTONEG_DISABLE;
}
et_cmd->maxtxpkt = 511;
et_cmd->maxrxpkt = 511;
return 0; return 0;
} }
......
...@@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ...@@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
*/ */
if (ppriv->pkey == pkey) { if (ppriv->pkey == pkey) {
result = -ENOTUNIQ; result = -ENOTUNIQ;
priv = NULL;
goto err; goto err;
} }
list_for_each_entry(priv, &ppriv->child_intfs, list) { list_for_each_entry(priv, &ppriv->child_intfs, list) {
if (priv->pkey == pkey) { if (priv->pkey == pkey) {
result = -ENOTUNIQ; result = -ENOTUNIQ;
priv = NULL;
goto err; goto err;
} }
} }
...@@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ...@@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
result = ipoib_set_dev_features(priv, ppriv->ca); result = ipoib_set_dev_features(priv, ppriv->ca);
if (result) if (result)
goto device_init_failed; goto err;
priv->pkey = pkey; priv->pkey = pkey;
...@@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ...@@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
ipoib_warn(ppriv, "failed to initialize subinterface: " ipoib_warn(ppriv, "failed to initialize subinterface: "
"device %s, port %d", "device %s, port %d",
ppriv->ca->name, ppriv->port); ppriv->ca->name, ppriv->port);
goto device_init_failed; goto err;
} }
result = register_netdevice(priv->dev); result = register_netdevice(priv->dev);
...@@ -146,19 +148,19 @@ sysfs_failed: ...@@ -146,19 +148,19 @@ sysfs_failed:
register_failed: register_failed:
ipoib_dev_cleanup(priv->dev); ipoib_dev_cleanup(priv->dev);
device_init_failed:
free_netdev(priv->dev);
err: err:
mutex_unlock(&ppriv->vlan_mutex); mutex_unlock(&ppriv->vlan_mutex);
rtnl_unlock(); rtnl_unlock();
if (priv)
free_netdev(priv->dev);
return result; return result;
} }
int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
{ {
struct ipoib_dev_priv *ppriv, *priv, *tpriv; struct ipoib_dev_priv *ppriv, *priv, *tpriv;
int ret = -ENOENT; struct net_device *dev = NULL;
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
...@@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) ...@@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
unregister_netdevice(priv->dev); unregister_netdevice(priv->dev);
ipoib_dev_cleanup(priv->dev); ipoib_dev_cleanup(priv->dev);
list_del(&priv->list); list_del(&priv->list);
free_netdev(priv->dev); dev = priv->dev;
ret = 0;
break; break;
} }
} }
mutex_unlock(&ppriv->vlan_mutex); mutex_unlock(&ppriv->vlan_mutex);
rtnl_unlock(); rtnl_unlock();
return ret; if (dev) {
free_netdev(dev);
return 0;
}
return -ENODEV;
} }
...@@ -299,13 +299,14 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) ...@@ -299,13 +299,14 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
struct mlx4_cmd_mailbox *mailbox; struct mlx4_cmd_mailbox *mailbox;
int err; int err;
if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
return 0;
mailbox = mlx4_alloc_cmd_mailbox(dev); mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox)) if (IS_ERR(mailbox))
return PTR_ERR(mailbox); return PTR_ERR(mailbox);
memset(mailbox->buf, 0, 256); memset(mailbox->buf, 0, 256);
if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
return 0;
((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment