lpfc: Fix external loopback failure.

Fix external loopback failure.

Rx sequence reassembly was incorrect.

Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com>
Signed-off-by: James Smart <james.smart@avagotech.com>
Reviewed-by: Hannes Reinicke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
James Smart 2015-12-16 18:12:04 -05:00 committed by Martin K. Petersen
parent 01c73bbcd7
commit 4360ca9c24

View File

@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf)
struct lpfc_dmabuf *h_buf; struct lpfc_dmabuf *h_buf;
struct hbq_dmabuf *seq_dmabuf = NULL; struct hbq_dmabuf *seq_dmabuf = NULL;
struct hbq_dmabuf *temp_dmabuf = NULL; struct hbq_dmabuf *temp_dmabuf = NULL;
uint8_t found = 0;
INIT_LIST_HEAD(&dmabuf->dbuf.list); INIT_LIST_HEAD(&dmabuf->dbuf.list);
dmabuf->time_stamp = jiffies; dmabuf->time_stamp = jiffies;
new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
/* Use the hdr_buf to find the sequence that this frame belongs to */ /* Use the hdr_buf to find the sequence that this frame belongs to */
list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
temp_hdr = (struct fc_frame_header *)h_buf->virt; temp_hdr = (struct fc_frame_header *)h_buf->virt;
@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf)
return seq_dmabuf; return seq_dmabuf;
} }
/* find the correct place in the sequence to insert this frame */ /* find the correct place in the sequence to insert this frame */
list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list);
while (!found) {
temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt;
/* /*
@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf)
if (be16_to_cpu(new_hdr->fh_seq_cnt) > if (be16_to_cpu(new_hdr->fh_seq_cnt) >
be16_to_cpu(temp_hdr->fh_seq_cnt)) { be16_to_cpu(temp_hdr->fh_seq_cnt)) {
list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list);
return seq_dmabuf; found = 1;
break;
} }
if (&d_buf->list == &seq_dmabuf->dbuf.list)
break;
d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list);
} }
if (found)
return seq_dmabuf;
return NULL; return NULL;
} }