#define IXGBE_MIN_RXD                       64
 
 /* flow control */
-#define IXGBE_DEFAULT_FCRTL            0x10000
 #define IXGBE_MIN_FCRTL                           0x40
 #define IXGBE_MAX_FCRTL                        0x7FF80
-#define IXGBE_DEFAULT_FCRTH            0x20000
 #define IXGBE_MIN_FCRTH                          0x600
 #define IXGBE_MAX_FCRTH                        0x7FFF0
 #define IXGBE_DEFAULT_FCPAUSE           0xFFFF
 
        u32 fctrl_reg;
        u32 rmcs_reg;
        u32 reg;
+       u32 rx_pba_size;
        u32 link_speed = 0;
        bool link_up;
 
 
        /* Set up and enable Rx high/low water mark thresholds, enable XON. */
        if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
-               if (hw->fc.send_xon) {
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
-                                       (hw->fc.low_water | IXGBE_FCRTL_XONE));
-               } else {
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
-                                       hw->fc.low_water);
-               }
+               rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+               rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+
+               reg = (rx_pba_size - hw->fc.low_water) << 6;
+               if (hw->fc.send_xon)
+                       reg |= IXGBE_FCRTL_XONE;
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);
+
+               reg = (rx_pba_size - hw->fc.high_water) << 10;
+               reg |= IXGBE_FCRTH_FCEN;
 
-               IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
-                               (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
        }
 
        /* Configure pause time (2 TCs per register) */
 
        u32 mflcn_reg, fccfg_reg;
        u32 reg;
        u32 rx_pba_size;
+       u32 fcrtl, fcrth;
 
 #ifdef CONFIG_DCB
        if (hw->fc.requested_mode == ixgbe_fc_pfc)
        IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
        IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
-       reg = IXGBE_READ_REG(hw, IXGBE_MTQC);
-       /* Thresholds are different for link flow control when in DCB mode */
-       if (reg & IXGBE_MTQC_RT_ENA) {
-               rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+       rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+       rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
 
-               /* Always disable XON for LFC when in DCB mode */
-               reg = (rx_pba_size >> 5) & 0xFFE0;
-               IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg);
+       fcrth = (rx_pba_size - hw->fc.high_water) << 10;
+       fcrtl = (rx_pba_size - hw->fc.low_water) << 10;
 
-               reg = (rx_pba_size >> 2) & 0xFFE0;
-               if (hw->fc.current_mode & ixgbe_fc_tx_pause)
-                       reg |= IXGBE_FCRTH_FCEN;
-               IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg);
-       } else {
-               /*
-                * Set up and enable Rx high/low water mark thresholds,
-                * enable XON.
-                */
-               if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
-                       if (hw->fc.send_xon) {
-                               IXGBE_WRITE_REG(hw,
-                                             IXGBE_FCRTL_82599(packetbuf_num),
-                                             (hw->fc.low_water |
-                                             IXGBE_FCRTL_XONE));
-                       } else {
-                               IXGBE_WRITE_REG(hw,
-                                             IXGBE_FCRTL_82599(packetbuf_num),
-                                             hw->fc.low_water);
-                       }
-
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
-                                      (hw->fc.high_water | IXGBE_FCRTH_FCEN));
-               }
+       if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+               fcrth |= IXGBE_FCRTH_FCEN;
+               if (hw->fc.send_xon)
+                       fcrtl |= IXGBE_FCRTL_XONE;
        }
 
+       IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth);
+       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl);
+
        /* Configure pause time (2 TCs per register) */
        reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
        if ((packetbuf_num & 1) == 0)
 
         * for each traffic class.
         */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
-               if (dcb_config->rx_pba_cfg == pba_equal) {
-                       rx_pba_size = IXGBE_RXPBSIZE_64KB;
-               } else {
-                       rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
-                                             : IXGBE_RXPBSIZE_48KB;
-               }
+               rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
+               rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+               reg = (rx_pba_size - hw->fc.low_water) << 10;
 
-               reg = ((rx_pba_size >> 5) &  0xFFF0);
                if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
                    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
                        reg |= IXGBE_FCRTL_XONE;
 
                IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
 
-               reg = ((rx_pba_size >> 2) & 0xFFF0);
+               reg = (rx_pba_size - hw->fc.high_water) << 10;
                if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
                    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
                        reg |= IXGBE_FCRTH_FCEN;
 
 
        /* Configure PFC Tx thresholds per TC */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
-               if (dcb_config->rx_pba_cfg == pba_equal)
-                       rx_pba_size = IXGBE_RXPBSIZE_64KB;
-               else
-                       rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
-                                             : IXGBE_RXPBSIZE_48KB;
+               rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
+               rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
+
+               reg = (rx_pba_size - hw->fc.low_water) << 10;
 
-               reg = ((rx_pba_size >> 5) & 0xFFE0);
                if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
                    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
                        reg |= IXGBE_FCRTL_XONE;
                IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
 
-               reg = ((rx_pba_size >> 2) & 0xFFE0);
+               reg = (rx_pba_size - hw->fc.high_water) << 10;
                if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
                    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
                        reg |= IXGBE_FCRTH_FCEN;
 
        int j;
        struct tc_configuration *tc;
 #endif
+       int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
 
        /* PCI config space info */
 
 #ifdef CONFIG_DCB
        adapter->last_lfc_mode = hw->fc.current_mode;
 #endif
-       hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
-       hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
+       hw->fc.high_water = FC_HIGH_WATER(max_frame);
+       hw->fc.low_water = FC_LOW_WATER(max_frame);
        hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
        hw->fc.send_xon = true;
        hw->fc.disable_fc_autoneg = false;
 static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
        /* MTU < 68 is an error and causes problems on some kernels */
        /* must set new MTU before calling down or up */
        netdev->mtu = new_mtu;
 
+       hw->fc.high_water = FC_HIGH_WATER(max_frame);
+       hw->fc.low_water = FC_LOW_WATER(max_frame);
+
        if (netif_running(netdev))
                ixgbe_reinit_locked(adapter);
 
 
 #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
 #define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
 
+/* Flow Control Macros */
+#define PAUSE_RTT      8
+#define PAUSE_MTU(MTU) ((MTU + 1024 - 1) / 1024)
+
+#define FC_HIGH_WATER(MTU) ((((PAUSE_RTT + PAUSE_MTU(MTU)) * 144) + 99) / 100 +\
+                               PAUSE_MTU(MTU))
+#define FC_LOW_WATER(MTU)  (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT))
+
 /* Software ATR hash keys */
 #define IXGBE_ATR_BUCKET_HASH_KEY    0xE214AD3D
 #define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17