net/txgbe: support device stop and close
authorJiawen Wu <jiawenwu@trustnetic.com>
Mon, 19 Oct 2020 08:53:47 +0000 (16:53 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 22:24:27 +0000 (23:24 +0100)
Add device stop, close and reset operations.
And support hardware thermal sensor.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/txgbe/base/txgbe_hw.c
drivers/net/txgbe/base/txgbe_hw.h
drivers/net/txgbe/base/txgbe_type.h
drivers/net/txgbe/txgbe_ethdev.c

index 9023ff1..afd7172 100644 (file)
@@ -960,6 +960,71 @@ void txgbe_clear_tx_pending(struct txgbe_hw *hw)
        wr32(hw, TXGBE_PSRCTL, hlreg0);
 }
 
+/**
+ *  txgbe_get_thermal_sensor_data - Gathers thermal sensor data
+ *  @hw: pointer to hardware structure
+ *
+ *  Returns the thermal sensor data structure
+ **/
+s32 txgbe_get_thermal_sensor_data(struct txgbe_hw *hw)
+{
+       struct txgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
+       s64 tsv;
+       u32 ts_stat;
+
+       DEBUGFUNC("txgbe_get_thermal_sensor_data");
+
+       /* Only support thermal sensors attached to physical port 0 */
+       if (hw->bus.lan_id != 0)
+               return TXGBE_NOT_IMPLEMENTED;
+
+       ts_stat = rd32(hw, TXGBE_TSSTAT);
+       tsv = (s64)TXGBE_TSSTAT_DATA(ts_stat);
+       tsv = tsv > 1200 ? tsv : 1200;
+       tsv = -(48380 << 8) / 1000
+               + tsv * (31020 << 8) / 100000
+               - tsv * tsv * (18201 << 8) / 100000000
+               + tsv * tsv * tsv * (81542 << 8) / 1000000000000
+               - tsv * tsv * tsv * tsv * (16743 << 8) / 1000000000000000;
+       tsv >>= 8;
+
+       data->sensor[0].temp = (s16)tsv;
+
+       return 0;
+}
+
+/**
+ *  txgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
+ *  @hw: pointer to hardware structure
+ *
+ *  Inits the thermal sensor thresholds according to the NVM map
+ *  and save off the threshold and location values into mac.thermal_sensor_data
+ **/
+s32 txgbe_init_thermal_sensor_thresh(struct txgbe_hw *hw)
+{
+       struct txgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
+
+       DEBUGFUNC("txgbe_init_thermal_sensor_thresh");
+
+       memset(data, 0, sizeof(struct txgbe_thermal_sensor_data));
+
+       if (hw->bus.lan_id != 0)
+               return TXGBE_NOT_IMPLEMENTED;
+
+       wr32(hw, TXGBE_TSCTRL, TXGBE_TSCTRL_EVALMD);
+       wr32(hw, TXGBE_TSINTR,
+               TXGBE_TSINTR_AEN | TXGBE_TSINTR_DEN);
+       wr32(hw, TXGBE_TSEN, TXGBE_TSEN_ENA);
+
+
+       data->sensor[0].alarm_thresh = 100;
+       wr32(hw, TXGBE_TSATHRE, 677);
+       data->sensor[0].dalarm_thresh = 90;
+       wr32(hw, TXGBE_TSDTHRE, 614);
+
+       return 0;
+}
+
 void txgbe_disable_rx(struct txgbe_hw *hw)
 {
        u32 pfdtxgswc;
@@ -1416,6 +1481,10 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
        mac->get_link_capabilities = txgbe_get_link_capabilities_raptor;
        mac->check_link = txgbe_check_mac_link;
 
+       /* Manageability interface */
+       mac->get_thermal_sensor_data = txgbe_get_thermal_sensor_data;
+       mac->init_thermal_sensor_thresh = txgbe_init_thermal_sensor_thresh;
+
        /* EEPROM */
        rom->init_params = txgbe_init_eeprom_params;
        rom->read16 = txgbe_ee_read16;
index 78b4dd2..f043597 100644 (file)
@@ -42,6 +42,9 @@ void txgbe_clear_tx_pending(struct txgbe_hw *hw);
 
 s32 txgbe_reset_pipeline_raptor(struct txgbe_hw *hw);
 
+s32 txgbe_get_thermal_sensor_data(struct txgbe_hw *hw);
+s32 txgbe_init_thermal_sensor_thresh(struct txgbe_hw *hw);
+
 void txgbe_disable_rx(struct txgbe_hw *hw);
 void txgbe_enable_rx(struct txgbe_hw *hw);
 s32 txgbe_setup_mac_link_multispeed_fiber(struct txgbe_hw *hw,
index c777d9f..d21e947 100644 (file)
 #include "txgbe_osdep.h"
 #include "txgbe_devids.h"
 
+struct txgbe_thermal_diode_data {
+       s16 temp;
+       s16 alarm_thresh;
+       s16 dalarm_thresh;
+};
+
+struct txgbe_thermal_sensor_data {
+       struct txgbe_thermal_diode_data sensor[1];
+};
+
 /* Physical layer type */
 #define TXGBE_PHYSICAL_LAYER_UNKNOWN           0
 #define TXGBE_PHYSICAL_LAYER_10GBASE_T         0x00001
@@ -360,6 +370,7 @@ struct txgbe_mac_info {
        bool orig_link_settings_stored;
        bool autotry_restart;
        u8 flags;
+       struct txgbe_thermal_sensor_data  thermal_sensor_data;
        bool set_lben;
        u32  max_link_up_time;
 };
index ddefd31..5c7eefb 100644 (file)
@@ -757,6 +757,73 @@ error:
        return -EIO;
 }
 
+/*
+ * Stop device: disable rx and tx functions to allow for reconfiguring.
+ */
+static int
+txgbe_dev_stop(struct rte_eth_dev *dev)
+{
+       struct rte_eth_link link;
+       struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+
+       if (hw->adapter_stopped)
+               return 0;
+
+       PMD_INIT_FUNC_TRACE();
+
+       rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler, dev);
+
+       /* disable interrupts */
+       txgbe_disable_intr(hw);
+
+       /* reset the NIC */
+       txgbe_pf_reset_hw(hw);
+       hw->adapter_stopped = 0;
+
+       /* stop adapter */
+       txgbe_stop_hw(hw);
+
+       if (hw->phy.media_type == txgbe_media_type_copper) {
+               /* Turn off the copper */
+               hw->phy.set_phy_power(hw, false);
+       } else {
+               /* Turn off the laser */
+               hw->mac.disable_tx_laser(hw);
+       }
+
+       txgbe_dev_clear_queues(dev);
+
+       /* Clear stored conf */
+       dev->data->scattered_rx = 0;
+       dev->data->lro = 0;
+
+       /* Clear recorded link status */
+       memset(&link, 0, sizeof(link));
+       rte_eth_linkstatus_set(dev, &link);
+
+       if (!rte_intr_allow_others(intr_handle))
+               /* resume to the default handler */
+               rte_intr_callback_register(intr_handle,
+                                          txgbe_dev_interrupt_handler,
+                                          (void *)dev);
+
+       /* Clean datapath event and queue/vec mapping */
+       rte_intr_efd_disable(intr_handle);
+       if (intr_handle->intr_vec != NULL) {
+               rte_free(intr_handle->intr_vec);
+               intr_handle->intr_vec = NULL;
+       }
+
+       wr32m(hw, TXGBE_LEDCTL, 0xFFFFFFFF, TXGBE_LEDCTL_SEL_MASK);
+
+       hw->adapter_stopped = true;
+       dev->data->dev_started = 0;
+
+       return 0;
+}
+
 /*
  * Set device link up: enable tx.
  */
