int i;
        bool link_up;
 
-       /*
-        * Validate the water mark configuration for packet buffer 0.  Zero
-        * water marks indicate that the packet buffer was not configured
-        * and the watermarks for packet buffer 0 should always be configured.
-        */
-       if (!hw->fc.low_water ||
-           !hw->fc.high_water[0] ||
-           !hw->fc.pause_time) {
-               hw_dbg(hw, "Invalid water mark configuration\n");
+       /* Validate the water mark configuration */
+       if (!hw->fc.pause_time) {
                ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
                goto out;
        }
 
+       /* Low water mark of zero causes XOFF floods */
+       for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+               if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+                   hw->fc.high_water[i]) {
+                       if (!hw->fc.low_water[i] ||
+                           hw->fc.low_water[i] >= hw->fc.high_water[i]) {
+                               hw_dbg(hw, "Invalid water mark configuration\n");
+                               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+                               goto out;
+                       }
+               }
+       }
+
        /*
         * On 82598 having Rx FC on causes resets while doing 1G
         * so if it's on turn it off once we know link_speed. For
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
        IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
-       fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
        /* Set up and enable Rx high/low water mark thresholds, enable XON. */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
                if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
                    hw->fc.high_water[i]) {
+                       fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                        fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
 
  **/
 s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
+       s32 ret_val;
        u32 ctrl_ext;
 
        /* Set the media type */
        IXGBE_WRITE_FLUSH(hw);
 
        /* Setup flow control */
-       ixgbe_setup_fc(hw);
+       ret_val = ixgbe_setup_fc(hw);
+       if (!ret_val)
+               goto out;
 
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
-       return 0;
+out:
+       return ret_val;
 }
 
 /**
        u32 fcrtl, fcrth;
        int i;
 
-       /*
-        * Validate the water mark configuration for packet buffer 0.  Zero
-        * water marks indicate that the packet buffer was not configured
-        * and the watermarks for packet buffer 0 should always be configured.
-        */
-       if (!hw->fc.low_water ||
-           !hw->fc.high_water[0] ||
-           !hw->fc.pause_time) {
-               hw_dbg(hw, "Invalid water mark configuration\n");
+       /* Validate the water mark configuration. */
+       if (!hw->fc.pause_time) {
                ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
                goto out;
        }
 
+       /* Low water mark of zero causes XOFF floods */
+       for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+               if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+                   hw->fc.high_water[i]) {
+                       if (!hw->fc.low_water[i] ||
+                           hw->fc.low_water[i] >= hw->fc.high_water[i]) {
+                               hw_dbg(hw, "Invalid water mark configuration\n");
+                               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+                               goto out;
+                       }
+               }
+       }
+
        /* Negotiate the fc mode to use */
        ixgbe_fc_autoneg(hw);
 
        IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
        IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
-       fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
        /* Set up and enable Rx high/low water mark thresholds, enable XON. */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
                if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
                    hw->fc.high_water[i]) {
+                       fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
                        fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
                } else {
 
 
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
 
-       fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
        /* Configure PFC Tx thresholds per TC */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
                if (!(pfc_en & (1 << i))) {
                        continue;
                }
 
+               fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
                IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
                IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
 
                        max_tc = prio_tc[i];
        }
 
-       fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
 
        /* Configure PFC Tx thresholds per TC */
        for (i = 0; i <= max_tc; i++) {
 
                if (enabled) {
                        reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+                       fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
                } else {
                        reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
 
        void *extra_ddp_buffer;
        dma_addr_t extra_ddp_buffer_dma;
        unsigned long mode;
-#ifdef CONFIG_IXGBE_DCB
        u8 up;
-#endif
 };
 
 #endif /* _IXGBE_FCOE_H */
 
            (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
            (pb == ixgbe_fcoe_get_tc(adapter)))
                tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
-
 #endif
+
        /* Calculate delay value for device */
        switch (hw->mac.type) {
        case ixgbe_mac_X540:
  * @adapter: board private structure to calculate for
  * @pb: packet buffer to calculate
  */
-static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter)
+static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        struct net_device *dev = adapter->netdev;
        /* Calculate max LAN frame size */
        tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
 
+#ifdef IXGBE_FCOE
+       /* FCoE traffic class uses FCOE jumbo frames */
+       if ((dev->features & NETIF_F_FCOE_MTU) &&
+           (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
+           (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up)))
+               tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+#endif
+
        /* Calculate delay value for device */
        switch (hw->mac.type) {
        case ixgbe_mac_X540:
        if (!num_tc)
                num_tc = 1;
 
-       hw->fc.low_water = ixgbe_lpbthresh(adapter);
-
        for (i = 0; i < num_tc; i++) {
                hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
+               hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
 
                /* Low water marks must not be larger than high water marks */
-               if (hw->fc.low_water > hw->fc.high_water[i])
-                       hw->fc.low_water = 0;
+               if (hw->fc.low_water[i] > hw->fc.high_water[i])
+                       hw->fc.low_water[i] = 0;
        }
+
+       for (; i < MAX_TRAFFIC_CLASS; i++)
+               hw->fc.high_water[i] = 0;
 }
 
 static void ixgbe_configure_pb(struct ixgbe_adapter *adapter)
 
 /* Flow control parameters */
 struct ixgbe_fc_info {
        u32 high_water[MAX_TRAFFIC_CLASS]; /* Flow Control High-water */
-       u32 low_water; /* Flow Control Low-water */
+       u32 low_water[MAX_TRAFFIC_CLASS]; /* Flow Control Low-water */
        u16 pause_time; /* Flow Control Pause timer */
        bool send_xon; /* Flow control send XON */
        bool strict_ieee; /* Strict IEEE mode */