aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2009-05-13 09:11:06 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-17 15:00:04 -0400
commiteacd73f79a106c6a0bc429003ab691024860ab2d (patch)
treeb788d0e9599b508a71ca2c5eb6bc2cee4a66ab29
parentbc079228e74d63742255c466d2bce1f42423f219 (diff)
ixgbe: Implement FCoE Tx side offload features in base driver of 82599
This patch implements the FCoE Tx side offload features in ixgbe_main.c to 82599 using the Tx offload infrastructure code added in the previous patch. This is achieved by the calling the FCoE Sequence Offload (FSO) function ixgbe_fso() on the transmit path of ixgbe. This patch also includes an EEPROM check to make sure the NIC we're loading on is an offload-enabled SKU. Signed-off-by: Yi Zou <yi.zou@intel.com> Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ixgbe/Makefile2
-rw-r--r--drivers/net/ixgbe/ixgbe.h13
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c1
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c104
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h1
5 files changed, 101 insertions, 20 deletions
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index b3f8208ec7be..21b41f42b61c 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -37,3 +37,5 @@ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
37 37
38ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ 38ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
39 ixgbe_dcb_82599.o ixgbe_dcb_nl.o 39 ixgbe_dcb_82599.o ixgbe_dcb_nl.o
40
41ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index d743d0ed5c2e..06859f687f19 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -36,6 +36,10 @@
36#include "ixgbe_type.h" 36#include "ixgbe_type.h"
37#include "ixgbe_common.h" 37#include "ixgbe_common.h"
38#include "ixgbe_dcb.h" 38#include "ixgbe_dcb.h"
39#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
40#define IXGBE_FCOE
41#include "ixgbe_fcoe.h"
42#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
39#ifdef CONFIG_IXGBE_DCA 43#ifdef CONFIG_IXGBE_DCA
40#include <linux/dca.h> 44#include <linux/dca.h>
41#endif 45#endif
@@ -84,6 +88,8 @@
84#define IXGBE_TX_FLAGS_VLAN (u32)(1 << 1) 88#define IXGBE_TX_FLAGS_VLAN (u32)(1 << 1)
85#define IXGBE_TX_FLAGS_TSO (u32)(1 << 2) 89#define IXGBE_TX_FLAGS_TSO (u32)(1 << 2)
86#define IXGBE_TX_FLAGS_IPV4 (u32)(1 << 3) 90#define IXGBE_TX_FLAGS_IPV4 (u32)(1 << 3)
91#define IXGBE_TX_FLAGS_FCOE (u32)(1 << 4)
92#define IXGBE_TX_FLAGS_FSO (u32)(1 << 5)
87#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 93#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
88#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 94#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
89#define IXGBE_TX_FLAGS_VLAN_SHIFT 16 95#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
@@ -298,6 +304,7 @@ struct ixgbe_adapter {
298#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) 304#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25)
299#define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 26) 305#define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 26)
300#define IXGBE_FLAG_RSC_ENABLED (u32)(1 << 27) 306#define IXGBE_FLAG_RSC_ENABLED (u32)(1 << 27)
307#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29)
301 308
302/* default to trying for four seconds */ 309/* default to trying for four seconds */
303#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) 310#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -371,5 +378,11 @@ extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
371extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); 378extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
372extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); 379extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
373extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32); 380extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
381#ifdef IXGBE_FCOE
382extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
383extern int ixgbe_fso(struct ixgbe_adapter *adapter,
384 struct ixgbe_ring *tx_ring, struct sk_buff *skb,
385 u32 tx_flags, u8 *hdr_len);
386#endif /* IXGBE_FCOE */
374 387
375#endif /* _IXGBE_H_ */ 388#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 6038ed14c9f9..23be4dbac7ed 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -1294,7 +1294,6 @@ s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
1294 return 0; 1294 return 0;
1295} 1295}
1296 1296
1297
1298static struct ixgbe_mac_operations mac_ops_82599 = { 1297static struct ixgbe_mac_operations mac_ops_82599 = {
1299 .init_hw = &ixgbe_init_hw_generic, 1298 .init_hw = &ixgbe_init_hw_generic,
1300 .reset_hw = &ixgbe_reset_hw_82599, 1299 .reset_hw = &ixgbe_reset_hw_82599,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index efb175b1e438..ee80f6f45015 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -39,6 +39,7 @@
39#include <net/ip6_checksum.h> 39#include <net/ip6_checksum.h>
40#include <linux/ethtool.h> 40#include <linux/ethtool.h>
41#include <linux/if_vlan.h> 41#include <linux/if_vlan.h>
42#include <scsi/fc/fc_fcoe.h>
42 43
43#include "ixgbe.h" 44#include "ixgbe.h"
44#include "ixgbe_common.h" 45#include "ixgbe_common.h"
@@ -1810,6 +1811,11 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
1810 /* Decide whether to use packet split mode or not */ 1811 /* Decide whether to use packet split mode or not */
1811 adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; 1812 adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
1812 1813
1814#ifdef IXGBE_FCOE
1815 if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
1816 adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
1817#endif /* IXGBE_FCOE */
1818
1813 /* Set the RX buffer length according to the mode */ 1819 /* Set the RX buffer length according to the mode */
1814 if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { 1820 if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
1815 rx_buf_len = IXGBE_RX_HDR_SIZE; 1821 rx_buf_len = IXGBE_RX_HDR_SIZE;
@@ -2241,6 +2247,11 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
2241 netif_set_gso_max_size(netdev, 65536); 2247 netif_set_gso_max_size(netdev, 65536);
2242#endif 2248#endif
2243 2249
2250#ifdef IXGBE_FCOE
2251 if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
2252 ixgbe_configure_fcoe(adapter);
2253
2254#endif /* IXGBE_FCOE */
2244 ixgbe_configure_tx(adapter); 2255 ixgbe_configure_tx(adapter);
2245 ixgbe_configure_rx(adapter); 2256 ixgbe_configure_rx(adapter);
2246 for (i = 0; i < adapter->num_rx_queues; i++) 2257 for (i = 0; i < adapter->num_rx_queues; i++)
@@ -3401,6 +3412,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
3401 adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; 3412 adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
3402 adapter->flags |= IXGBE_FLAG_RSC_CAPABLE; 3413 adapter->flags |= IXGBE_FLAG_RSC_CAPABLE;
3403 adapter->flags |= IXGBE_FLAG_RSC_ENABLED; 3414 adapter->flags |= IXGBE_FLAG_RSC_ENABLED;
3415#ifdef IXGBE_FCOE
3416 adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
3417#endif /* IXGBE_FCOE */
3404 } 3418 }
3405 3419
3406#ifdef CONFIG_IXGBE_DCB 3420#ifdef CONFIG_IXGBE_DCB
@@ -4416,10 +4430,12 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
4416 4430
4417static int ixgbe_tx_map(struct ixgbe_adapter *adapter, 4431static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
4418 struct ixgbe_ring *tx_ring, 4432 struct ixgbe_ring *tx_ring,
4419 struct sk_buff *skb, unsigned int first) 4433 struct sk_buff *skb, u32 tx_flags,
4434 unsigned int first)
4420{ 4435{
4421 struct ixgbe_tx_buffer *tx_buffer_info; 4436 struct ixgbe_tx_buffer *tx_buffer_info;
4422 unsigned int len = skb_headlen(skb); 4437 unsigned int len;
4438 unsigned int total = skb->len;
4423 unsigned int offset = 0, size, count = 0, i; 4439 unsigned int offset = 0, size, count = 0, i;
4424 unsigned int nr_frags = skb_shinfo(skb)->nr_frags; 4440 unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
4425 unsigned int f; 4441 unsigned int f;
@@ -4434,6 +4450,11 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
4434 4450
4435 map = skb_shinfo(skb)->dma_maps; 4451 map = skb_shinfo(skb)->dma_maps;
4436 4452
4453 if (tx_flags & IXGBE_TX_FLAGS_FCOE)
4454 /* excluding fcoe_crc_eof for FCoE */
4455 total -= sizeof(struct fcoe_crc_eof);
4456
4457 len = min(skb_headlen(skb), total);
4437 while (len) { 4458 while (len) {
4438 tx_buffer_info = &tx_ring->tx_buffer_info[i]; 4459 tx_buffer_info = &tx_ring->tx_buffer_info[i];
4439 size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); 4460 size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
@@ -4444,6 +4465,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
4444 tx_buffer_info->next_to_watch = i; 4465 tx_buffer_info->next_to_watch = i;
4445 4466
4446 len -= size; 4467 len -= size;
4468 total -= size;
4447 offset += size; 4469 offset += size;
4448 count++; 4470 count++;
4449 4471
@@ -4458,7 +4480,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
4458 struct skb_frag_struct *frag; 4480 struct skb_frag_struct *frag;
4459 4481
4460 frag = &skb_shinfo(skb)->frags[f]; 4482 frag = &skb_shinfo(skb)->frags[f];
4461 len = frag->size; 4483 len = min((unsigned int)frag->size, total);
4462 offset = 0; 4484 offset = 0;
4463 4485
4464 while (len) { 4486 while (len) {
@@ -4475,9 +4497,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
4475 tx_buffer_info->next_to_watch = i; 4497 tx_buffer_info->next_to_watch = i;
4476 4498
4477 len -= size; 4499 len -= size;
4500 total -= size;
4478 offset += size; 4501 offset += size;
4479 count++; 4502 count++;
4480 } 4503 }
4504 if (total == 0)
4505 break;
4481 } 4506 }
4482 4507
4483 tx_ring->tx_buffer_info[i].skb = skb; 4508 tx_ring->tx_buffer_info[i].skb = skb;
@@ -4519,6 +4544,13 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
4519 olinfo_status |= IXGBE_TXD_POPTS_TXSM << 4544 olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
4520 IXGBE_ADVTXD_POPTS_SHIFT; 4545 IXGBE_ADVTXD_POPTS_SHIFT;
4521 4546
4547 if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
4548 olinfo_status |= IXGBE_ADVTXD_CC;
4549 olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
4550 if (tx_flags & IXGBE_TX_FLAGS_FSO)
4551 cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
4552 }
4553
4522 olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT); 4554 olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
4523 4555
4524 i = tx_ring->next_to_use; 4556 i = tx_ring->next_to_use;
@@ -4615,10 +4647,16 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
4615 tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; 4647 tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
4616 tx_flags |= IXGBE_TX_FLAGS_VLAN; 4648 tx_flags |= IXGBE_TX_FLAGS_VLAN;
4617 } 4649 }
4618 /* three things can cause us to need a context descriptor */ 4650
4651 if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
4652 (skb->protocol == htons(ETH_P_FCOE)))
4653 tx_flags |= IXGBE_TX_FLAGS_FCOE;
4654
4655 /* four things can cause us to need a context descriptor */
4619 if (skb_is_gso(skb) || 4656 if (skb_is_gso(skb) ||
4620 (skb->ip_summed == CHECKSUM_PARTIAL) || 4657 (skb->ip_summed == CHECKSUM_PARTIAL) ||
4621 (tx_flags & IXGBE_TX_FLAGS_VLAN)) 4658 (tx_flags & IXGBE_TX_FLAGS_VLAN) ||
4659 (tx_flags & IXGBE_TX_FLAGS_FCOE))
4622 count++; 4660 count++;
4623 4661
4624 count += TXD_USE_COUNT(skb_headlen(skb)); 4662 count += TXD_USE_COUNT(skb_headlen(skb));
@@ -4630,23 +4668,35 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
4630 return NETDEV_TX_BUSY; 4668 return NETDEV_TX_BUSY;
4631 } 4669 }
4632 4670
4633 if (skb->protocol == htons(ETH_P_IP))
4634 tx_flags |= IXGBE_TX_FLAGS_IPV4;
4635 first = tx_ring->next_to_use; 4671 first = tx_ring->next_to_use;
4636 tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len); 4672 if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
4637 if (tso < 0) { 4673#ifdef IXGBE_FCOE
4638 dev_kfree_skb_any(skb); 4674 /* setup tx offload for FCoE */
4639 return NETDEV_TX_OK; 4675 tso = ixgbe_fso(adapter, tx_ring, skb, tx_flags, &hdr_len);
4640 } 4676 if (tso < 0) {
4641 4677 dev_kfree_skb_any(skb);
4642 if (tso) 4678 return NETDEV_TX_OK;
4643 tx_flags |= IXGBE_TX_FLAGS_TSO; 4679 }
4644 else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) && 4680 if (tso)
4645 (skb->ip_summed == CHECKSUM_PARTIAL)) 4681 tx_flags |= IXGBE_TX_FLAGS_FSO;
4646 tx_flags |= IXGBE_TX_FLAGS_CSUM; 4682#endif /* IXGBE_FCOE */
4683 } else {
4684 if (skb->protocol == htons(ETH_P_IP))
4685 tx_flags |= IXGBE_TX_FLAGS_IPV4;
4686 tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
4687 if (tso < 0) {
4688 dev_kfree_skb_any(skb);
4689 return NETDEV_TX_OK;
4690 }
4647 4691
4648 count = ixgbe_tx_map(adapter, tx_ring, skb, first); 4692 if (tso)
4693 tx_flags |= IXGBE_TX_FLAGS_TSO;
4694 else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
4695 (skb->ip_summed == CHECKSUM_PARTIAL))
4696 tx_flags |= IXGBE_TX_FLAGS_CSUM;
4697 }
4649 4698
4699 count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first);
4650 if (count) { 4700 if (count) {
4651 ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, 4701 ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
4652 hdr_len); 4702 hdr_len);
@@ -4794,6 +4844,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
4794 const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; 4844 const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
4795 static int cards_found; 4845 static int cards_found;
4796 int i, err, pci_using_dac; 4846 int i, err, pci_using_dac;
4847#ifdef IXGBE_FCOE
4848 u16 device_caps;
4849#endif
4797 u32 part_num, eec; 4850 u32 part_num, eec;
4798 4851
4799 err = pci_enable_device_mem(pdev); 4852 err = pci_enable_device_mem(pdev);
@@ -4976,6 +5029,19 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
4976 netdev->dcbnl_ops = &dcbnl_ops; 5029 netdev->dcbnl_ops = &dcbnl_ops;
4977#endif 5030#endif
4978 5031
5032#ifdef IXGBE_FCOE
5033 if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
5034 if (hw->mac.ops.get_device_caps) {
5035 hw->mac.ops.get_device_caps(hw, &device_caps);
5036 if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) {
5037 netdev->features |= NETIF_F_FCOE_CRC;
5038 netdev->features |= NETIF_F_FSO;
5039 } else {
5040 adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
5041 }
5042 }
5043 }
5044#endif /* IXGBE_FCOE */
4979 if (pci_using_dac) 5045 if (pci_using_dac)
4980 netdev->features |= NETIF_F_HIGHDMA; 5046 netdev->features |= NETIF_F_HIGHDMA;
4981 5047
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index c2d9ed5b9e05..b3de7233eeb1 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1483,6 +1483,7 @@
1483#endif 1483#endif
1484 1484
1485#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 1485#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
1486#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2
1486 1487
1487/* PCI Bus Info */ 1488/* PCI Bus Info */
1488#define IXGBE_PCI_LINK_STATUS 0xB2 1489#define IXGBE_PCI_LINK_STATUS 0xB2