[dpdk-dev] [PATCH v2 30/56] net/txgbe: add device stop and close operations
Jiawen Wu
jiawenwu at trustnetic.com
Mon Oct 5 14:08:44 CEST 2020
From: jiawenwu <jiawenwu at trustnetic.com>
Add device stop, close and reset operations. And support hardware
thermal sensor.
Signed-off-by: jiawenwu <jiawenwu at trustnetic.com>
---
drivers/net/txgbe/base/txgbe_hw.c | 70 +++++++++++++++++++
drivers/net/txgbe/base/txgbe_hw.h | 3 +
drivers/net/txgbe/base/txgbe_type.h | 11 +++
drivers/net/txgbe/txgbe_ethdev.c | 104 ++++++++++++++++++++++++++++
4 files changed, 188 insertions(+)
diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index 36e97eb4f..52b6f9888 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -965,6 +965,72 @@ 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;
@@ -1420,6 +1486,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 d6fbb0ca4..c75234e85 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);
extern 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 ef5924cf9..559b1206f 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
@@ -373,6 +383,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 d7fc110ac..11948389a 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -757,6 +757,70 @@ txgbe_dev_start(struct rte_eth_dev *dev)
return -EIO;
}
+/*
+ * Stop device: disable rx and tx functions to allow for reconfiguring.
+ */
+static void
+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;
+
+ 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;
+}
+
/*
* Set device link up: enable tx.
*/
@@ -803,6 +867,7 @@ txgbe_dev_set_link_down(struct rte_eth_dev *dev)
static void
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,9 +875,18 @@ txgbe_dev_close(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
+ txgbe_pf_reset_hw(hw);
+
+ 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);
+
dev->dev_ops = NULL;
+ dev->rx_pkt_burst = NULL;
+ dev->tx_pkt_burst = NULL;
/* disable uio intr before callback unregister */
rte_intr_disable(intr_handle);
@@ -840,6 +914,32 @@ txgbe_dev_close(struct rte_eth_dev *dev)
dev->data->hash_mac_addrs = NULL;
}
+/*
+ * 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
txgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
@@ -1576,8 +1676,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.18.4
More information about the dev
mailing list