ixgbe: filter FIP frames into the FCoE offload queues
authorChris Leech <christopher.leech@intel.com>
Wed, 24 Mar 2010 12:45:21 +0000 (12:45 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Mar 2010 18:56:04 +0000 (11:56 -0700)
During FCF solicitation, the switch is supposed to pad the
solicited advertisement out to the endpoints specified
maximum FCoE frame size.  That means that we need to receive
FIP frames that are larger than the standard MTU.  To make
sure the receive queue is configured correctly, we should be
filtering FIP traffic into the FCoE queues.

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_fcoe.c
drivers/net/ixgbe/ixgbe_type.h

index e1978da49e5b650e12c913f05e664f2ef4ecf20c..9276d5965b0d13271d64e4232cb6e9641e494430 100644 (file)
@@ -522,6 +522,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
        /* Enable L2 eth type filter for FCoE */
        IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
                        (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+       /* Enable L2 eth type filter for FIP */
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP),
+                       (ETH_P_FIP | IXGBE_ETQF_FILTER_EN));
        if (adapter->ring_feature[RING_F_FCOE].indices) {
                /* Use multiple rx queues for FCoE by redirection table */
                for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
@@ -532,6 +535,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
                }
                IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
                IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+               fcoe_i = f->mask;
+               fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+               fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+               IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+                               IXGBE_ETQS_QUEUE_EN |
+                               (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
        } else  {
                /* Use single rx queue for FCoE */
                fcoe_i = f->mask;
@@ -541,6 +550,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
                                IXGBE_ETQS_QUEUE_EN |
                                (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
        }
+       /* send FIP frames to the first FCoE queue */
+       fcoe_i = f->mask;
+       fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+       IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+                       IXGBE_ETQS_QUEUE_EN |
+                       (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
 
        IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
                        IXGBE_FCRXCTRL_FCOELLI |
index 0ed5ab37cc5301efe4dfb94a90eaacd60cb25b47..4ec6dc1a5b75c06a800d3bc7d61f8c2e6cab7853 100644 (file)
 #define IXGBE_ETQF_FILTER_BCN            1
 #define IXGBE_ETQF_FILTER_FCOE           2
 #define IXGBE_ETQF_FILTER_1588           3
+#define IXGBE_ETQF_FILTER_FIP            4
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET       0x0000FFFF  /* bits 0-15 */
 #define IXGBE_VLNCTRL_CFI       0x10000000  /* bit 28 */