aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c59
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index 4bc794249801..da7da752b6b4 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -357,22 +357,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
357 */ 357 */
358int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, 358int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
359 union ixgbe_adv_rx_desc *rx_desc, 359 union ixgbe_adv_rx_desc *rx_desc,
360 struct sk_buff *skb, 360 struct sk_buff *skb)
361 u32 staterr)
362{ 361{
363 u16 xid;
364 u32 fctl;
365 u32 fceofe, fcerr, fcstat;
366 int rc = -EINVAL; 362 int rc = -EINVAL;
367 struct ixgbe_fcoe *fcoe; 363 struct ixgbe_fcoe *fcoe;
368 struct ixgbe_fcoe_ddp *ddp; 364 struct ixgbe_fcoe_ddp *ddp;
369 struct fc_frame_header *fh; 365 struct fc_frame_header *fh;
370 struct fcoe_crc_eof *crc; 366 struct fcoe_crc_eof *crc;
367 __le32 fcerr = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCERR);
368 __le32 ddp_err;
369 u32 fctl;
370 u16 xid;
371 371
372 fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR); 372 if (fcerr == cpu_to_le32(IXGBE_FCERR_BADCRC))
373 fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE); 373 skb->ip_summed = CHECKSUM_NONE;
374 if (fcerr == IXGBE_FCERR_BADCRC)
375 skb_checksum_none_assert(skb);
376 else 374 else
377 skb->ip_summed = CHECKSUM_UNNECESSARY; 375 skb->ip_summed = CHECKSUM_UNNECESSARY;
378 376
@@ -382,6 +380,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
382 else 380 else
383 fh = (struct fc_frame_header *)(skb->data + 381 fh = (struct fc_frame_header *)(skb->data +
384 sizeof(struct fcoe_hdr)); 382 sizeof(struct fcoe_hdr));
383
385 fctl = ntoh24(fh->fh_f_ctl); 384 fctl = ntoh24(fh->fh_f_ctl);
386 if (fctl & FC_FC_EX_CTX) 385 if (fctl & FC_FC_EX_CTX)
387 xid = be16_to_cpu(fh->fh_ox_id); 386 xid = be16_to_cpu(fh->fh_ox_id);
@@ -396,27 +395,39 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
396 if (!ddp->udl) 395 if (!ddp->udl)
397 goto ddp_out; 396 goto ddp_out;
398 397
399 if (fcerr | fceofe) 398 ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE |
399 IXGBE_RXDADV_ERR_FCERR);
400 if (ddp_err)
400 goto ddp_out; 401 goto ddp_out;
401 402
402 fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT); 403 switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) {
403 if (fcstat) { 404 /* return 0 to bypass going to ULD for DDPed data */
405 case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_DDP):
404 /* update length of DDPed data */ 406 /* update length of DDPed data */
405 ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); 407 ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
406 /* unmap the sg list when FCP_RSP is received */ 408 rc = 0;
407 if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) { 409 break;
408 pci_unmap_sg(adapter->pdev, ddp->sgl, 410 /* unmap the sg list when FCPRSP is received */
409 ddp->sgc, DMA_FROM_DEVICE); 411 case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_FCPRSP):
410 ddp->err = (fcerr | fceofe); 412 pci_unmap_sg(adapter->pdev, ddp->sgl,
411 ddp->sgl = NULL; 413 ddp->sgc, DMA_FROM_DEVICE);
412 ddp->sgc = 0; 414 ddp->err = ddp_err;
413 } 415 ddp->sgl = NULL;
414 /* return 0 to bypass going to ULD for DDPed data */ 416 ddp->sgc = 0;
415 if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) 417 /* fall through */
416 rc = 0; 418 /* if DDP length is present pass it through to ULD */
417 else if (ddp->len) 419 case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP):
420 /* update length of DDPed data */
421 ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
422 if (ddp->len)
418 rc = ddp->len; 423 rc = ddp->len;
424 break;
425 /* no match will return as an error */
426 case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NOMTCH):
427 default:
428 break;
419 } 429 }
430
420 /* In target mode, check the last data frame of the sequence. 431 /* In target mode, check the last data frame of the sequence.
421 * For DDP in target mode, data is already DDPed but the header 432 * For DDP in target mode, data is already DDPed but the header
422 * indication of the last data frame ould allow is to tell if we 433 * indication of the last data frame ould allow is to tell if we