From e0d876ef6bbc1fb40fc079a0a96406c3571633b5 Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Mon, 19 Oct 2020 16:53:47 +0800 Subject: [PATCH] net/txgbe: support device stop and close Add device stop, close and reset operations. And support hardware thermal sensor. Signed-off-by: Jiawen Wu Reviewed-by: Ferruh Yigit --- drivers/net/txgbe/base/txgbe_hw.c | 69 ++++++++++++++++++ drivers/net/txgbe/base/txgbe_hw.h | 3 + drivers/net/txgbe/base/txgbe_type.h | 11 +++ drivers/net/txgbe/txgbe_ethdev.c | 107 +++++++++++++++++++++++++++- 4 files changed, 189 insertions(+), 1 deletion(-) diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c index 9023ff1980..afd7172a9c 100644 --- a/drivers/net/txgbe/base/txgbe_hw.c +++ b/drivers/net/txgbe/base/txgbe_hw.c @@ -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; diff --git a/drivers/net/txgbe/base/txgbe_hw.h b/drivers/net/txgbe/base/txgbe_hw.h index 78b4dd2b5c..f0435976dc 100644 --- a/drivers/net/txgbe/base/txgbe_hw.h +++ b/drivers/net/txgbe/base/txgbe_hw.h @@ -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, diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h index c777d9f757..d21e9475c1 100644 --- a/drivers/net/txgbe/base/txgbe_type.h +++ b/drivers/net/txgbe/base/txgbe_type.h @@ -18,6 +18,16 @@ #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; }; diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index ddefd313d7..5c7eefbb69 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -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, -- 2.20.1