int i, fcoe_q, fcoe_i;
u32 etqf;
- /* leave registers unconfigued if FCoE is disabled */
- if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
+ /* Minimal functionality for FCoE requires at least CRC offloads */
+ if (!(adapter->netdev->features & NETIF_F_FCOE_CRC))
return;
- /* Enable L2 EtherType filter for FCoE, necessary for FCoE Rx CRC */
+ /* Enable L2 EtherType filter for FCoE, needed for FCoE CRC and DDP */
etqf = ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN;
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
etqf |= IXGBE_ETQF_POOL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), etqf);
IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+ /* leave registers un-configured if FCoE is disabled */
+ if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
+ return;
+
/* Use one or more Rx queues for FCoE by redirection table */
for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
fcoe_i = fcoe->offset + (i % fcoe->indices);
/* enable FCoE and notify stack */
adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
- netdev->features |= NETIF_F_FSO | NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU;
+ netdev->features |= NETIF_F_FCOE_MTU;
netdev_features_change(netdev);
/* release existing queues and reallocate them */
/* disable FCoE and notify stack */
adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
- netdev->features &= ~(NETIF_F_FCOE_CRC |
- NETIF_F_FSO |
- NETIF_F_FCOE_MTU);
+ netdev->features &= ~NETIF_F_FCOE_MTU;
netdev_features_change(netdev);
#ifdef IXGBE_FCOE
/* setup tx offload for FCoE */
if ((protocol == __constant_htons(ETH_P_FCOE)) &&
- (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) {
+ (tx_ring->netdev->features & (NETIF_F_FSO | NETIF_F_FCOE_CRC))) {
tso = ixgbe_fso(tx_ring, first, &hdr_len);
if (tso < 0)
goto out_drop;
adapter->ring_feature[RING_F_FCOE].limit = IXGBE_FCRETA_SIZE;
+ netdev->features |= NETIF_F_FSO |
+ NETIF_F_FCOE_CRC;
+
netdev->vlan_features |= NETIF_F_FSO |
NETIF_F_FCOE_CRC |
NETIF_F_FCOE_MTU;