- if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
- fcrth = hw->fc.high_water[packetbuf_num] << 10;
- fcrth |= IXGBE_FCRTH_FCEN;
- if (hw->fc.send_xon)
- fcrtl |= IXGBE_FCRTL_XONE;
- } else {
- /*
- * If Tx flow control is disabled, set our high water mark
- * to Rx FIFO size minus 32 in order prevent Tx switch
- * loopback from stalling on DMA.
- */
- fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)) - 32;
- }
+ /* 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]) {
+ 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_FCRTL_82599(i), 0);
+ /*
+ * In order to prevent Tx hangs when the internal Tx
+ * switch is enabled we must set the high water mark
+ * to the maximum FCRTH value. This allows the Tx
+ * switch to function even under heavy Rx workloads.
+ */
+ fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+ }