@@ -803,6 +870,7 @@ txgbe_dev_set_link_down(struct rte_eth_dev *dev)
 static int
 txgbe_dev_close(struct rte_eth_dev *dev)
 {
+       struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        int retries = 0;
@@ -810,8 +878,15 @@ txgbe_dev_close(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
+       txgbe_pf_reset_hw(hw);
+
+       ret = txgbe_dev_stop(dev);
+
        txgbe_dev_free_queues(dev);
 
+       /* reprogram the RAR[0] in case user changed it. */
+       txgbe_set_rar(hw, 0, hw->mac.addr, 0, true);
+
        /* disable uio intr before callback unregister */
        rte_intr_disable(intr_handle);
 
@@ -837,7 +912,33 @@ txgbe_dev_close(struct rte_eth_dev *dev)
        rte_free(dev->data->hash_mac_addrs);
        dev->data->hash_mac_addrs = NULL;
 
-       return 0;
+       return ret;
+}
+
+/*
+ * Reset PF device.
+ */
+static int
+txgbe_dev_reset(struct rte_eth_dev *dev)
+{
+       int ret;
+
+       /* When a DPDK PMD PF begin to reset PF port, it should notify all
+        * its VF to make them align with it. The detailed notification
+        * mechanism is PMD specific. As to txgbe PF, it is rather complex.
+        * To avoid unexpected behavior in VF, currently reset of PF with
+        * SR-IOV activation is not supported. It might be supported later.
+        */
+       if (dev->data->sriov.active)
+               return -ENOTSUP;
+
+       ret = eth_txgbe_dev_uninit(dev);
+       if (ret)
+               return ret;
+
+       ret = eth_txgbe_dev_init(dev, NULL);
+
+       return ret;
 }
 
 static int
@@ -1577,8 +1678,12 @@ static const struct eth_dev_ops txgbe_eth_dev_ops = {
        .dev_configure              = txgbe_dev_configure,
        .dev_infos_get              = txgbe_dev_info_get,
        .dev_start                  = txgbe_dev_start,
+       .dev_stop                   = txgbe_dev_stop,
        .dev_set_link_up            = txgbe_dev_set_link_up,
        .dev_set_link_down          = txgbe_dev_set_link_down,
+       .dev_close                  = txgbe_dev_close,
+       .dev_reset                  = txgbe_dev_reset,
+       .link_update                = txgbe_dev_link_update,
        .dev_supported_ptypes_get   = txgbe_dev_supported_ptypes_get,
        .rx_queue_start             = txgbe_dev_rx_queue_start,
        .rx_queue_stop              = txgbe_dev_rx_queue_stop,