diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 59 |
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 | */ |
358 | int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, | 358 | int 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 |