|
@@ -247,7 +247,6 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
|
|
|
struct nes_rskb_cb *cb;
|
|
|
struct pau_fpdu_info *fpdu_info = NULL;
|
|
|
struct pau_fpdu_frag frags[MAX_FPDU_FRAGS];
|
|
|
- unsigned long flags;
|
|
|
u32 fpdu_len = 0;
|
|
|
u32 tmp_len;
|
|
|
int frag_cnt = 0;
|
|
@@ -262,12 +261,10 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
|
|
|
|
|
|
*pau_fpdu_info = NULL;
|
|
|
|
|
|
- spin_lock_irqsave(&nesqp->pau_lock, flags);
|
|
|
skb = nes_get_next_skb(nesdev, nesqp, NULL, nesqp->pau_rcv_nxt, &ack, &wnd, &fin_rcvd, &rst_rcvd);
|
|
|
- if (!skb) {
|
|
|
- spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
+ if (!skb)
|
|
|
goto out;
|
|
|
- }
|
|
|
+
|
|
|
cb = (struct nes_rskb_cb *)&skb->cb[0];
|
|
|
if (skb->len) {
|
|
|
fpdu_len = be16_to_cpu(*(__be16 *) skb->data) + MPA_FRAMING;
|
|
@@ -292,10 +289,9 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
|
|
|
|
|
|
skb = nes_get_next_skb(nesdev, nesqp, skb,
|
|
|
nesqp->pau_rcv_nxt + frag_tot, &ack, &wnd, &fin_rcvd, &rst_rcvd);
|
|
|
- if (!skb) {
|
|
|
- spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
+ if (!skb)
|
|
|
goto out;
|
|
|
- } else if (rst_rcvd) {
|
|
|
+ if (rst_rcvd) {
|
|
|
/* rst received in the middle of fpdu */
|
|
|
for (; i >= 0; i--) {
|
|
|
skb_unlink(frags[i].skb, &nesqp->pau_list);
|
|
@@ -322,8 +318,6 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
|
|
|
frag_cnt = 1;
|
|
|
}
|
|
|
|
|
|
- spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
-
|
|
|
/* Found one */
|
|
|
fpdu_info = kzalloc(sizeof(*fpdu_info), GFP_ATOMIC);
|
|
|
if (fpdu_info == NULL) {
|
|
@@ -385,10 +379,8 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
|
|
|
|
|
|
if (frags[i].skb->len == 0) {
|
|
|
/* Pull skb off the list - it will be freed in the callback */
|
|
|
- spin_lock_irqsave(&nesqp->pau_lock, flags);
|
|
|
if (!skb_queue_empty(&nesqp->pau_list))
|
|
|
skb_unlink(frags[i].skb, &nesqp->pau_list);
|
|
|
- spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
} else {
|
|
|
/* Last skb still has data so update the seq */
|
|
|
iph = (struct iphdr *)(cb->data_start + ETH_HLEN);
|
|
@@ -417,14 +409,18 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
|
|
|
struct pau_fpdu_info *fpdu_info;
|
|
|
struct nes_hw_cqp_wqe *cqp_wqe;
|
|
|
struct nes_cqp_request *cqp_request;
|
|
|
+ unsigned long flags;
|
|
|
u64 u64tmp;
|
|
|
u32 u32tmp;
|
|
|
int rc;
|
|
|
|
|
|
while (1) {
|
|
|
+ spin_lock_irqsave(&nesqp->pau_lock, flags);
|
|
|
rc = get_fpdu_info(nesdev, nesqp, &fpdu_info);
|
|
|
- if (fpdu_info == NULL)
|
|
|
+ if (rc || (fpdu_info == NULL)) {
|
|
|
+ spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
return rc;
|
|
|
+ }
|
|
|
|
|
|
cqp_request = fpdu_info->cqp_request;
|
|
|
cqp_wqe = &cqp_request->cqp_wqe;
|
|
@@ -478,6 +474,7 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
|
|
|
|
|
|
atomic_set(&cqp_request->refcount, 1);
|
|
|
nes_post_cqp_request(nesdev, cqp_request);
|
|
|
+ spin_unlock_irqrestore(&nesqp->pau_lock, flags);
|
|
|
}
|
|
|
|
|
|
return 0;
|