ixgbe: add new wrapper for X550 support
authorDon Skidmore <donald.c.skidmore@intel.com>
Fri, 13 Mar 2015 20:54:30 +0000 (13:54 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 13 Mar 2015 20:54:30 +0000 (13:54 -0700)
For the X550 mac type we have to do additional steps around
enabling/disabling Rx.  This patch will add a layer of indirection
around these support functions to enable this.

CC: <kernel-team@fb.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c

index c5c97b4..51628b3 100644 (file)
@@ -1193,6 +1193,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
        .init_thermal_sensor_thresh = NULL,
        .prot_autoc_read        = &prot_autoc_read_generic,
        .prot_autoc_write       = &prot_autoc_write_generic,
+       .enable_rx              = &ixgbe_enable_rx_generic,
+       .disable_rx             = &ixgbe_disable_rx_generic,
 };
 
 static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
index cf55a0d..e0c3639 100644 (file)
@@ -1977,7 +1977,10 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
         */
        hw->mac.ops.disable_rx_buff(hw);
 
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+       if (regval & IXGBE_RXCTRL_RXEN)
+               hw->mac.ops.enable_rx(hw);
+       else
+               hw->mac.ops.disable_rx(hw);
 
        hw->mac.ops.enable_rx_buff(hw);
 
@@ -2336,6 +2339,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
        .init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,
        .prot_autoc_read        = &prot_autoc_read_82599,
        .prot_autoc_write       = &prot_autoc_write_82599,
+       .enable_rx              = &ixgbe_enable_rx_generic,
+       .disable_rx             = &ixgbe_disable_rx_generic,
 };
 
 static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
index 9c66bab..13b58f9 100644 (file)
@@ -703,7 +703,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
        hw->adapter_stopped = true;
 
        /* Disable the receive unit */
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, 0);
+       hw->mac.ops.disable_rx(hw);
 
        /* Clear interrupt mask to stop interrupts from being generated */
        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -2639,7 +2639,10 @@ s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw)
  **/
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
 {
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+       if (regval & IXGBE_RXCTRL_RXEN)
+               hw->mac.ops.enable_rx(hw);
+       else
+               hw->mac.ops.disable_rx(hw);
 
        return 0;
 }
@@ -3850,3 +3853,44 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
        return 0;
 }
 
+void ixgbe_disable_rx_generic(struct ixgbe_hw *hw)
+{
+       u32 rxctrl;
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+               if (hw->mac.type != ixgbe_mac_82598EB) {
+                       u32 pfdtxgswc;
+
+                       pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+                       if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
+                               pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+                               IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+                               hw->mac.set_lben = true;
+                       } else {
+                               hw->mac.set_lben = false;
+                       }
+               }
+               rxctrl &= ~IXGBE_RXCTRL_RXEN;
+               IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+       }
+}
+
+void ixgbe_enable_rx_generic(struct ixgbe_hw *hw)
+{
+       u32 rxctrl;
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN));
+
+       if (hw->mac.type != ixgbe_mac_82598EB) {
+               if (hw->mac.set_lben) {
+                       u32 pfdtxgswc;
+
+                       pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+                       pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN;
+                       IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+                       hw->mac.set_lben = false;
+               }
+       }
+}
index 8cfadcb..f21f8a1 100644 (file)
@@ -130,6 +130,8 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb,
 
 s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
+void ixgbe_disable_rx_generic(struct ixgbe_hw *hw);
+void ixgbe_enable_rx_generic(struct ixgbe_hw *hw);
 
 #define IXGBE_FAILED_READ_REG 0xffffffffU
 #define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU
index e5be0dd..02ffb30 100644 (file)
@@ -1637,9 +1637,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
        /* shut down the DMA engines now so they can be reinitialized later */
 
        /* first Rx */
-       reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
-       reg_ctl &= ~IXGBE_RXCTRL_RXEN;
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
+       hw->mac.ops.disable_rx(hw);
        ixgbe_disable_rx_queue(adapter, rx_ring);
 
        /* now Tx */
@@ -1670,6 +1668,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
        struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+       struct ixgbe_hw *hw = &adapter->hw;
        u32 rctl, reg_data;
        int ret_val;
        int err;
@@ -1713,14 +1712,16 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
                goto err_nomem;
        }
 
-       rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN);
+       hw->mac.ops.disable_rx(hw);
 
        ixgbe_configure_rx_ring(adapter, rx_ring);
 
