aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes/nes_mgt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_mgt.c')
-rw-r--r--drivers/infiniband/hw/nes/nes_mgt.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
index 3ba7be369452..416645259b0f 100644
--- a/drivers/infiniband/hw/nes/nes_mgt.c
+++ b/drivers/infiniband/hw/nes/nes_mgt.c
@@ -210,6 +210,9 @@ static struct sk_buff *nes_get_next_skb(struct nes_device *nesdev, struct nes_qp
210 } 210 }
211 211
212 while (1) { 212 while (1) {
213 if (skb_queue_empty(&nesqp->pau_list))
214 goto out;
215
213 seq = nes_get_seq(skb, ack, wnd, fin_rcvd, rst_rcvd); 216 seq = nes_get_seq(skb, ack, wnd, fin_rcvd, rst_rcvd);
214 if (seq == nextseq) { 217 if (seq == nextseq) {
215 if (skb->len || processacks) 218 if (skb->len || processacks)
@@ -218,14 +221,13 @@ static struct sk_buff *nes_get_next_skb(struct nes_device *nesdev, struct nes_qp
218 goto out; 221 goto out;
219 } 222 }
220 223
221 if (skb->next == (struct sk_buff *)&nesqp->pau_list)
222 goto out;
223
224 old_skb = skb; 224 old_skb = skb;
225 skb = skb->next; 225 skb = skb->next;
226 skb_unlink(old_skb, &nesqp->pau_list); 226 skb_unlink(old_skb, &nesqp->pau_list);
227 nes_mgt_free_skb(nesdev, old_skb, PCI_DMA_TODEVICE); 227 nes_mgt_free_skb(nesdev, old_skb, PCI_DMA_TODEVICE);
228 nes_rem_ref_cm_node(nesqp->cm_node); 228 nes_rem_ref_cm_node(nesqp->cm_node);
229 if (skb == (struct sk_buff *)&nesqp->pau_list)
230 goto out;
229 } 231 }
230 return skb; 232 return skb;
231 233
@@ -245,7 +247,6 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
245 struct nes_rskb_cb *cb; 247 struct nes_rskb_cb *cb;
246 struct pau_fpdu_info *fpdu_info = NULL; 248 struct pau_fpdu_info *fpdu_info = NULL;
247 struct pau_fpdu_frag frags[MAX_FPDU_FRAGS]; 249 struct pau_fpdu_frag frags[MAX_FPDU_FRAGS];
248 unsigned long flags;
249 u32 fpdu_len = 0; 250 u32 fpdu_len = 0;
250 u32 tmp_len; 251 u32 tmp_len;
251 int frag_cnt = 0; 252 int frag_cnt = 0;
@@ -260,12 +261,10 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
260 261
261 *pau_fpdu_info = NULL; 262 *pau_fpdu_info = NULL;
262 263
263 spin_lock_irqsave(&nesqp->pau_lock, flags);
264 skb = nes_get_next_skb(nesdev, nesqp, NULL, nesqp->pau_rcv_nxt, &ack, &wnd, &fin_rcvd, &rst_rcvd); 264 skb = nes_get_next_skb(nesdev, nesqp, NULL, nesqp->pau_rcv_nxt, &ack, &wnd, &fin_rcvd, &rst_rcvd);
265 if (!skb) { 265 if (!skb)
266 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
267 goto out; 266 goto out;
268 } 267
269 cb = (struct nes_rskb_cb *)&skb->cb[0]; 268 cb = (struct nes_rskb_cb *)&skb->cb[0];
270 if (skb->len) { 269 if (skb->len) {
271 fpdu_len = be16_to_cpu(*(__be16 *) skb->data) + MPA_FRAMING; 270 fpdu_len = be16_to_cpu(*(__be16 *) skb->data) + MPA_FRAMING;
@@ -290,10 +289,9 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
290 289
291 skb = nes_get_next_skb(nesdev, nesqp, skb, 290 skb = nes_get_next_skb(nesdev, nesqp, skb,
292 nesqp->pau_rcv_nxt + frag_tot, &ack, &wnd, &fin_rcvd, &rst_rcvd); 291 nesqp->pau_rcv_nxt + frag_tot, &ack, &wnd, &fin_rcvd, &rst_rcvd);
293 if (!skb) { 292 if (!skb)
294 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
295 goto out; 293 goto out;
296 } else if (rst_rcvd) { 294 if (rst_rcvd) {
297 /* rst received in the middle of fpdu */ 295 /* rst received in the middle of fpdu */
298 for (; i >= 0; i--) { 296 for (; i >= 0; i--) {
299 skb_unlink(frags[i].skb, &nesqp->pau_list); 297 skb_unlink(frags[i].skb, &nesqp->pau_list);
@@ -320,8 +318,6 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
320 frag_cnt = 1; 318 frag_cnt = 1;
321 } 319 }
322 320
323 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
324
325 /* Found one */ 321 /* Found one */
326 fpdu_info = kzalloc(sizeof(*fpdu_info), GFP_ATOMIC); 322 fpdu_info = kzalloc(sizeof(*fpdu_info), GFP_ATOMIC);
327 if (fpdu_info == NULL) { 323 if (fpdu_info == NULL) {
@@ -383,9 +379,8 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
383 379
384 if (frags[i].skb->len == 0) { 380 if (frags[i].skb->len == 0) {
385 /* Pull skb off the list - it will be freed in the callback */ 381 /* Pull skb off the list - it will be freed in the callback */
386 spin_lock_irqsave(&nesqp->pau_lock, flags); 382 if (!skb_queue_empty(&nesqp->pau_list))
387 skb_unlink(frags[i].skb, &nesqp->pau_list); 383 skb_unlink(frags[i].skb, &nesqp->pau_list);
388 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
389 } else { 384 } else {
390 /* Last skb still has data so update the seq */ 385 /* Last skb still has data so update the seq */
391 iph = (struct iphdr *)(cb->data_start + ETH_HLEN); 386 iph = (struct iphdr *)(cb->data_start + ETH_HLEN);
@@ -414,14 +409,18 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
414 struct pau_fpdu_info *fpdu_info; 409 struct pau_fpdu_info *fpdu_info;
415 struct nes_hw_cqp_wqe *cqp_wqe; 410 struct nes_hw_cqp_wqe *cqp_wqe;
416 struct nes_cqp_request *cqp_request; 411 struct nes_cqp_request *cqp_request;
412 unsigned long flags;
417 u64 u64tmp; 413 u64 u64tmp;
418 u32 u32tmp; 414 u32 u32tmp;
419 int rc; 415 int rc;
420 416
421 while (1) { 417 while (1) {
418 spin_lock_irqsave(&nesqp->pau_lock, flags);
422 rc = get_fpdu_info(nesdev, nesqp, &fpdu_info); 419 rc = get_fpdu_info(nesdev, nesqp, &fpdu_info);
423 if (fpdu_info == NULL) 420 if (rc || (fpdu_info == NULL)) {
421 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
424 return rc; 422 return rc;
423 }
425 424
426 cqp_request = fpdu_info->cqp_request; 425 cqp_request = fpdu_info->cqp_request;
427 cqp_wqe = &cqp_request->cqp_wqe; 426 cqp_wqe = &cqp_request->cqp_wqe;
@@ -447,7 +446,7 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
447 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX, 446 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX,
448 lower_32_bits(u64tmp)); 447 lower_32_bits(u64tmp));
449 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_HIGH_IDX, 448 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_HIGH_IDX,
450 upper_32_bits(u64tmp >> 32)); 449 upper_32_bits(u64tmp));
451 450
452 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX, 451 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX,
453 lower_32_bits(fpdu_info->frags[0].physaddr)); 452 lower_32_bits(fpdu_info->frags[0].physaddr));
@@ -475,6 +474,7 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
475 474
476 atomic_set(&cqp_request->refcount, 1); 475 atomic_set(&cqp_request->refcount, 1);
477 nes_post_cqp_request(nesdev, cqp_request); 476 nes_post_cqp_request(nesdev, cqp_request);
477 spin_unlock_irqrestore(&nesqp->pau_lock, flags);
478 } 478 }
479 479
480 return 0; 480 return 0;
@@ -649,11 +649,9 @@ static void nes_chg_qh_handler(struct nes_device *nesdev, struct nes_cqp_request
649 nesqp = qh_chg->nesqp; 649 nesqp = qh_chg->nesqp;
650 650
651 /* Should we handle the bad completion */ 651 /* Should we handle the bad completion */
652 if (cqp_request->major_code) { 652 if (cqp_request->major_code)
653 printk(KERN_ERR PFX "Invalid cqp_request major_code=0x%x\n", 653 WARN(1, PFX "Invalid cqp_request major_code=0x%x\n",
654 cqp_request->major_code); 654 cqp_request->major_code);
655 WARN_ON(1);
656 }
657 655
658 switch (nesqp->pau_state) { 656 switch (nesqp->pau_state) {
659 case PAU_DEL_QH: 657 case PAU_DEL_QH: