drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Extension
.c
Size
61849 bytes
Lines
2239
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tx_ret == NETDEV_TX_OK) {
			good_cnt++;
		} else {
			kfree_skb(skb);
			netdev_err(ndev, "hns3_lb_run_test xmit failed: %d\n",
				   tx_ret);
		}
	}
	if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM) {
		ret_val = HNS3_NIC_LB_TEST_TX_CNT_ERR;
		netdev_err(ndev, "mode %d sent fail, cnt=0x%x, budget=0x%x\n",
			   mode, good_cnt, HNS3_NIC_LB_TEST_PKT_NUM);
		goto out;
	}

	/* Allow 200 milliseconds for packets to go from Tx to Rx */
	msleep(200);

	good_cnt = hns3_lb_check_rx_ring(priv, HNS3_NIC_LB_TEST_PKT_NUM);
	if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM) {
		ret_val = HNS3_NIC_LB_TEST_RX_CNT_ERR;
		netdev_err(ndev, "mode %d recv fail, cnt=0x%x, budget=0x%x\n",
			   mode, good_cnt, HNS3_NIC_LB_TEST_PKT_NUM);
	}

out:
	hns3_lb_clear_tx_ring(priv, HNS3_NIC_LB_TEST_RING_ID,
			      HNS3_NIC_LB_TEST_RING_ID);

	kfree_skb(skb);
	return ret_val;
}

static void hns3_set_selftest_param(struct hnae3_handle *h, int (*st_param)[2])
{
	st_param[HNAE3_LOOP_EXTERNAL][0] = HNAE3_LOOP_EXTERNAL;
	st_param[HNAE3_LOOP_EXTERNAL][1] =
			h->flags & HNAE3_SUPPORT_EXTERNAL_LOOPBACK;

	st_param[HNAE3_LOOP_APP][0] = HNAE3_LOOP_APP;
	st_param[HNAE3_LOOP_APP][1] =
			h->flags & HNAE3_SUPPORT_APP_LOOPBACK;

	st_param[HNAE3_LOOP_SERIAL_SERDES][0] = HNAE3_LOOP_SERIAL_SERDES;
	st_param[HNAE3_LOOP_SERIAL_SERDES][1] =
			h->flags & HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;

	st_param[HNAE3_LOOP_PARALLEL_SERDES][0] =
			HNAE3_LOOP_PARALLEL_SERDES;
	st_param[HNAE3_LOOP_PARALLEL_SERDES][1] =
			h->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;

	st_param[HNAE3_LOOP_PHY][0] = HNAE3_LOOP_PHY;
	st_param[HNAE3_LOOP_PHY][1] =
			h->flags & HNAE3_SUPPORT_PHY_LOOPBACK;
}

static void hns3_selftest_prepare(struct net_device *ndev, bool if_running)
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hnae3_handle *h = priv->ae_handle;

	if (if_running)
		ndev->netdev_ops->ndo_stop(ndev);

#if IS_ENABLED(CONFIG_VLAN_8021Q)
	/* Disable the vlan filter for selftest does not support it */
	if (h->ae_algo->ops->enable_vlan_filter &&
	    ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
		h->ae_algo->ops->enable_vlan_filter(h, false);
#endif

	/* Tell firmware to stop mac autoneg before loopback test start,
	 * otherwise loopback test may be failed when the port is still
	 * negotiating.
	 */
	if (h->ae_algo->ops->halt_autoneg)
		h->ae_algo->ops->halt_autoneg(h, true);

	set_bit(HNS3_NIC_STATE_TESTING, &priv->state);
}

static void hns3_selftest_restore(struct net_device *ndev, bool if_running)
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hnae3_handle *h = priv->ae_handle;

	clear_bit(HNS3_NIC_STATE_TESTING, &priv->state);

	if (h->ae_algo->ops->halt_autoneg)

Annotation

Implementation Notes