-       rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS;
+       rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
+       rctl |= IXGBE_RXCTRL_DMBYPS;
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
 
+       hw->mac.ops.enable_rx(hw);
+
        return 0;
 
 err_nomem:
index 21aea7e..581015b 100644 (file)
@@ -3705,8 +3705,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        u32 rxctrl, rfctl;
 
        /* disable receives while setting up the descriptors */
-       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
+       hw->mac.ops.disable_rx(hw);
 
        ixgbe_setup_psrtype(adapter);
        ixgbe_setup_rdrxctl(adapter);
@@ -3731,6 +3730,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        for (i = 0; i < adapter->num_rx_queues; i++)
                ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]);
 
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
        /* disable drop enable for 82598 parts */
        if (hw->mac.type == ixgbe_mac_82598EB)
                rxctrl |= IXGBE_RXCTRL_DMBYPS;
@@ -5014,7 +5014,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        struct ixgbe_hw *hw = &adapter->hw;
        struct net_device *upper;
        struct list_head *iter;
-       u32 rxctrl;
        int i;
 
        /* signal that we are down to the interrupt handler */
@@ -5022,8 +5021,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
                return; /* do nothing if already down */
 
        /* disable receives */
-       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
+       hw->mac.ops.disable_rx(hw);
 
        /* disable all enabled rx queues */
        for (i = 0; i < adapter->num_rx_queues; i++)
index 8451f9a..02dc62e 100644 (file)
@@ -3067,6 +3067,8 @@ struct ixgbe_mac_operations {
        s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
        s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
        s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
+       void (*disable_rx)(struct ixgbe_hw *hw);
+       void (*enable_rx)(struct ixgbe_hw *hw);
        void (*set_ethertype_anti_spoofing)(struct ixgbe_hw *, bool, int);
 
        /* DMA Coalescing */
@@ -3137,6 +3139,7 @@ struct ixgbe_mac_info {
        u8                              flags;
        u8                              san_mac_rar_index;
        struct ixgbe_thermal_sensor_data  thermal_sensor_data;
+       bool                            set_lben;
 };
 
 struct ixgbe_phy_info {
index 4939542..f5f948d 100644 (file)
@@ -820,6 +820,8 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
        .init_thermal_sensor_thresh = NULL,
        .prot_autoc_read        = &prot_autoc_read_generic,
        .prot_autoc_write       = &prot_autoc_write_generic,
+       .enable_rx              = &ixgbe_enable_rx_generic,
+       .disable_rx             = &ixgbe_disable_rx_generic,
 };
 
 static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
index 50bf819..161a9e5 100644 (file)
@@ -557,6 +557,47 @@ static s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
        return status;
 }
 
+/** ixgbe_disable_rx_x550 - Disable RX unit
+ *
+ *  Enables the Rx DMA unit for x550
+ **/
+static void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
+{
+       u32 rxctrl, pfdtxgswc;
+       s32 status;
+       struct ixgbe_hic_disable_rxen fw_cmd;
+
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+               pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+               if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
+                       pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+                       IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+                       hw->mac.set_lben = true;
+               } else {
+                       hw->mac.set_lben = false;
+               }
+
+               fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
+               fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
+               fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+               fw_cmd.port_number = (u8)hw->bus.lan_id;
+
+               status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
+                                       sizeof(struct ixgbe_hic_disable_rxen),
+                                       IXGBE_HI_COMMAND_TIMEOUT, true);
+
+               /* If we fail - disable RX using register write */
+               if (status) {
+                       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+                       if (rxctrl & IXGBE_RXCTRL_RXEN) {
+                               rxctrl &= ~IXGBE_RXCTRL_RXEN;
+                               IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+                       }
+               }
+       }
+}
+
 /** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
  *  @hw: pointer to hardware structure
  *
@@ -1366,6 +1407,8 @@ void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, bool enable,
        .init_thermal_sensor_thresh     = NULL, \
        .prot_autoc_read                = &prot_autoc_read_generic, \
        .prot_autoc_write               = &prot_autoc_write_generic, \
+       .enable_rx                      = &ixgbe_enable_rx_generic, \
+       .disable_rx                     = &ixgbe_disable_rx_x550, \
 
 static struct ixgbe_mac_operations mac_ops_X550 = {
        X550_COMMON_MAC