From 931bc0d91639f8fbf336332aa443705004ecf61d Mon Sep 17 00:00:00 2001 From: Yuval Shaia Date: Wed, 6 Sep 2017 13:15:50 +0300 Subject: IB: Move PCI dependency from root KConfig to HW's KConfigs No reason to have dependency on PCI for the entire infiniband stack so move it to KConfig of only the drivers that actually using PCI. Signed-off-by: Yuval Shaia Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/Kconfig b/drivers/infiniband/hw/i40iw/Kconfig index 6e7d27a14061..f6d20ba88c03 100644 --- a/drivers/infiniband/hw/i40iw/Kconfig +++ b/drivers/infiniband/hw/i40iw/Kconfig @@ -1,6 +1,7 @@ config INFINIBAND_I40IW tristate "Intel(R) Ethernet X722 iWARP Driver" depends on INET && I40E + depends on PCI select GENERIC_ALLOCATOR ---help--- Intel(R) Ethernet X722 iWARP Driver -- cgit v1.2.3-59-g8ed1b From 4ea597ea3de2733873cdcfd5c4a9a2760a126daf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 29 Sep 2017 10:49:43 +0300 Subject: i40iw: delete some stray tabs These lines were indented too far by mistake. Signed-off-by: Dan Carpenter Reviewed-by: Leon Romanovsky Acked-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 5230dd3c938c..9017c1cc51d4 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1524,8 +1524,8 @@ static bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port, bool acti break; } } - if (!ret) - clear_bit(port, cm_core->active_side_ports); + if (!ret) + clear_bit(port, cm_core->active_side_ports); spin_unlock_irqrestore(&cm_core->ht_lock, flags); } else { spin_lock_irqsave(&cm_core->listen_list_lock, flags); -- cgit v1.2.3-59-g8ed1b From 1660a26adbb3aab6af0bb067e15a831f926c163a Mon Sep 17 00:00:00 2001 From: Tatyana Nikolova Date: Tue, 3 Oct 2017 11:11:46 -0500 Subject: i40iw: Do not retransmit MPA request after it is ACKed The ACK packets for an MPA request are ignored and the MPA request is retransmitted if the MPA reply is late or missing. Fix this by checking ack_rcvd variable before retransmitting a packet. Fixes: f27b4746f378 ("i40iw: add connection management code") Signed-off-by: Tatyana Nikolova Signed-off-by: Faisal Latif Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 13 ++++++++++--- drivers/infiniband/hw/i40iw/i40iw_cm.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 9017c1cc51d4..50c43766defd 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1267,13 +1267,16 @@ static void i40iw_cm_timer_tick(unsigned long pass) spin_lock_irqsave(&cm_node->retrans_list_lock, flags); goto done; } - cm_node->cm_core->stats_pkt_retrans++; spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); vsi = &cm_node->iwdev->vsi; dev = cm_node->dev; - atomic_inc(&send_entry->sqbuf->refcount); - i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf); + + if (!cm_node->ack_rcvd) { + atomic_inc(&send_entry->sqbuf->refcount); + i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf); + cm_node->cm_core->stats_pkt_retrans++; + } spin_lock_irqsave(&cm_node->retrans_list_lock, flags); if (send_entry->send_retrans) { send_entry->retranscount--; @@ -2181,6 +2184,7 @@ static struct i40iw_cm_node *i40iw_make_cm_node( cm_node->cm_id = cm_info->cm_id; ether_addr_copy(cm_node->loc_mac, netdev->dev_addr); spin_lock_init(&cm_node->retrans_list_lock); + cm_node->ack_rcvd = false; atomic_set(&cm_node->ref_count, 1); /* associate our parent CM core */ @@ -2719,7 +2723,10 @@ static int i40iw_handle_ack_pkt(struct i40iw_cm_node *cm_node, cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); if (datasize) { cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; + cm_node->ack_rcvd = false; i40iw_handle_rcv_mpa(cm_node, rbuf); + } else { + cm_node->ack_rcvd = true; } break; case I40IW_CM_STATE_LISTENING: diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.h b/drivers/infiniband/hw/i40iw/i40iw_cm.h index 45abef76295b..0d5840d2c4fc 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.h +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.h @@ -360,6 +360,7 @@ struct i40iw_cm_node { u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN]; struct i40iw_kmem_info mpa_hdr; + bool ack_rcvd; }; /* structure for client or CM to fill when making CM api calls. */ -- cgit v1.2.3-59-g8ed1b From abae49e433c5b02b6ff583eee00321eee2bad18a Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Tue, 3 Oct 2017 11:11:47 -0500 Subject: i40iw: Do not generate CQE for RTR on QP flush If RTR WQE is posted and QP is flushed, a CQE is incorrectly generated for the RTR WQE. Add code to look for the RTR and not generate a CQE when QP is flushed. Fixes: 280cfc4b74e6 ("i40iw: user kernel shared files") Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Reviewed-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_uk.c | 13 +++++++++++++ drivers/infiniband/hw/i40iw/i40iw_user.h | 1 + 2 files changed, 14 insertions(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c index 0aadb7a0d1aa..42dde5924bb5 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_uk.c +++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c @@ -821,6 +821,18 @@ static enum i40iw_status_code i40iw_cq_poll_completion(struct i40iw_cq_uk *cq, I40IW_RING_SET_TAIL(qp->rq_ring, array_idx + 1); pring = &qp->rq_ring; } else { + if (qp->first_sq_wq) { + qp->first_sq_wq = false; + if (!wqe_idx && (qp->sq_ring.head == qp->sq_ring.tail)) { + I40IW_RING_MOVE_HEAD_NOCHECK(cq->cq_ring); + I40IW_RING_MOVE_TAIL(cq->cq_ring); + set_64bit_val(cq->shadow_area, 0, + I40IW_RING_GETCURRENT_HEAD(cq->cq_ring)); + memset(info, 0, sizeof(struct i40iw_cq_poll_info)); + return i40iw_cq_poll_completion(cq, info); + } + } + if (info->comp_status != I40IW_COMPL_STATUS_FLUSHED) { info->wr_id = qp->sq_wrtrk_array[wqe_idx].wrid; info->bytes_xfered = qp->sq_wrtrk_array[wqe_idx].wr_len; @@ -988,6 +1000,7 @@ enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp, I40IW_RING_MOVE_TAIL(qp->sq_ring); I40IW_RING_MOVE_HEAD(qp->initial_ring, ret_code); qp->swqe_polarity = 1; + qp->first_sq_wq = true; qp->swqe_polarity_deferred = 1; qp->rwqe_polarity = 0; diff --git a/drivers/infiniband/hw/i40iw/i40iw_user.h b/drivers/infiniband/hw/i40iw/i40iw_user.h index 84be6f13b9c5..15e8f55983fd 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_user.h +++ b/drivers/infiniband/hw/i40iw/i40iw_user.h @@ -376,6 +376,7 @@ struct i40iw_qp_uk { u8 rwqe_polarity; u8 rq_wqe_size; u8 rq_wqe_size_multiplier; + bool first_sq_wq; bool deferred_flag; }; -- cgit v1.2.3-59-g8ed1b From 40837273d084ad1584dbaea5e8fbefe0a64f2a6b Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Tue, 3 Oct 2017 11:11:48 -0500 Subject: i40iw: Do not allow posting WR after QP is flushed A Work Request (WR) posted after QP is flushed will not get a flush completion. Correct this problem by not allowing posting of WRs after a QP is flushed. Fixes: d37498417947 ("i40iw: add files for iwarp interface") Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index 28b3d02d511b..58d815f06e4e 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -2202,6 +2202,12 @@ static int i40iw_post_send(struct ib_qp *ibqp, ukqp = &iwqp->sc_qp.qp_uk; spin_lock_irqsave(&iwqp->lock, flags); + + if (iwqp->flush_issued) { + err = -EINVAL; + goto out; + } + while (ib_wr) { inv_stag = false; memset(&info, 0, sizeof(info)); @@ -2344,6 +2350,7 @@ static int i40iw_post_send(struct ib_qp *ibqp, ib_wr = ib_wr->next; } +out: if (err) *bad_wr = ib_wr; else @@ -2376,6 +2383,12 @@ static int i40iw_post_recv(struct ib_qp *ibqp, memset(&post_recv, 0, sizeof(post_recv)); spin_lock_irqsave(&iwqp->lock, flags); + + if (iwqp->flush_issued) { + err = -EINVAL; + goto out; + } + while (ib_wr) { post_recv.num_sges = ib_wr->num_sge; post_recv.wr_id = ib_wr->wr_id; -- cgit v1.2.3-59-g8ed1b From 605cbb2c443f68b1eb74e4cfdf6c15d7d965f00a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 4 Oct 2017 17:45:41 -0700 Subject: RDMA/i40iw: Convert timers to use timer_setup() In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Faisal Latif Cc: Shiraz Saleem Cc: Doug Ledford Cc: Sean Hefty Cc: Hal Rosenstock Cc: linux-rdma@vger.kernel.org Cc: Thomas Gleixner Signed-off-by: Kees Cook Acked-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 1 + drivers/infiniband/hw/i40iw/i40iw_type.h | 1 + drivers/infiniband/hw/i40iw/i40iw_utils.c | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index 42ca5346777d..1e9f18c86e2b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -4873,6 +4873,7 @@ enum i40iw_status_code i40iw_vsi_stats_init(struct i40iw_sc_vsi *vsi, struct i40 vsi->pestat = info->pestat; vsi->pestat->hw = vsi->dev->hw; + vsi->pestat->vsi = vsi; if (info->stats_initialize) { i40iw_hw_stats_init(vsi->pestat, fcn_id, true); diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h index 63118f6d5ab4..7798e8e2f9bd 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_type.h +++ b/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -250,6 +250,7 @@ struct i40iw_vsi_pestat { struct i40iw_dev_hw_stats last_read_hw_stats; struct i40iw_dev_hw_stats_offsets hw_stats_offsets; struct timer_list stats_timer; + struct i40iw_sc_vsi *vsi; spinlock_t lock; /* rdma stats lock */ }; diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c index e52dbbb4165e..f6c76595e834 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_utils.c +++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c @@ -1445,11 +1445,12 @@ enum i40iw_status_code i40iw_puda_get_tcpip_info(struct i40iw_puda_completion_in * i40iw_hw_stats_timeout - Stats timer-handler which updates all HW stats * @vsi: pointer to the vsi structure */ -static void i40iw_hw_stats_timeout(unsigned long vsi) +static void i40iw_hw_stats_timeout(struct timer_list *t) { - struct i40iw_sc_vsi *sc_vsi = (struct i40iw_sc_vsi *)vsi; + struct i40iw_vsi_pestat *pf_devstat = from_timer(pf_devstat, t, + stats_timer); + struct i40iw_sc_vsi *sc_vsi = pf_devstat->vsi; struct i40iw_sc_dev *pf_dev = sc_vsi->dev; - struct i40iw_vsi_pestat *pf_devstat = sc_vsi->pestat; struct i40iw_vsi_pestat *vf_devstat = NULL; u16 iw_vf_idx; unsigned long flags; @@ -1480,8 +1481,7 @@ void i40iw_hw_stats_start_timer(struct i40iw_sc_vsi *vsi) { struct i40iw_vsi_pestat *devstat = vsi->pestat; - setup_timer(&devstat->stats_timer, i40iw_hw_stats_timeout, - (unsigned long)vsi); + timer_setup(&devstat->stats_timer, i40iw_hw_stats_timeout, 0); mod_timer(&devstat->stats_timer, jiffies + msecs_to_jiffies(STATS_TIMER_DELAY)); } -- cgit v1.2.3-59-g8ed1b From b965b51c55c5a21d65ca36592c6048ea60c3ace9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 11 Oct 2017 10:49:02 -0700 Subject: RDMA/i40iw: Fix a race condition Use the proper primitives to dereference the RCU pointer upper_dev->ip_ptr. Compile-tested only. Signed-off-by: Bart Van Assche Reviewed-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_utils.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c index e52dbbb4165e..7304189b62ef 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_utils.c +++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c @@ -168,11 +168,16 @@ int i40iw_inetaddr_event(struct notifier_block *notifier, if (netdev != event_netdev) return NOTIFY_DONE; - if (upper_dev) - local_ipaddr = ntohl( - ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address); - else + if (upper_dev) { + struct in_device *in; + + rcu_read_lock(); + in = __in_dev_get_rcu(upper_dev); + local_ipaddr = ntohl(in->ifa_list->ifa_address); + rcu_read_unlock(); + } else { local_ipaddr = ntohl(ifa->ifa_address); + } switch (event) { case NETDEV_DOWN: action = I40IW_ARP_DELETE; -- cgit v1.2.3-59-g8ed1b From ad4d63401008ea9ac6c5b1613d86c756c6ab9a2a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 11 Oct 2017 10:49:03 -0700 Subject: RDMA/i40iw: Suppress gcc 7 fall-through complaints Avoid that gcc 7 reports the following warning when building with W=1: warning: this statement may fall through [-Wimplicit-fallthrough=] Signed-off-by: Bart Van Assche Reviewed-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 1 + drivers/infiniband/hw/i40iw/i40iw_hw.c | 1 + drivers/infiniband/hw/i40iw/i40iw_puda.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 50c43766defd..4e1ff81c5ba0 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -2410,6 +2410,7 @@ static void i40iw_handle_rst_pkt(struct i40iw_cm_node *cm_node, case I40IW_CM_STATE_FIN_WAIT1: case I40IW_CM_STATE_LAST_ACK: cm_node->cm_id->rem_ref(cm_node->cm_id); + /* fall through */ case I40IW_CM_STATE_TIME_WAIT: cm_node->state = I40IW_CM_STATE_CLOSED; i40iw_rem_ref_cm_node(cm_node); diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c index 476867a3f584..7e9de845a350 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_hw.c +++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c @@ -410,6 +410,7 @@ void i40iw_process_aeq(struct i40iw_device *iwdev) case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG: case I40IW_AE_UDA_XMIT_IPADDR_MISMATCH: ctx_info->err_rq_idx_valid = false; + /* fall through */ default: if (!info->sq && ctx_info->err_rq_idx_valid) { ctx_info->err_rq_idx = info->wqe_idx; diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index c2cab20c4bc5..2a3bf6488b4b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -816,6 +816,7 @@ void i40iw_puda_dele_resources(struct i40iw_sc_vsi *vsi, switch (rsrc->completion) { case PUDA_HASH_CRC_COMPLETE: i40iw_free_hash_desc(rsrc->hash_desc); + /* fall through */ case PUDA_QP_CREATED: if (!reset) i40iw_puda_free_qp(rsrc); -- cgit v1.2.3-59-g8ed1b From 4956f031e13a2546da1f7049188e0ca766a25607 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 11 Oct 2017 10:49:04 -0700 Subject: RDMA/i40iw: Remove a set-but-not-used variable Signed-off-by: Bart Van Assche Reviewed-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 4e1ff81c5ba0..f5cfb224e153 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1199,7 +1199,6 @@ static void i40iw_cm_timer_tick(unsigned long pass) struct i40iw_cm_core *cm_core = (struct i40iw_cm_core *)pass; u32 settimer = 0; unsigned long timetosend; - struct i40iw_sc_dev *dev; unsigned long flags; struct list_head timer_list; @@ -1270,7 +1269,6 @@ static void i40iw_cm_timer_tick(unsigned long pass) spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); vsi = &cm_node->iwdev->vsi; - dev = cm_node->dev; if (!cm_node->ack_rcvd) { atomic_inc(&send_entry->sqbuf->refcount); -- cgit v1.2.3-59-g8ed1b From 2ec46d68464c26fc524ebf75afe42964266ea73e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 17 Oct 2017 11:37:54 -0700 Subject: RDMA/i40iw: Convert timers to use timer_setup() (part 2) In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. This includes the remaining timers missed in the earlier i40iw patch. Cc: Faisal Latif Cc: Shiraz Saleem Cc: Doug Ledford Cc: Sean Hefty Cc: Hal Rosenstock Cc: linux-rdma@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 7 +++---- drivers/infiniband/hw/i40iw/i40iw_utils.c | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 5230dd3c938c..af7526a275b8 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1188,7 +1188,7 @@ static void i40iw_handle_close_entry(struct i40iw_cm_node *cm_node, u32 rem_node * i40iw_cm_timer_tick - system's timer expired callback * @pass: Pointing to cm_core */ -static void i40iw_cm_timer_tick(unsigned long pass) +static void i40iw_cm_timer_tick(struct timer_list *t) { unsigned long nexttimeout = jiffies + I40IW_LONG_TIME; struct i40iw_cm_node *cm_node; @@ -1196,7 +1196,7 @@ static void i40iw_cm_timer_tick(unsigned long pass) struct list_head *list_core_temp; struct i40iw_sc_vsi *vsi; struct list_head *list_node; - struct i40iw_cm_core *cm_core = (struct i40iw_cm_core *)pass; + struct i40iw_cm_core *cm_core = from_timer(cm_core, t, tcp_timer); u32 settimer = 0; unsigned long timetosend; struct i40iw_sc_dev *dev; @@ -3195,8 +3195,7 @@ void i40iw_setup_cm_core(struct i40iw_device *iwdev) INIT_LIST_HEAD(&cm_core->connected_nodes); INIT_LIST_HEAD(&cm_core->listen_nodes); - setup_timer(&cm_core->tcp_timer, i40iw_cm_timer_tick, - (unsigned long)cm_core); + timer_setup(&cm_core->tcp_timer, i40iw_cm_timer_tick, 0); spin_lock_init(&cm_core->ht_lock); spin_lock_init(&cm_core->listen_list_lock); diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c index f6c76595e834..2ed31004b19c 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_utils.c +++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c @@ -870,9 +870,9 @@ void i40iw_terminate_done(struct i40iw_sc_qp *qp, int timeout_occurred) * i40iw_terminate_imeout - timeout happened * @context: points to iwarp qp */ -static void i40iw_terminate_timeout(unsigned long context) +static void i40iw_terminate_timeout(struct timer_list *t) { - struct i40iw_qp *iwqp = (struct i40iw_qp *)context; + struct i40iw_qp *iwqp = from_timer(iwqp, t, terminate_timer); struct i40iw_sc_qp *qp = (struct i40iw_sc_qp *)&iwqp->sc_qp; i40iw_terminate_done(qp, 1); @@ -889,8 +889,7 @@ void i40iw_terminate_start_timer(struct i40iw_sc_qp *qp) iwqp = (struct i40iw_qp *)qp->back_qp; i40iw_add_ref(&iwqp->ibqp); - setup_timer(&iwqp->terminate_timer, i40iw_terminate_timeout, - (unsigned long)iwqp); + timer_setup(&iwqp->terminate_timer, i40iw_terminate_timeout, 0); iwqp->terminate_timer.expires = jiffies + HZ; add_timer(&iwqp->terminate_timer); } -- cgit v1.2.3-59-g8ed1b From 2d7099fc3daa2e898424c2cb1bad4484d6c7e116 Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Mon, 16 Oct 2017 15:45:54 -0500 Subject: i40iw: Cleanup AE processing Remove unimplemented Asynchronous Events (AE) and correct names. Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 5 ----- drivers/infiniband/hw/i40iw/i40iw_d.h | 10 ++-------- drivers/infiniband/hw/i40iw/i40iw_hw.c | 2 +- 3 files changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index 1e9f18c86e2b..c46b5d10e306 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -4376,10 +4376,6 @@ static int i40iw_bld_terminate_hdr(struct i40iw_sc_qp *qp, i40iw_setup_termhdr(qp, termhdr, FLUSH_REM_ACCESS_ERR, (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT, RDMAP_TO_WRAP); break; - case I40IW_AE_LLP_RECEIVED_MARKER_AND_LENGTH_FIELDS_DONT_MATCH: - i40iw_setup_termhdr(qp, termhdr, FLUSH_LOC_LEN_ERR, - (LAYER_MPA << 4) | DDP_LLP, MPA_MARKER); - break; case I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR: i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR, (LAYER_MPA << 4) | DDP_LLP, MPA_CRC); @@ -4395,7 +4391,6 @@ static int i40iw_bld_terminate_hdr(struct i40iw_sc_qp *qp, (LAYER_DDP << 4) | DDP_CATASTROPHIC, DDP_CATASTROPHIC_LOCAL); break; case I40IW_AE_DDP_INVALID_MSN_GAP_IN_MSN: - case I40IW_AE_DDP_INVALID_MSN_RANGE_IS_NOT_VALID: i40iw_setup_termhdr(qp, termhdr, FLUSH_GENERAL_ERR, (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER, DDP_UNTAGGED_INV_MSN_RANGE); break; diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index 2ebaadbed379..dc319e987cde 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -1636,7 +1636,8 @@ enum i40iw_alignment { #define I40IW_AE_AMP_MWBIND_INVALID_BOUNDS 0x0119 #define I40IW_AE_AMP_MWBIND_TO_INVALID_PARENT 0x011a #define I40IW_AE_AMP_MWBIND_BIND_DISABLED 0x011b -#define I40IW_AE_AMP_WQE_INVALID_PARAMETER 0x0130 +#define I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG 0x0132 +#define I40IW_AE_UDA_XMIT_DGRAM_TOO_SHORT 0x0134 #define I40IW_AE_BAD_CLOSE 0x0201 #define I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE 0x0202 #define I40IW_AE_CQ_OPERATION_ERROR 0x0203 @@ -1644,12 +1645,10 @@ enum i40iw_alignment { #define I40IW_AE_RDMA_READ_WHILE_ORD_ZERO 0x0205 #define I40IW_AE_STAG_ZERO_INVALID 0x0206 #define I40IW_AE_IB_RREQ_AND_Q1_FULL 0x0207 -#define I40IW_AE_SRQ_LIMIT 0x0209 #define I40IW_AE_WQE_UNEXPECTED_OPCODE 0x020a #define I40IW_AE_WQE_INVALID_PARAMETER 0x020b #define I40IW_AE_WQE_LSMM_TOO_LONG 0x0220 #define I40IW_AE_DDP_INVALID_MSN_GAP_IN_MSN 0x0301 -#define I40IW_AE_DDP_INVALID_MSN_RANGE_IS_NOT_VALID 0x0302 #define I40IW_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER 0x0303 #define I40IW_AE_DDP_UBE_INVALID_DDP_VERSION 0x0304 #define I40IW_AE_DDP_UBE_INVALID_MO 0x0305 @@ -1663,12 +1662,10 @@ enum i40iw_alignment { #define I40IW_AE_INVALID_ARP_ENTRY 0x0401 #define I40IW_AE_INVALID_TCP_OPTION_RCVD 0x0402 #define I40IW_AE_STALE_ARP_ENTRY 0x0403 -#define I40IW_AE_INVALID_WQE_LENGTH 0x0404 #define I40IW_AE_INVALID_MAC_ENTRY 0x0405 #define I40IW_AE_LLP_CLOSE_COMPLETE 0x0501 #define I40IW_AE_LLP_CONNECTION_RESET 0x0502 #define I40IW_AE_LLP_FIN_RECEIVED 0x0503 -#define I40IW_AE_LLP_RECEIVED_MARKER_AND_LENGTH_FIELDS_DONT_MATCH 0x0504 #define I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR 0x0505 #define I40IW_AE_LLP_SEGMENT_TOO_LARGE 0x0506 #define I40IW_AE_LLP_SEGMENT_TOO_SMALL 0x0507 @@ -1685,9 +1682,6 @@ enum i40iw_alignment { #define I40IW_AE_LCE_QP_CATASTROPHIC 0x0700 #define I40IW_AE_LCE_FUNCTION_CATASTROPHIC 0x0701 #define I40IW_AE_LCE_CQ_CATASTROPHIC 0x0702 -#define I40IW_AE_UDA_XMIT_FRAG_SEQ 0x0800 -#define I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG 0x0801 -#define I40IW_AE_UDA_XMIT_IPADDR_MISMATCH 0x0802 #define I40IW_AE_QP_SUSPEND_COMPLETE 0x0900 #define OP_DELETE_LOCAL_MAC_IPADDR_ENTRY 1 diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c index 7e9de845a350..e96bdafbcbb3 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_hw.c +++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c @@ -408,7 +408,7 @@ void i40iw_process_aeq(struct i40iw_device *iwdev) case I40IW_AE_LCE_FUNCTION_CATASTROPHIC: case I40IW_AE_LCE_CQ_CATASTROPHIC: case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG: - case I40IW_AE_UDA_XMIT_IPADDR_MISMATCH: + case I40IW_AE_UDA_XMIT_DGRAM_TOO_SHORT: ctx_info->err_rq_idx_valid = false; /* fall through */ default: -- cgit v1.2.3-59-g8ed1b From 4236f4b99ee0dcefea909ab2a179dc6a0abcb8d6 Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Mon, 16 Oct 2017 15:45:55 -0500 Subject: i40iw: Ignore AE source field in AEQE for some AEs The AE source field in Asynchronous Event Queue Entry (AEQE) is not set by the hardware for some AEs, but the code assumes it does. This results in incorrect processing of some AEs. Fix this by setting ae_src to I40IW_AE_SOURCE_RSVD for those AEs. Fixes: 86dbcd0f12e9 ("i40iw: add file to handle cqp calls") Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 49 ++++++++++++++++++++++++++++++++ drivers/infiniband/hw/i40iw/i40iw_d.h | 1 + 2 files changed, 50 insertions(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index c46b5d10e306..04284e819011 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -1774,6 +1774,53 @@ static enum i40iw_status_code i40iw_sc_get_next_aeqe(struct i40iw_sc_aeq *aeq, info->iwarp_state = (u8)RS_64(temp, I40IW_AEQE_IWSTATE); info->q2_data_written = (u8)RS_64(temp, I40IW_AEQE_Q2DATA); info->aeqe_overflow = (bool)RS_64(temp, I40IW_AEQE_OVERFLOW); + + switch (info->ae_id) { + case I40IW_AE_PRIV_OPERATION_DENIED: + case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG: + case I40IW_AE_UDA_XMIT_DGRAM_TOO_SHORT: + case I40IW_AE_BAD_CLOSE: + case I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE: + case I40IW_AE_RDMA_READ_WHILE_ORD_ZERO: + case I40IW_AE_STAG_ZERO_INVALID: + case I40IW_AE_IB_RREQ_AND_Q1_FULL: + case I40IW_AE_WQE_UNEXPECTED_OPCODE: + case I40IW_AE_DDP_UBE_INVALID_DDP_VERSION: + case I40IW_AE_DDP_UBE_INVALID_MO: + case I40IW_AE_DDP_UBE_INVALID_QN: + case I40IW_AE_DDP_NO_L_BIT: + case I40IW_AE_RDMAP_ROE_INVALID_RDMAP_VERSION: + case I40IW_AE_RDMAP_ROE_UNEXPECTED_OPCODE: + case I40IW_AE_ROE_INVALID_RDMA_READ_REQUEST: + case I40IW_AE_ROE_INVALID_RDMA_WRITE_OR_READ_RESP: + case I40IW_AE_INVALID_ARP_ENTRY: + case I40IW_AE_INVALID_TCP_OPTION_RCVD: + case I40IW_AE_STALE_ARP_ENTRY: + case I40IW_AE_LLP_CLOSE_COMPLETE: + case I40IW_AE_LLP_CONNECTION_RESET: + case I40IW_AE_LLP_FIN_RECEIVED: + case I40IW_AE_LLP_RECEIVED_MPA_CRC_ERROR: + case I40IW_AE_LLP_SEGMENT_TOO_SMALL: + case I40IW_AE_LLP_SYN_RECEIVED: + case I40IW_AE_LLP_TERMINATE_RECEIVED: + case I40IW_AE_LLP_TOO_MANY_RETRIES: + case I40IW_AE_LLP_DOUBT_REACHABILITY: + case I40IW_AE_RESET_SENT: + case I40IW_AE_TERMINATE_SENT: + case I40IW_AE_RESET_NOT_SENT: + case I40IW_AE_LCE_QP_CATASTROPHIC: + case I40IW_AE_QP_SUSPEND_COMPLETE: + info->qp = true; + info->compl_ctx = compl_ctx; + ae_src = I40IW_AE_SOURCE_RSVD; + break; + case I40IW_AE_LCE_CQ_CATASTROPHIC: + info->cq = true; + info->compl_ctx = LS_64_1(compl_ctx, 1); + ae_src = I40IW_AE_SOURCE_RSVD; + break; + } + switch (ae_src) { case I40IW_AE_SOURCE_RQ: case I40IW_AE_SOURCE_RQ_0011: @@ -1807,6 +1854,8 @@ static enum i40iw_status_code i40iw_sc_get_next_aeqe(struct i40iw_sc_aeq *aeq, info->compl_ctx = compl_ctx; info->out_rdrsp = true; break; + case I40IW_AE_SOURCE_RSVD: + /* fallthrough */ default: break; } diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index dc319e987cde..60c785a68b5e 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -128,6 +128,7 @@ &_ceq->ceqe_base[I40IW_RING_GETCURRENT_TAIL(_ceq->ceq_ring)] \ ) +#define I40IW_AE_SOURCE_RSVD 0x0 #define I40IW_AE_SOURCE_RQ 0x1 #define I40IW_AE_SOURCE_RQ_0011 0x3 -- cgit v1.2.3-59-g8ed1b From de9f063468d00fe961723f72ac7d60f51f528d98 Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Mon, 16 Oct 2017 15:45:56 -0500 Subject: i40iw: Remove unused static_rsrc from i40iw_create_qp_info The field static_rsrc in i40iw_create_qp_info is unused and not needed. Remove it. Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 -- drivers/infiniband/hw/i40iw/i40iw_d.h | 3 --- drivers/infiniband/hw/i40iw/i40iw_type.h | 2 -- 3 files changed, 7 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index 04284e819011..a4bd968f8bc1 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -2448,7 +2448,6 @@ static enum i40iw_status_code i40iw_sc_qp_create( LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) | LS_64(qp->virtual_map, I40IW_CQPSQ_QP_VQ) | LS_64(info->cq_num_valid, I40IW_CQPSQ_QP_CQNUMVALID) | - LS_64(info->static_rsrc, I40IW_CQPSQ_QP_STATRSRC) | LS_64(info->arp_cache_idx_valid, I40IW_CQPSQ_QP_ARPTABIDXVALID) | LS_64(info->next_iwarp_state, I40IW_CQPSQ_QP_NEXTIWSTATE) | LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID); @@ -2511,7 +2510,6 @@ static enum i40iw_status_code i40iw_sc_qp_modify( LS_64(info->cq_num_valid, I40IW_CQPSQ_QP_CQNUMVALID) | LS_64(info->force_loopback, I40IW_CQPSQ_QP_FORCELOOPBACK) | LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) | - LS_64(info->static_rsrc, I40IW_CQPSQ_QP_STATRSRC) | LS_64(info->remove_hash_idx, I40IW_CQPSQ_QP_REMOVEHASHENTRY) | LS_64(term_actions, I40IW_CQPSQ_QP_TERMACT) | LS_64(info->reset_tcp_conn, I40IW_CQPSQ_QP_RESETCON) | diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index 60c785a68b5e..40d474384a4e 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -540,9 +540,6 @@ #define I40IW_CQPSQ_QP_MSSCHANGE_SHIFT 52 #define I40IW_CQPSQ_QP_MSSCHANGE_MASK (1ULL << I40IW_CQPSQ_QP_MSSCHANGE_SHIFT) -#define I40IW_CQPSQ_QP_STATRSRC_SHIFT 53 -#define I40IW_CQPSQ_QP_STATRSRC_MASK (1ULL << I40IW_CQPSQ_QP_STATRSRC_SHIFT) - #define I40IW_CQPSQ_QP_IGNOREMWBOUND_SHIFT 54 #define I40IW_CQPSQ_QP_IGNOREMWBOUND_MASK \ (1ULL << I40IW_CQPSQ_QP_IGNOREMWBOUND_SHIFT) diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h index 7798e8e2f9bd..608164250c65 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_type.h +++ b/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -535,7 +535,6 @@ struct i40iw_create_qp_info { bool ord_valid; bool tcp_ctx_valid; bool cq_num_valid; - bool static_rsrc; bool arp_cache_idx_valid; }; @@ -547,7 +546,6 @@ struct i40iw_modify_qp_info { bool ord_valid; bool tcp_ctx_valid; bool cq_num_valid; - bool static_rsrc; bool arp_cache_idx_valid; bool reset_tcp_conn; bool remove_hash_idx; -- cgit v1.2.3-59-g8ed1b From 66f49f88aef8388da03753ce9c60758bacd730bf Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Mon, 16 Oct 2017 15:45:57 -0500 Subject: i40iw: Move exception_lan_queue to VSI structure Consolidate exception_lan_queue under VSI structure where it belongs. Remove it from device and QP structures. Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 6 +++--- drivers/infiniband/hw/i40iw/i40iw_main.c | 4 ++-- drivers/infiniband/hw/i40iw/i40iw_type.h | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index a4bd968f8bc1..a3ea42888576 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -2406,7 +2406,6 @@ static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp, qp->rcv_tph_en = info->rcv_tph_en; qp->xmit_tph_en = info->xmit_tph_en; qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle; - qp->exception_lan_queue = qp->pd->dev->exception_lan_queue; return 0; } @@ -2741,7 +2740,7 @@ static enum i40iw_status_code i40iw_sc_qp_setctx( LS_64(qp->sq_tph_val, I40IWQPC_SQTPHVAL) | LS_64(qp->rq_tph_val, I40IWQPC_RQTPHVAL) | LS_64(qp->qs_handle, I40IWQPC_QSHANDLE) | - LS_64(qp->exception_lan_queue, I40IWQPC_EXCEPTION_LAN_QUEUE)); + LS_64(vsi->exception_lan_queue, I40IWQPC_EXCEPTION_LAN_QUEUE)); if (info->iwarp_info_valid) { qw0 |= LS_64(iw->ddp_ver, I40IWQPC_DDP_VER) | @@ -4584,6 +4583,8 @@ void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *inf vsi->dev = info->dev; vsi->back_vsi = info->back_vsi; vsi->mss = info->params->mss; + vsi->exception_lan_queue = info->exception_lan_queue; + i40iw_fill_qos_list(info->params->qs_handle_list); for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) { @@ -5068,7 +5069,6 @@ enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev, dev->debug_mask = info->debug_mask; dev->hmc_fn_id = info->hmc_fn_id; - dev->exception_lan_queue = info->exception_lan_queue; dev->is_pf = info->is_pf; dev->fpm_query_buf_pa = info->fpm_query_buf_pa; diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c index 27590ae21881..ee0323fe765d 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -958,7 +958,7 @@ static enum i40iw_status_code i40iw_initialize_ieq(struct i40iw_device *iwdev) memset(&info, 0, sizeof(info)); info.type = I40IW_PUDA_RSRC_TYPE_IEQ; info.cq_id = 2; - info.qp_id = iwdev->sc_dev.exception_lan_queue; + info.qp_id = iwdev->vsi.exception_lan_queue; info.count = 1; info.pd_id = 2; info.sq_size = 8192; @@ -1338,7 +1338,6 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, iwdev->dcb = true; } i40iw_pr_info("DCB is set/clear = %d\n", iwdev->dcb); - info.exception_lan_queue = 1; info.vchnl_send = i40iw_virtchnl_send; status = i40iw_device_init(&iwdev->sc_dev, &info); @@ -1348,6 +1347,7 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, vsi_info.dev = &iwdev->sc_dev; vsi_info.back_vsi = (void *)iwdev; vsi_info.params = &l2params; + vsi_info.exception_lan_queue = 1; i40iw_sc_vsi_init(&iwdev->vsi, &vsi_info); if (dev->is_pf) { diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h index 608164250c65..e8d153b963ec 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_type.h +++ b/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -381,7 +381,6 @@ struct i40iw_sc_qp { u8 *q2_buf; u64 qp_compl_ctx; u16 qs_handle; - u16 exception_lan_queue; u16 push_idx; u8 sq_tph_val; u8 rq_tph_val; @@ -460,6 +459,7 @@ struct i40iw_sc_vsi { u32 ieq_count; struct i40iw_virt_mem ieq_mem; struct i40iw_puda_rsrc *ieq; + u16 exception_lan_queue; u16 mss; u8 fcn_id; bool stats_fcn_id_alloc; @@ -502,7 +502,6 @@ struct i40iw_sc_dev { struct i40iw_hmc_fpm_misc hmc_fpm_misc; u32 debug_mask; - u16 exception_lan_queue; u8 hmc_fn_id; bool is_pf; bool vchnl_up; @@ -574,6 +573,7 @@ struct i40iw_vsi_init_info { struct i40iw_sc_dev *dev; void *back_vsi; struct i40iw_l2params *params; + u16 exception_lan_queue; }; struct i40iw_vsi_stats_info { @@ -591,7 +591,6 @@ struct i40iw_device_init_info { struct i40iw_hw *hw; void __iomem *bar0; enum i40iw_status_code (*vchnl_send)(struct i40iw_sc_dev *, u32, u8 *, u16); - u16 exception_lan_queue; u8 hmc_fn_id; bool is_pf; u32 debug_mask; -- cgit v1.2.3-59-g8ed1b From b0d4f703693aabf727924d1568cc36e1b7484c66 Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Mon, 16 Oct 2017 15:45:58 -0500 Subject: i40iw: Remove unused structures Some structures for post SQ operation are not used. Remove the following: i40iw_post_send_w_inv i40iw_post_inline_send_w_inv send_w_sol send_w_inv send_w_sol_inv inline_send_w_sol inline_send_w_inv inline_send_w_sol_inv Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_user.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_user.h b/drivers/infiniband/hw/i40iw/i40iw_user.h index 15e8f55983fd..a898f9923a6f 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_user.h +++ b/drivers/infiniband/hw/i40iw/i40iw_user.h @@ -204,18 +204,6 @@ struct i40iw_post_inline_send { u32 len; }; -struct i40iw_post_send_w_inv { - i40iw_sgl sg_list; - u32 num_sges; - i40iw_stag remote_stag_to_inv; -}; - -struct i40iw_post_inline_send_w_inv { - void *data; - u32 len; - i40iw_stag remote_stag_to_inv; -}; - struct i40iw_rdma_write { i40iw_sgl lo_sg_list; u32 num_lo_sges; @@ -257,9 +245,6 @@ struct i40iw_post_sq_info { bool defer_flag; union { struct i40iw_post_send send; - struct i40iw_post_send send_w_sol; - struct i40iw_post_send_w_inv send_w_inv; - struct i40iw_post_send_w_inv send_w_sol_inv; struct i40iw_rdma_write rdma_write; struct i40iw_rdma_read rdma_read; struct i40iw_rdma_read rdma_read_inv; @@ -267,9 +252,6 @@ struct i40iw_post_sq_info { struct i40iw_inv_local_stag inv_local_stag; struct i40iw_inline_rdma_write inline_rdma_write; struct i40iw_post_inline_send inline_send; - struct i40iw_post_inline_send inline_send_w_sol; - struct i40iw_post_inline_send_w_inv inline_send_w_inv; - struct i40iw_post_inline_send_w_inv inline_send_w_sol_inv; } op; }; -- cgit v1.2.3-59-g8ed1b From 343d86bd45d2d5770acc8cab2e4c4b4f6595d1f6 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Mon, 16 Oct 2017 15:45:59 -0500 Subject: i40iw: Account for IPv6 header when setting MSS The IPv6 header size is not subtracted from MTU when MSS is set for QPs. Save MTU opposed to MSS in the vsi struct during initialization and calculate the MSS based on IPv4 vs IPv6 connection. Fixes: f27b4746f378 ("i40iw: add connection management code") Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw.h | 3 --- drivers/infiniband/hw/i40iw/i40iw_cm.c | 3 ++- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 5 ++--- drivers/infiniband/hw/i40iw/i40iw_d.h | 4 ++++ drivers/infiniband/hw/i40iw/i40iw_main.c | 6 +++--- drivers/infiniband/hw/i40iw/i40iw_puda.c | 3 ++- drivers/infiniband/hw/i40iw/i40iw_type.h | 4 ++-- 7 files changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h index a65e4cbdce2f..4ae9131b6350 100644 --- a/drivers/infiniband/hw/i40iw/i40iw.h +++ b/drivers/infiniband/hw/i40iw/i40iw.h @@ -119,9 +119,6 @@ #define I40IW_CQP_COMPL_SQ_WQE_FLUSHED 3 #define I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED 4 -#define I40IW_MTU_TO_MSS 40 -#define I40IW_DEFAULT_MSS 1460 - struct i40iw_cqp_compl_info { u32 op_ret_val; u16 maj_err_code; diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 4bd54b367532..493d6ef3d2d5 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -2193,7 +2193,8 @@ static struct i40iw_cm_node *i40iw_make_cm_node( I40IW_CM_DEFAULT_RCV_WND_SCALED >> I40IW_CM_DEFAULT_RCV_WND_SCALE; ts = current_kernel_time(); cm_node->tcp_cntxt.loc_seq_num = ts.tv_nsec; - cm_node->tcp_cntxt.mss = iwdev->vsi.mss; + cm_node->tcp_cntxt.mss = (cm_node->ipv4) ? (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV4) : + (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV6); cm_node->iwdev = iwdev; cm_node->dev = &iwdev->sc_dev; diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index a3ea42888576..fbc0f95b0ebd 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -348,7 +348,7 @@ void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2pa u16 qs_handle; int i; - vsi->mss = l2params->mss; + vsi->mtu = l2params->mtu; i40iw_fill_qos_list(l2params->qs_handle_list); for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) { @@ -4582,9 +4582,8 @@ void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *inf vsi->dev = info->dev; vsi->back_vsi = info->back_vsi; - vsi->mss = info->params->mss; + vsi->mtu = info->params->mtu; vsi->exception_lan_queue = info->exception_lan_queue; - i40iw_fill_qos_list(info->params->qs_handle_list); for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) { diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index 40d474384a4e..17ed45b42df4 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -73,6 +73,10 @@ #define I40IW_FIRST_NON_PF_STAT 4 +#define I40IW_MTU_TO_MSS_IPV4 40 +#define I40IW_MTU_TO_MSS_IPV6 60 +#define I40IW_DEFAULT_MTU 1500 + #define LS_64_1(val, bits) ((u64)(uintptr_t)val << bits) #define RS_64_1(val, bits) ((u64)(uintptr_t)val >> bits) #define LS_32_1(val, bits) (u32)(val << bits) diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c index ee0323fe765d..438f5269548b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -1327,8 +1327,8 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, info.bar0 = ldev->hw_addr; info.hw = &iwdev->hw; info.debug_mask = debug; - l2params.mss = - (ldev->params.mtu) ? ldev->params.mtu - I40IW_MTU_TO_MSS : I40IW_DEFAULT_MSS; + l2params.mtu = + (ldev->params.mtu) ? ldev->params.mtu : I40IW_DEFAULT_MTU; for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) { qset = ldev->params.qos.prio_qos[i].qs_handle; l2params.qs_handle_list[i] = qset; @@ -1748,7 +1748,7 @@ static void i40iw_l2param_change(struct i40e_info *ldev, struct i40e_client *cli for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) l2params->qs_handle_list[i] = params->qos.prio_qos[i].qs_handle; - l2params->mss = (params->mtu) ? params->mtu - I40IW_MTU_TO_MSS : iwdev->vsi.mss; + l2params->mtu = (params->mtu) ? params->mtu : iwdev->vsi.mtu; INIT_WORK(&work->work, i40iw_l2params_worker); queue_work(iwdev->param_wq, &work->work); diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index dfbade0ad003..af6d0dc82b89 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -1401,7 +1401,8 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq, pfpdu->rcv_nxt = fps; pfpdu->fps = fps; pfpdu->mode = true; - pfpdu->max_fpdu_data = ieq->vsi->mss; + pfpdu->max_fpdu_data = (buf->ipv4) ? (ieq->vsi->mtu - I40IW_MTU_TO_MSS_IPV4) : + (ieq->vsi->mtu - I40IW_MTU_TO_MSS_IPV6); pfpdu->pmode_count++; INIT_LIST_HEAD(rxlist); i40iw_ieq_check_first_buf(buf, fps); diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h index e8d153b963ec..f443f2075d6f 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_type.h +++ b/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -460,7 +460,7 @@ struct i40iw_sc_vsi { struct i40iw_virt_mem ieq_mem; struct i40iw_puda_rsrc *ieq; u16 exception_lan_queue; - u16 mss; + u16 mtu; u8 fcn_id; bool stats_fcn_id_alloc; struct i40iw_qos qos[I40IW_MAX_USER_PRIORITY]; @@ -566,7 +566,7 @@ struct i40iw_ccq_cqe_info { struct i40iw_l2params { u16 qs_handle_list[I40IW_MAX_USER_PRIORITY]; - u16 mss; + u16 mtu; }; struct i40iw_vsi_init_info { -- cgit v1.2.3-59-g8ed1b From 9381699eedd1b5dd5b490e993b870dff7571ddcf Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Mon, 16 Oct 2017 15:46:00 -0500 Subject: i40iw: Move ceq_valid to i40iw_sc_dev structure Completion Event Queues are created and destroyed on a per device basis as opposed to per User-space Direct Access resource. Move ceq_valid to the correct place in i40iw_sc_dev from i40iw_puda_rsrc. Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_main.c | 19 ++++++++++--------- drivers/infiniband/hw/i40iw/i40iw_puda.c | 9 ++++----- drivers/infiniband/hw/i40iw/i40iw_puda.h | 2 -- drivers/infiniband/hw/i40iw/i40iw_type.h | 1 + 4 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c index 438f5269548b..dc6b338772e9 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -353,6 +353,8 @@ static void i40iw_dele_ceqs(struct i40iw_device *iwdev) i40iw_disable_irq(dev, msix_vec, (void *)iwceq); i40iw_destroy_ceq(iwdev, iwceq); } + + iwdev->sc_dev.ceq_valid = false; } /** @@ -810,17 +812,16 @@ static enum i40iw_status_code i40iw_setup_ceqs(struct i40iw_device *iwdev, i40iw_enable_intr(&iwdev->sc_dev, msix_vec->idx); iwdev->ceqs_count++; } - exit: - if (status) { - if (!iwdev->ceqs_count) { - kfree(iwdev->ceqlist); - iwdev->ceqlist = NULL; - } else { - status = 0; - } + if (status && !iwdev->ceqs_count) { + kfree(iwdev->ceqlist); + iwdev->ceqlist = NULL; + return status; + } else { + iwdev->sc_dev.ceq_valid = true; + return 0; } - return status; + } /** diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index af6d0dc82b89..fee6643d6626 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -611,7 +611,7 @@ static enum i40iw_status_code i40iw_puda_qp_create(struct i40iw_puda_rsrc *rsrc) qp->user_pri = 0; i40iw_qp_add_qos(qp); i40iw_puda_qp_setctx(rsrc); - if (rsrc->ceq_valid) + if (rsrc->dev->ceq_valid) ret = i40iw_cqp_qp_create_cmd(rsrc->dev, qp); else ret = i40iw_puda_qp_wqe(rsrc->dev, qp); @@ -704,7 +704,7 @@ static enum i40iw_status_code i40iw_puda_cq_create(struct i40iw_puda_rsrc *rsrc) ret = dev->iw_priv_cq_ops->cq_init(cq, &info); if (ret) goto error; - if (rsrc->ceq_valid) + if (rsrc->dev->ceq_valid) ret = i40iw_cqp_cq_create_cmd(dev, cq); else ret = i40iw_puda_cq_wqe(dev, cq); @@ -724,7 +724,7 @@ static void i40iw_puda_free_qp(struct i40iw_puda_rsrc *rsrc) struct i40iw_ccq_cqe_info compl_info; struct i40iw_sc_dev *dev = rsrc->dev; - if (rsrc->ceq_valid) { + if (rsrc->dev->ceq_valid) { i40iw_cqp_qp_destroy_cmd(dev, &rsrc->qp); return; } @@ -757,7 +757,7 @@ static void i40iw_puda_free_cq(struct i40iw_puda_rsrc *rsrc) struct i40iw_ccq_cqe_info compl_info; struct i40iw_sc_dev *dev = rsrc->dev; - if (rsrc->ceq_valid) { + if (rsrc->dev->ceq_valid) { i40iw_cqp_cq_destroy_cmd(dev, &rsrc->cq); return; } @@ -922,7 +922,6 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi, rsrc->xmit_complete = i40iw_ieq_tx_compl; } - rsrc->ceq_valid = info->ceq_valid; rsrc->type = info->type; rsrc->sq_wrtrk_array = (struct i40iw_sq_uk_wr_trk_info *)((u8 *)vmem->va + pudasize); rsrc->rq_wrid_array = (u64 *)((u8 *)vmem->va + pudasize + sqwridsize); diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.h b/drivers/infiniband/hw/i40iw/i40iw_puda.h index dba05ce7d392..660aa3edae56 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.h +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.h @@ -100,7 +100,6 @@ struct i40iw_puda_rsrc_info { enum puda_resource_type type; /* ILQ or IEQ */ u32 count; u16 pd_id; - bool ceq_valid; u32 cq_id; u32 qp_id; u32 sq_size; @@ -125,7 +124,6 @@ struct i40iw_puda_rsrc { enum puda_resource_type type; u16 buf_size; /*buffer must be max datalen + tcpip hdr + mac */ u16 mss; - bool ceq_valid; u32 cq_id; u32 qp_id; u32 sq_size; diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h index f443f2075d6f..a27d392c92a2 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_type.h +++ b/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -505,6 +505,7 @@ struct i40iw_sc_dev { u8 hmc_fn_id; bool is_pf; bool vchnl_up; + bool ceq_valid; u8 vf_id; wait_queue_head_t vf_reqs; u64 cqp_cmd_stats[OP_SIZE_CQP_STAT_ARRAY]; -- cgit v1.2.3-59-g8ed1b From 5b4a1a8b87fda31c1a1d44aba7e6926167610a20 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Mon, 16 Oct 2017 15:46:01 -0500 Subject: i40iw: Reinitialize IEQ on MTU change On a netdev MTU change event, the iWARP Exception Queue (IEQ) buffers may not be sized properly to handle the new MTU. Reinitialize the IEQ with new MTU size on MTU change event. Also, add define for the max ethernet frame size field in IEQ QP context instead of the snd_mss define which is for iWARP QPs' MSS field. Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 5 ++++- drivers/infiniband/hw/i40iw/i40iw_d.h | 3 +++ drivers/infiniband/hw/i40iw/i40iw_main.c | 19 +++++++++++++++++-- drivers/infiniband/hw/i40iw/i40iw_p.h | 1 + drivers/infiniband/hw/i40iw/i40iw_puda.c | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index fbc0f95b0ebd..3b6d12176413 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -348,7 +348,10 @@ void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2pa u16 qs_handle; int i; - vsi->mtu = l2params->mtu; + if (vsi->mtu != l2params->mtu) { + vsi->mtu = l2params->mtu; + i40iw_reinitialize_ieq(dev); + } i40iw_fill_qos_list(l2params->qs_handle_list); for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) { diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index 17ed45b42df4..f1a6ce6c927c 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -1107,6 +1107,9 @@ #define I40IWQPC_SNDMSS_SHIFT 16 #define I40IWQPC_SNDMSS_MASK (0x3fffUL << I40IWQPC_SNDMSS_SHIFT) +#define I40IW_UDA_QPC_MAXFRAMESIZE_SHIFT 16 +#define I40IW_UDA_QPC_MAXFRAMESIZE_MASK (0x3fffUL << I40IW_UDA_QPC_MAXFRAMESIZE_SHIFT) + #define I40IWQPC_VLANTAG_SHIFT 32 #define I40IWQPC_VLANTAG_MASK (0xffffULL << I40IWQPC_VLANTAG_SHIFT) diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c index dc6b338772e9..e824296713e2 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -964,14 +964,29 @@ static enum i40iw_status_code i40iw_initialize_ieq(struct i40iw_device *iwdev) info.pd_id = 2; info.sq_size = 8192; info.rq_size = 8192; - info.buf_size = 2048; - info.tx_buf_cnt = 16384; + info.buf_size = iwdev->vsi.mtu + VLAN_ETH_HLEN; + info.tx_buf_cnt = 4096; status = i40iw_puda_create_rsrc(&iwdev->vsi, &info); if (status) i40iw_pr_err("ieq create fail\n"); return status; } +/** + * i40iw_reinitialize_ieq - destroy and re-create ieq + * @dev: iwarp device + */ +void i40iw_reinitialize_ieq(struct i40iw_sc_dev *dev) +{ + struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev; + + i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, false); + if (i40iw_initialize_ieq(iwdev)) { + iwdev->reset = true; + i40iw_request_reset(iwdev); + } +} + /** * i40iw_hmc_setup - create hmc objects for the device * @iwdev: iwarp device diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h index 5498ad01c280..2ad5a8ebee7e 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_p.h +++ b/drivers/infiniband/hw/i40iw/i40iw_p.h @@ -123,5 +123,6 @@ enum i40iw_status_code i40iw_allocate_virt_mem(struct i40iw_hw *hw, enum i40iw_status_code i40iw_free_virt_mem(struct i40iw_hw *hw, struct i40iw_virt_mem *mem); u8 i40iw_get_encoded_wqe_size(u32 wqsize, bool cqpsq); +void i40iw_reinitialize_ieq(struct i40iw_sc_dev *dev); #endif diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index fee6643d6626..19ced8bd64c0 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -488,7 +488,7 @@ static void i40iw_puda_qp_setctx(struct i40iw_puda_rsrc *rsrc) LS_64(qp->hw_rq_size, I40IWQPC_RQSIZE) | LS_64(qp->hw_sq_size, I40IWQPC_SQSIZE)); - set_64bit_val(qp_ctx, 48, LS_64(1514, I40IWQPC_SNDMSS)); + set_64bit_val(qp_ctx, 48, LS_64(rsrc->buf_size, I40IW_UDA_QPC_MAXFRAMESIZE)); set_64bit_val(qp_ctx, 56, 0); set_64bit_val(qp_ctx, 64, 1); -- cgit v1.2.3-59-g8ed1b From 1196923838cf1d2b7abcb9a1007eede09ad93acd Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Mon, 16 Oct 2017 15:46:02 -0500 Subject: i40iw: Refactor queue depth calculation Queue depth calculations use a mix of work requests and actual number of bytes. Consolidate all calculations using minimum WQE size to avoid confusion. Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_d.h | 9 ++++- drivers/infiniband/hw/i40iw/i40iw_uk.c | 63 ++++++++++++++++++++++++------- drivers/infiniband/hw/i40iw/i40iw_user.h | 4 +- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 34 ++++------------- 4 files changed, 67 insertions(+), 43 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h index f1a6ce6c927c..65ec39e3746b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_d.h +++ b/drivers/infiniband/hw/i40iw/i40iw_d.h @@ -1301,8 +1301,13 @@ (0xffffffffULL << I40IWQPC_LOCAL_IPADDR0_SHIFT) /* wqe size considering 32 bytes per wqe*/ -#define I40IWQP_SW_MIN_WQSIZE 4 /* 128 bytes */ -#define I40IWQP_SW_MAX_WQSIZE 2048 /* 2048 bytes */ +#define I40IW_QP_SW_MIN_WQSIZE 4 /*in WRs*/ +#define I40IW_SQ_RSVD 2 +#define I40IW_RQ_RSVD 1 +#define I40IW_MAX_QUANTAS_PER_WR 2 +#define I40IW_QP_SW_MAX_SQ_QUANTAS 2048 +#define I40IW_QP_SW_MAX_RQ_QUANTAS 16384 +#define I40IW_MAX_QP_WRS ((I40IW_QP_SW_MAX_SQ_QUANTAS / I40IW_MAX_QUANTAS_PER_WR) - 1) #define I40IWQP_OP_RDMA_WRITE 0 #define I40IWQP_OP_RDMA_READ 1 diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c index 42dde5924bb5..3ec5389a81a1 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_uk.c +++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c @@ -893,9 +893,22 @@ exit: return ret_code; } +/** + * i40iw_qp_roundup - return round up QP WQ depth + * @wqdepth: WQ depth in quantas to round up + */ +static int i40iw_qp_round_up(u32 wqdepth) +{ + int scount = 1; + + for (wqdepth--; scount <= 16; scount *= 2) + wqdepth |= wqdepth >> scount; + + return ++wqdepth; +} + /** * i40iw_get_wqe_shift - get shift count for maximum wqe size - * @wqdepth: depth of wq required. * @sge: Maximum Scatter Gather Elements wqe * @inline_data: Maximum inline data size * @shift: Returns the shift needed based on sge @@ -905,22 +918,48 @@ exit: * For 2 or 3 SGEs or inline data <= 48, shift = 1 (wqe size of 64 bytes). * Shift of 2 otherwise (wqe size of 128 bytes). */ -enum i40iw_status_code i40iw_get_wqe_shift(u32 wqdepth, u32 sge, u32 inline_data, u8 *shift) +void i40iw_get_wqe_shift(u32 sge, u32 inline_data, u8 *shift) { - u32 size; - *shift = 0; if (sge > 1 || inline_data > 16) *shift = (sge < 4 && inline_data <= 48) ? 1 : 2; +} - /* check if wqdepth is multiple of 2 or not */ +/* + * i40iw_get_sqdepth - get SQ depth (quantas) + * @sq_size: SQ size + * @shift: shift which determines size of WQE + * @sqdepth: depth of SQ + * + */ +enum i40iw_status_code i40iw_get_sqdepth(u32 sq_size, u8 shift, u32 *sqdepth) +{ + *sqdepth = i40iw_qp_round_up((sq_size << shift) + I40IW_SQ_RSVD); - if ((wqdepth < I40IWQP_SW_MIN_WQSIZE) || (wqdepth & (wqdepth - 1))) + if (*sqdepth < (I40IW_QP_SW_MIN_WQSIZE << shift)) + *sqdepth = I40IW_QP_SW_MIN_WQSIZE << shift; + else if (*sqdepth > I40IW_QP_SW_MAX_SQ_QUANTAS) return I40IW_ERR_INVALID_SIZE; - size = wqdepth << *shift; /* multiple of 32 bytes count */ - if (size > I40IWQP_SW_MAX_WQSIZE) + return 0; +} + +/* + * i40iw_get_rq_depth - get RQ depth (quantas) + * @rq_size: RQ size + * @shift: shift which determines size of WQE + * @rqdepth: depth of RQ + * + */ +enum i40iw_status_code i40iw_get_rqdepth(u32 rq_size, u8 shift, u32 *rqdepth) +{ + *rqdepth = i40iw_qp_round_up((rq_size << shift) + I40IW_RQ_RSVD); + + if (*rqdepth < (I40IW_QP_SW_MIN_WQSIZE << shift)) + *rqdepth = I40IW_QP_SW_MIN_WQSIZE << shift; + else if (*rqdepth > I40IW_QP_SW_MAX_RQ_QUANTAS) return I40IW_ERR_INVALID_SIZE; + return 0; } @@ -974,9 +1013,7 @@ enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp, if (info->max_rq_frag_cnt > I40IW_MAX_WQ_FRAGMENT_COUNT) return I40IW_ERR_INVALID_FRAG_COUNT; - ret_code = i40iw_get_wqe_shift(info->sq_size, info->max_sq_frag_cnt, info->max_inline_data, &sqshift); - if (ret_code) - return ret_code; + i40iw_get_wqe_shift(info->max_sq_frag_cnt, info->max_inline_data, &sqshift); qp->sq_base = info->sq; qp->rq_base = info->rq; @@ -1010,9 +1047,7 @@ enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp, I40IW_RING_INIT(qp->rq_ring, qp->rq_size); switch (info->abi_ver) { case 4: - ret_code = i40iw_get_wqe_shift(info->rq_size, info->max_rq_frag_cnt, 0, &rqshift); - if (ret_code) - return ret_code; + i40iw_get_wqe_shift(info->max_rq_frag_cnt, 0, &rqshift); break; case 5: /* fallthrough until next ABI version */ default: diff --git a/drivers/infiniband/hw/i40iw/i40iw_user.h b/drivers/infiniband/hw/i40iw/i40iw_user.h index a898f9923a6f..e73efc59a0ab 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_user.h +++ b/drivers/infiniband/hw/i40iw/i40iw_user.h @@ -425,5 +425,7 @@ enum i40iw_status_code i40iw_fragcnt_to_wqesize_sq(u32 frag_cnt, u8 *wqe_size); enum i40iw_status_code i40iw_fragcnt_to_wqesize_rq(u32 frag_cnt, u8 *wqe_size); enum i40iw_status_code i40iw_inline_data_size_to_wqesize(u32 data_size, u8 *wqe_size); -enum i40iw_status_code i40iw_get_wqe_shift(u32 wqdepth, u32 sge, u32 inline_data, u8 *shift); +void i40iw_get_wqe_shift(u32 sge, u32 inline_data, u8 *shift); +enum i40iw_status_code i40iw_get_sqdepth(u32 sq_size, u8 shift, u32 *sqdepth); +enum i40iw_status_code i40iw_get_rqdepth(u32 rq_size, u8 shift, u32 *rqdepth); #endif diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index 5c60de6bd999..3c6f3ce88f89 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -69,7 +69,7 @@ static int i40iw_query_device(struct ib_device *ibdev, props->hw_ver = (u32)iwdev->sc_dev.hw_rev; props->max_mr_size = I40IW_MAX_OUTBOUND_MESSAGE_SIZE; props->max_qp = iwdev->max_qp - iwdev->used_qps; - props->max_qp_wr = (I40IW_MAX_WQ_ENTRIES >> 2) - 1; + props->max_qp_wr = I40IW_MAX_QP_WRS; props->max_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; props->max_cq = iwdev->max_cq - iwdev->used_cqs; props->max_cqe = iwdev->max_cqe; @@ -380,22 +380,6 @@ static int i40iw_dealloc_pd(struct ib_pd *ibpd) return 0; } -/** - * i40iw_qp_roundup - return round up qp ring size - * @wr_ring_size: ring size to round up - */ -static int i40iw_qp_roundup(u32 wr_ring_size) -{ - int scount = 1; - - if (wr_ring_size < I40IWQP_SW_MIN_WQSIZE) - wr_ring_size = I40IWQP_SW_MIN_WQSIZE; - - for (wr_ring_size--; scount <= 16; scount *= 2) - wr_ring_size |= wr_ring_size >> scount; - return ++wr_ring_size; -} - /** * i40iw_get_pbl - Retrieve pbl from a list given a virtual * address @@ -515,21 +499,19 @@ static int i40iw_setup_kmode_qp(struct i40iw_device *iwdev, { struct i40iw_dma_mem *mem = &iwqp->kqp.dma_mem; u32 sqdepth, rqdepth; - u32 sq_size, rq_size; u8 sqshift; u32 size; enum i40iw_status_code status; struct i40iw_qp_uk_init_info *ukinfo = &info->qp_uk_init_info; - sq_size = i40iw_qp_roundup(ukinfo->sq_size + 1); - rq_size = i40iw_qp_roundup(ukinfo->rq_size + 1); - - status = i40iw_get_wqe_shift(sq_size, ukinfo->max_sq_frag_cnt, ukinfo->max_inline_data, &sqshift); + i40iw_get_wqe_shift(ukinfo->max_sq_frag_cnt, ukinfo->max_inline_data, &sqshift); + status = i40iw_get_sqdepth(ukinfo->sq_size, sqshift, &sqdepth); if (status) return -ENOMEM; - sqdepth = sq_size << sqshift; - rqdepth = rq_size << I40IW_MAX_RQ_WQE_SHIFT; + status = i40iw_get_rqdepth(ukinfo->rq_size, I40IW_MAX_RQ_WQE_SHIFT, &rqdepth); + if (status) + return -ENOMEM; size = sqdepth * sizeof(struct i40iw_sq_uk_wr_trk_info) + (rqdepth << 3); iwqp->kqp.wrid_mem = kzalloc(size, GFP_KERNEL); @@ -559,8 +541,8 @@ static int i40iw_setup_kmode_qp(struct i40iw_device *iwdev, ukinfo->shadow_area = ukinfo->rq[rqdepth].elem; info->shadow_area_pa = info->rq_pa + (rqdepth * I40IW_QP_WQE_MIN_SIZE); - ukinfo->sq_size = sq_size; - ukinfo->rq_size = rq_size; + ukinfo->sq_size = sqdepth >> sqshift; + ukinfo->rq_size = rqdepth >> I40IW_MAX_RQ_WQE_SHIFT; ukinfo->qp_id = iwqp->ibqp.qp_num; return 0; } -- cgit v1.2.3-59-g8ed1b From 56b2f52310f9fdfc1ea7b99702f827f84ad16801 Mon Sep 17 00:00:00 2001 From: Christopher Bednarz Date: Mon, 16 Oct 2017 15:46:03 -0500 Subject: i40iw: Clear CQP Head/Tail during initialization Clear Control Queue Pair (CQP) Head/Tail on CQP initialization as during an adapter reset, these values are not reinitialized. Tail is cleared by writing 0 to CQP's tail register. Head is cleared by writing 0 to CQP's doorbell register. Fixes: 86dbcd0f12e9 ("i40iw: add file to handle cqp calls") Signed-off-by: Christopher Bednarz Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index 3b6d12176413..e5c8f579e67b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -483,6 +483,9 @@ static enum i40iw_status_code i40iw_sc_cqp_init(struct i40iw_sc_cqp *cqp, cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] = 0; cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS] = 0; + i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPTAIL, 0); + i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPDB, 0); + i40iw_debug(cqp->dev, I40IW_DEBUG_WQE, "%s: sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%llxh] cqp[%p] polarity[x%04X]\n", __func__, cqp->sq_size, cqp->hw_sq_size, -- cgit v1.2.3-59-g8ed1b From f535b56c39c81ba75c714b9163be540d39d3badd Mon Sep 17 00:00:00 2001 From: Ivan Barrera Date: Mon, 16 Oct 2017 15:46:04 -0500 Subject: i40iw: Remove UDA QP from QoS list if creation fails If User-space Direct Access (UDA) QP creation fails, the QP entry is not removed from QoS list. Fix this by removing QP from QoS list if create QP fails. Fixes: 0fc2dc58896f ("i40iw: Add Quality of Service support") Signed-off-by: Ivan Barrera Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 +- drivers/infiniband/hw/i40iw/i40iw_p.h | 2 +- drivers/infiniband/hw/i40iw/i40iw_puda.c | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index e5c8f579e67b..c8a40b3fbc31 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -377,7 +377,7 @@ void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2pa * i40iw_qp_rem_qos - remove qp from qos lists during destroy qp * @qp: qp to be removed from qos */ -static void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp) +void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp) { struct i40iw_sc_vsi *vsi = qp->vsi; unsigned long flags; diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h index 2ad5a8ebee7e..11d3a2a72100 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_p.h +++ b/drivers/infiniband/hw/i40iw/i40iw_p.h @@ -86,7 +86,7 @@ void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *inf void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2params); void i40iw_qp_add_qos(struct i40iw_sc_qp *qp); - +void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp); void i40iw_terminate_send_fin(struct i40iw_sc_qp *qp); void i40iw_terminate_connection(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *info); diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index 19ced8bd64c0..796a815b53fd 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -615,8 +615,10 @@ static enum i40iw_status_code i40iw_puda_qp_create(struct i40iw_puda_rsrc *rsrc) ret = i40iw_cqp_qp_create_cmd(rsrc->dev, qp); else ret = i40iw_puda_qp_wqe(rsrc->dev, qp); - if (ret) + if (ret) { + i40iw_qp_rem_qos(qp); i40iw_free_dma_mem(rsrc->dev->hw, &rsrc->qpmem); + } return ret; } -- cgit v1.2.3-59-g8ed1b From d2782739c1498e4425dcdeb79f90f9291e58f6f6 Mon Sep 17 00:00:00 2001 From: Bob Sharp Date: Mon, 16 Oct 2017 15:46:05 -0500 Subject: i40iw: Move cqp_cmd_head init to CQP initialization Control QP (CQP) command backlog list is initialized at device initialization time. It is not reinitialized in the reset flow. Move the initialization to CQP creation time so the list can be initialized correctly for reset as well. Fixes: 86dbcd0f12e9 ("i40iw: add file to handle cqp calls") Signed-off-by: Bob Sharp Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/infiniband/hw/i40iw') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index c8a40b3fbc31..d88c6cf47cf2 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -482,6 +482,7 @@ static enum i40iw_status_code i40iw_sc_cqp_init(struct i40iw_sc_cqp *cqp, I40IW_RING_INIT(cqp->sq_ring, cqp->sq_size); cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] = 0; cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS] = 0; + INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head); /* for the cqp commands backlog. */ i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPTAIL, 0); i40iw_wr32(cqp->dev->hw, I40E_PFPE_CQPDB, 0); @@ -5067,7 +5068,6 @@ enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev, u8 db_size; spin_lock_init(&dev->cqp_lock); - INIT_LIST_HEAD(&dev->cqp_cmd_head); /* for the cqp commands backlog. */ i40iw_device_init_uk(&dev->dev_uk); -- cgit v1.2.3-59-g8ed1b