aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_fcoe.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2011-05-27 01:31:47 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-06-25 03:06:05 -0400
commit897ab15606ce896b6a574a263beb51cbfb43f041 (patch)
treea269fefc4423c239eeb411c76c6bd9dd25ac09db /drivers/net/ixgbe/ixgbe_fcoe.c
parent63544e9c0055316d0397cb671f2ff99d85c77293 (diff)
ixgbe: Add one function that handles most of context descriptor setup
There is a significant amount of shared functionality between the checksum and TSO offload configuration that is shared in regards to how they setup the context descriptors. Since so much of the functionality is shared it makes sense to move the shared functionality into a single function and just call that function from the two context descriptor specific routines. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_fcoe.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c85
1 files changed, 31 insertions, 54 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index f5f39edb86a..9c20077dd44 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -474,24 +474,18 @@ ddp_out:
474 * 474 *
475 * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error 475 * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error
476 */ 476 */
477int ixgbe_fso(struct ixgbe_adapter *adapter, 477int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb,
478 struct ixgbe_ring *tx_ring, struct sk_buff *skb,
479 u32 tx_flags, u8 *hdr_len) 478 u32 tx_flags, u8 *hdr_len)
480{ 479{
481 u8 sof, eof; 480 struct fc_frame_header *fh;
482 u32 vlan_macip_lens; 481 u32 vlan_macip_lens;
483 u32 fcoe_sof_eof; 482 u32 fcoe_sof_eof = 0;
484 u32 type_tucmd;
485 u32 mss_l4len_idx; 483 u32 mss_l4len_idx;
486 int mss = 0; 484 u8 sof, eof;
487 unsigned int i;
488 struct ixgbe_tx_buffer *tx_buffer_info;
489 struct ixgbe_adv_tx_context_desc *context_desc;
490 struct fc_frame_header *fh;
491 485
492 if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) { 486 if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {
493 e_err(drv, "Wrong gso type %d:expecting SKB_GSO_FCOE\n", 487 dev_err(tx_ring->dev, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",
494 skb_shinfo(skb)->gso_type); 488 skb_shinfo(skb)->gso_type);
495 return -EINVAL; 489 return -EINVAL;
496 } 490 }
497 491
@@ -501,23 +495,22 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
501 sizeof(struct fcoe_hdr)); 495 sizeof(struct fcoe_hdr));
502 496
503 /* sets up SOF and ORIS */ 497 /* sets up SOF and ORIS */
504 fcoe_sof_eof = 0;
505 sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof; 498 sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
506 switch (sof) { 499 switch (sof) {
507 case FC_SOF_I2: 500 case FC_SOF_I2:
508 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS; 501 fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_ORIS;
509 break; 502 break;
510 case FC_SOF_I3: 503 case FC_SOF_I3:
511 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF; 504 fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF |
512 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS; 505 IXGBE_ADVTXD_FCOEF_ORIS;
513 break; 506 break;
514 case FC_SOF_N2: 507 case FC_SOF_N2:
515 break; 508 break;
516 case FC_SOF_N3: 509 case FC_SOF_N3:
517 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF; 510 fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF;
518 break; 511 break;
519 default: 512 default:
520 e_warn(drv, "unknown sof = 0x%x\n", sof); 513 dev_warn(tx_ring->dev, "unknown sof = 0x%x\n", sof);
521 return -EINVAL; 514 return -EINVAL;
522 } 515 }
523 516
@@ -530,12 +523,11 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
530 break; 523 break;
531 case FC_EOF_T: 524 case FC_EOF_T:
532 /* lso needs ORIE */ 525 /* lso needs ORIE */
533 if (skb_is_gso(skb)) { 526 if (skb_is_gso(skb))
534 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N; 527 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N |
535 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIE; 528 IXGBE_ADVTXD_FCOEF_ORIE;
536 } else { 529 else
537 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T; 530 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T;
538 }
539 break; 531 break;
540 case FC_EOF_NI: 532 case FC_EOF_NI:
541 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI; 533 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI;
@@ -544,7 +536,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
544 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A; 536 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A;
545 break; 537 break;
546 default: 538 default:
547 e_warn(drv, "unknown eof = 0x%x\n", eof); 539 dev_warn(tx_ring->dev, "unknown eof = 0x%x\n", eof);
548 return -EINVAL; 540 return -EINVAL;
549 } 541 }
550 542
@@ -553,43 +545,28 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
553 if (fh->fh_f_ctl[2] & FC_FC_REL_OFF) 545 if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
554 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC; 546 fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC;
555 547
556 /* hdr_len includes fc_hdr if FCoE lso is enabled */ 548 /* include trailer in headlen as it is replicated per frame */
557 *hdr_len = sizeof(struct fcoe_crc_eof); 549 *hdr_len = sizeof(struct fcoe_crc_eof);
550
551 /* hdr_len includes fc_hdr if FCoE LSO is enabled */
558 if (skb_is_gso(skb)) 552 if (skb_is_gso(skb))
559 *hdr_len += (skb_transport_offset(skb) + 553 *hdr_len += (skb_transport_offset(skb) +
560 sizeof(struct fc_frame_header)); 554 sizeof(struct fc_frame_header));
561 /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ 555
562 vlan_macip_lens = (skb_transport_offset(skb) +
563 sizeof(struct fc_frame_header));
564 vlan_macip_lens |= ((skb_transport_offset(skb) - 4)
565 << IXGBE_ADVTXD_MACLEN_SHIFT);
566 vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
567
568 /* type_tycmd and mss: set TUCMD.FCoE to enable offload */
569 type_tucmd = IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT |
570 IXGBE_ADVTXT_TUCMD_FCOE;
571 if (skb_is_gso(skb))
572 mss = skb_shinfo(skb)->gso_size;
573 /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */ 556 /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */
574 mss_l4len_idx = (mss << IXGBE_ADVTXD_MSS_SHIFT) | 557 mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;
575 (1 << IXGBE_ADVTXD_IDX_SHIFT); 558 mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT;
559
560 /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
561 vlan_macip_lens = skb_transport_offset(skb) +
562 sizeof(struct fc_frame_header);
563 vlan_macip_lens |= (skb_transport_offset(skb) - 4)
564 << IXGBE_ADVTXD_MACLEN_SHIFT;
565 vlan_macip_lens |= tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
576 566
577 /* write context desc */ 567 /* write context desc */
578 i = tx_ring->next_to_use; 568 ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof,
579 context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); 569 IXGBE_ADVTXT_TUCMD_FCOE, mss_l4len_idx);
580 context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
581 context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof);
582 context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
583 context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
584
585 tx_buffer_info = &tx_ring->tx_buffer_info[i];
586 tx_buffer_info->time_stamp = jiffies;
587 tx_buffer_info->next_to_watch = i;
588
589 i++;
590 if (i == tx_ring->count)
591 i = 0;
592 tx_ring->next_to_use = i;
593 570
594 return skb_is_gso(skb); 571 return skb_is_gso(skb);
595} 572}