Commit e08f6d41 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:
  IB/qib: Ensure that LOS and DFE are being turned off
  RDMA/cxgb4: Couple of abort fixes
  RDMA/cxgb4: Don't truncate MR lengths
  RDMA/cxgb4: Don't exceed hw IQ depth limit for user CQs
parents 890879cf c7d74b09
...@@ -1463,9 +1463,9 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -1463,9 +1463,9 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
struct c4iw_qp_attributes attrs; struct c4iw_qp_attributes attrs;
int disconnect = 1; int disconnect = 1;
int release = 0; int release = 0;
int abort = 0;
struct tid_info *t = dev->rdev.lldi.tids; struct tid_info *t = dev->rdev.lldi.tids;
unsigned int tid = GET_TID(hdr); unsigned int tid = GET_TID(hdr);
int ret;
ep = lookup_tid(t, tid); ep = lookup_tid(t, tid);
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
...@@ -1501,10 +1501,12 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -1501,10 +1501,12 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
start_ep_timer(ep); start_ep_timer(ep);
__state_set(&ep->com, CLOSING); __state_set(&ep->com, CLOSING);
attrs.next_state = C4IW_QP_STATE_CLOSING; attrs.next_state = C4IW_QP_STATE_CLOSING;
abort = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
if (ret != -ECONNRESET) {
peer_close_upcall(ep); peer_close_upcall(ep);
disconnect = 1; disconnect = 1;
}
break; break;
case ABORTING: case ABORTING:
disconnect = 0; disconnect = 0;
...@@ -2109,15 +2111,16 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) ...@@ -2109,15 +2111,16 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
break; break;
} }
mutex_unlock(&ep->com.mutex);
if (close) { if (close) {
if (abrupt) if (abrupt) {
ret = abort_connection(ep, NULL, gfp); close_complete_upcall(ep);
else ret = send_abort(ep, NULL, gfp);
} else
ret = send_halfclose(ep, gfp); ret = send_halfclose(ep, gfp);
if (ret) if (ret)
fatal = 1; fatal = 1;
} }
mutex_unlock(&ep->com.mutex);
if (fatal) if (fatal)
release_ep_resources(ep); release_ep_resources(ep);
return ret; return ret;
...@@ -2301,6 +2304,31 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) ...@@ -2301,6 +2304,31 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
return 0; return 0;
} }
static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
{
struct cpl_abort_req_rss *req = cplhdr(skb);
struct c4iw_ep *ep;
struct tid_info *t = dev->rdev.lldi.tids;
unsigned int tid = GET_TID(req);
ep = lookup_tid(t, tid);
if (is_neg_adv_abort(req->status)) {
PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
ep->hwtid);
kfree_skb(skb);
return 0;
}
PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
ep->com.state);
/*
* Wake up any threads in rdma_init() or rdma_fini().
*/
c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
sched(dev, skb);
return 0;
}
/* /*
* Most upcalls from the T4 Core go to sched() to * Most upcalls from the T4 Core go to sched() to
* schedule the processing on a work queue. * schedule the processing on a work queue.
...@@ -2317,7 +2345,7 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = { ...@@ -2317,7 +2345,7 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = {
[CPL_PASS_ESTABLISH] = sched, [CPL_PASS_ESTABLISH] = sched,
[CPL_PEER_CLOSE] = sched, [CPL_PEER_CLOSE] = sched,
[CPL_CLOSE_CON_RPL] = sched, [CPL_CLOSE_CON_RPL] = sched,
[CPL_ABORT_REQ_RSS] = sched, [CPL_ABORT_REQ_RSS] = peer_abort_intr,
[CPL_RDMA_TERMINATE] = sched, [CPL_RDMA_TERMINATE] = sched,
[CPL_FW4_ACK] = sched, [CPL_FW4_ACK] = sched,
[CPL_SET_TCB_RPL] = set_tcb_rpl, [CPL_SET_TCB_RPL] = set_tcb_rpl,
......
...@@ -801,6 +801,10 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, ...@@ -801,6 +801,10 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
if (ucontext) { if (ucontext) {
memsize = roundup(memsize, PAGE_SIZE); memsize = roundup(memsize, PAGE_SIZE);
hwentries = memsize / sizeof *chp->cq.queue; hwentries = memsize / sizeof *chp->cq.queue;
while (hwentries > T4_MAX_IQ_SIZE) {
memsize -= PAGE_SIZE;
hwentries = memsize / sizeof *chp->cq.queue;
}
} }
chp->cq.size = hwentries; chp->cq.size = hwentries;
chp->cq.memsize = memsize; chp->cq.memsize = memsize;
......
...@@ -625,7 +625,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, ...@@ -625,7 +625,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mhp->attr.perms = c4iw_ib_to_tpt_access(acc); mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
mhp->attr.va_fbo = virt; mhp->attr.va_fbo = virt;
mhp->attr.page_size = shift - 12; mhp->attr.page_size = shift - 12;
mhp->attr.len = (u32) length; mhp->attr.len = length;
err = register_mem(rhp, php, mhp, shift); err = register_mem(rhp, php, mhp, shift);
if (err) if (err)
......
...@@ -1207,11 +1207,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, ...@@ -1207,11 +1207,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
c4iw_get_ep(&qhp->ep->com); c4iw_get_ep(&qhp->ep->com);
} }
ret = rdma_fini(rhp, qhp, ep); ret = rdma_fini(rhp, qhp, ep);
if (ret) { if (ret)
if (internal)
c4iw_get_ep(&qhp->ep->com);
goto err; goto err;
}
break; break;
case C4IW_QP_STATE_TERMINATE: case C4IW_QP_STATE_TERMINATE:
set_state(qhp, C4IW_QP_STATE_TERMINATE); set_state(qhp, C4IW_QP_STATE_TERMINATE);
......
...@@ -469,6 +469,8 @@ static u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = { ...@@ -469,6 +469,8 @@ static u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = {
#define IB_7322_LT_STATE_RECOVERIDLE 0x0f #define IB_7322_LT_STATE_RECOVERIDLE 0x0f
#define IB_7322_LT_STATE_CFGENH 0x10 #define IB_7322_LT_STATE_CFGENH 0x10
#define IB_7322_LT_STATE_CFGTEST 0x11 #define IB_7322_LT_STATE_CFGTEST 0x11
#define IB_7322_LT_STATE_CFGWAITRMTTEST 0x12
#define IB_7322_LT_STATE_CFGWAITENH 0x13
/* link state machine states from IBC */ /* link state machine states from IBC */
#define IB_7322_L_STATE_DOWN 0x0 #define IB_7322_L_STATE_DOWN 0x0
...@@ -498,8 +500,10 @@ static const u8 qib_7322_physportstate[0x20] = { ...@@ -498,8 +500,10 @@ static const u8 qib_7322_physportstate[0x20] = {
IB_PHYSPORTSTATE_LINK_ERR_RECOVER, IB_PHYSPORTSTATE_LINK_ERR_RECOVER,
[IB_7322_LT_STATE_CFGENH] = IB_PHYSPORTSTATE_CFG_ENH, [IB_7322_LT_STATE_CFGENH] = IB_PHYSPORTSTATE_CFG_ENH,
[IB_7322_LT_STATE_CFGTEST] = IB_PHYSPORTSTATE_CFG_TRAIN, [IB_7322_LT_STATE_CFGTEST] = IB_PHYSPORTSTATE_CFG_TRAIN,
[0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, [IB_7322_LT_STATE_CFGWAITRMTTEST] =
[0x13] = IB_PHYSPORTSTATE_CFG_WAIT_ENH, IB_PHYSPORTSTATE_CFG_TRAIN,
[IB_7322_LT_STATE_CFGWAITENH] =
IB_PHYSPORTSTATE_CFG_WAIT_ENH,
[0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN,
[0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN,
[0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN,
...@@ -1692,7 +1696,9 @@ static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst) ...@@ -1692,7 +1696,9 @@ static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst)
break; break;
} }
if (ibclt == IB_7322_LT_STATE_CFGTEST && if (((ibclt >= IB_7322_LT_STATE_CFGTEST &&
ibclt <= IB_7322_LT_STATE_CFGWAITENH) ||
ibclt == IB_7322_LT_STATE_LINKUP) &&
(ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) { (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) {
force_h1(ppd); force_h1(ppd);
ppd->cpspec->qdr_reforce = 1; ppd->cpspec->qdr_reforce = 1;
...@@ -7301,12 +7307,17 @@ static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data, ...@@ -7301,12 +7307,17 @@ static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data,
static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable) static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable)
{ {
u64 data = qib_read_kreg_port(ppd, krp_serdesctrl); u64 data = qib_read_kreg_port(ppd, krp_serdesctrl);
printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS %s\n", u8 state = SYM_FIELD(data, IBSerdesCtrl_0, RXLOSEN);
ppd->dd->unit, ppd->port, (enable ? "on" : "off"));
if (enable) if (enable && !state) {
printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS on\n",
ppd->dd->unit, ppd->port);
data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN); data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN);
else } else if (!enable && state) {
printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS off\n",
ppd->dd->unit, ppd->port);
data &= ~SYM_MASK(IBSerdesCtrl_0, RXLOSEN); data &= ~SYM_MASK(IBSerdesCtrl_0, RXLOSEN);
}
qib_write_kreg_port(ppd, krp_serdesctrl, data); qib_write_kreg_port(ppd, krp_serdesctrl, data);
} }
......
...@@ -96,8 +96,12 @@ void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs) ...@@ -96,8 +96,12 @@ void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs)
* states, or if it transitions from any of the up (INIT or better) * states, or if it transitions from any of the up (INIT or better)
* states into any of the down states (except link recovery), then * states into any of the down states (except link recovery), then
* call the chip-specific code to take appropriate actions. * call the chip-specific code to take appropriate actions.
*
* ppd->lflags could be 0 if this is the first time the interrupt
* handlers has been called but the link is already up.
*/ */
if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) && if (lstate >= IB_PORT_INIT &&
(!ppd->lflags || (ppd->lflags & QIBL_LINKDOWN)) &&
ltstate == IB_PHYSPORTSTATE_LINKUP) { ltstate == IB_PHYSPORTSTATE_LINKUP) {
/* transitioned to UP */ /* transitioned to UP */
if (dd->f_ib_updown(ppd, 1, ibcs)) if (dd->f_ib_updown(ppd, 1, ibcs))
......
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