Commit 0bf5eb78 authored by Huazhong Tan's avatar Huazhong Tan Committed by David S. Miller
Browse files

net: hns3: add support for PTP



Adds PTP support for HNS3 ethernet driver.

Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarYufeng Mo <moyufeng@huawei.com>
Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 76cf404c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ config HNS3_HCLGE
	tristate "Hisilicon HNS3 HCLGE Acceleration Engine & Compatibility Layer Support"
	default m
	depends on PCI_MSI
	imply PTP_1588_CLOCK
	help
	  This selects the HNS3_HCLGE network acceleration engine & its hardware
	  compatibility layer. The engine would be used in Hisilicon hip08 family of
+12 −0
Original line number Diff line number Diff line
@@ -525,6 +525,12 @@ struct hnae3_ae_dev {
 *   Check if any cls flower rule exist
 * dbg_read_cmd
 *   Execute debugfs read command.
 * set_tx_hwts_info
 *   Save information for 1588 tx packet
 * get_rx_hwts
 *   Get 1588 rx hwstamp
 * get_ts_info
 *   Get phc info
 */
struct hnae3_ae_ops {
	int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
@@ -710,6 +716,12 @@ struct hnae3_ae_ops {
				      struct ethtool_link_ksettings *cmd);
	int (*set_phy_link_ksettings)(struct hnae3_handle *handle,
				      const struct ethtool_link_ksettings *cmd);
	bool (*set_tx_hwts_info)(struct hnae3_handle *handle,
				 struct sk_buff *skb);
	void (*get_rx_hwts)(struct hnae3_handle *handle, struct sk_buff *skb,
			    u32 nsec, u32 sec);
	int (*get_ts_info)(struct hnae3_handle *handle,
			   struct ethtool_ts_info *info);
};

struct hnae3_dcb_ops {
+27 −0
Original line number Diff line number Diff line
@@ -1799,6 +1799,18 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,
	WRITE_ONCE(ring->last_to_use, ring->next_to_use);
}

static void hns3_tsyn(struct net_device *netdev, struct sk_buff *skb,
		      struct hns3_desc *desc)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	if (!(h->ae_algo->ops->set_tx_hwts_info &&
	      h->ae_algo->ops->set_tx_hwts_info(h, skb)))
		return;

	desc->tx.bdtp_fe_sc_vld_ra_ri |= cpu_to_le16(BIT(HNS3_TXD_TSYN_B));
}

netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
	struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -1851,10 +1863,16 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)

	pre_ntu = ring->next_to_use ? (ring->next_to_use - 1) :
					(ring->desc_num - 1);

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
		hns3_tsyn(netdev, skb, &ring->desc[pre_ntu]);

	ring->desc[pre_ntu].tx.bdtp_fe_sc_vld_ra_ri |=
				cpu_to_le16(BIT(HNS3_TXD_FE_B));
	trace_hns3_tx_desc(ring, pre_ntu);

	skb_tx_timestamp(skb);

	/* Complete translate all packets */
	dev_queue = netdev_get_tx_queue(netdev, ring->queue_index);
	doorbell = __netdev_tx_sent_queue(dev_queue, desc_cb->send_bytes,
@@ -3585,6 +3603,15 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb)
	ol_info = le32_to_cpu(desc->rx.ol_info);
	csum = le16_to_cpu(desc->csum);

	if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B))) {
		struct hnae3_handle *h = hns3_get_handle(netdev);
		u32 nsec = le32_to_cpu(desc->ts_nsec);
		u32 sec = le32_to_cpu(desc->ts_sec);

		if (h->ae_algo->ops->get_rx_hwts)
			h->ae_algo->ops->get_rx_hwts(h, skb, nsec, sec);
	}

	/* Based on hw strategy, the tag offloaded will be stored at
	 * ot_vlan_tag in two layer tag case, and stored at vlan_tag
	 * in one layer tag case.
+7 −2
Original line number Diff line number Diff line
@@ -122,8 +122,9 @@ enum hns3_nic_state {
#define HNS3_RXD_LUM_B				9
#define HNS3_RXD_CRCP_B				10
#define HNS3_RXD_L3L4P_B			11
#define HNS3_RXD_TSIND_S			12
#define HNS3_RXD_TSIND_M			(0x7 << HNS3_RXD_TSIND_S)
#define HNS3_RXD_TSIDX_S			12
#define HNS3_RXD_TSIDX_M			(0x3 << HNS3_RXD_TSIDX_S)
#define HNS3_RXD_TS_VLD_B			14
#define HNS3_RXD_LKBK_B				15
#define HNS3_RXD_GRO_SIZE_S			16
#define HNS3_RXD_GRO_SIZE_M			(0x3fff << HNS3_RXD_GRO_SIZE_S)
@@ -240,6 +241,10 @@ struct __packed hns3_desc {
	union {
		__le64 addr;
		__le16 csum;
		struct {
			__le32 ts_nsec;
			__le32 ts_sec;
		};
	};
	union {
		struct {
+12 −0
Original line number Diff line number Diff line
@@ -1598,6 +1598,17 @@ static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
				 ETHTOOL_COALESCE_TX_USECS_HIGH |	\
				 ETHTOOL_COALESCE_MAX_FRAMES)

static int hns3_get_ts_info(struct net_device *netdev,
			    struct ethtool_ts_info *info)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);

	if (handle->ae_algo->ops->get_ts_info)
		return handle->ae_algo->ops->get_ts_info(handle, info);

	return ethtool_op_get_ts_info(netdev, info);
}

static const struct ethtool_ops hns3vf_ethtool_ops = {
	.supported_coalesce_params = HNS3_ETHTOOL_COALESCE,
	.get_drvinfo = hns3_get_drvinfo,
@@ -1662,6 +1673,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
	.get_module_eeprom = hns3_get_module_eeprom,
	.get_priv_flags = hns3_get_priv_flags,
	.set_priv_flags = hns3_set_priv_flags,
	.get_ts_info = hns3_get_ts_info,
};

void hns3_ethtool_set_ops(struct net_device *netdev)
Loading