Skip to content

Commit 0bf5eb7

Browse files
Huazhong Tandavem330
authored andcommitted
net: hns3: add support for PTP
Adds PTP support for HNS3 ethernet driver. Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: Yufeng Mo <[email protected]> Signed-off-by: Guangbin Huang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 76cf404 commit 0bf5eb7

File tree

11 files changed

+806
-6
lines changed

11 files changed

+806
-6
lines changed

drivers/net/ethernet/hisilicon/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ config HNS3_HCLGE
102102
tristate "Hisilicon HNS3 HCLGE Acceleration Engine & Compatibility Layer Support"
103103
default m
104104
depends on PCI_MSI
105+
imply PTP_1588_CLOCK
105106
help
106107
This selects the HNS3_HCLGE network acceleration engine & its hardware
107108
compatibility layer. The engine would be used in Hisilicon hip08 family of

drivers/net/ethernet/hisilicon/hns3/hnae3.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,12 @@ struct hnae3_ae_dev {
525525
* Check if any cls flower rule exist
526526
* dbg_read_cmd
527527
* Execute debugfs read command.
528+
* set_tx_hwts_info
529+
* Save information for 1588 tx packet
530+
* get_rx_hwts
531+
* Get 1588 rx hwstamp
532+
* get_ts_info
533+
* Get phc info
528534
*/
529535
struct hnae3_ae_ops {
530536
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
@@ -710,6 +716,12 @@ struct hnae3_ae_ops {
710716
struct ethtool_link_ksettings *cmd);
711717
int (*set_phy_link_ksettings)(struct hnae3_handle *handle,
712718
const struct ethtool_link_ksettings *cmd);
719+
bool (*set_tx_hwts_info)(struct hnae3_handle *handle,
720+
struct sk_buff *skb);
721+
void (*get_rx_hwts)(struct hnae3_handle *handle, struct sk_buff *skb,
722+
u32 nsec, u32 sec);
723+
int (*get_ts_info)(struct hnae3_handle *handle,
724+
struct ethtool_ts_info *info);
713725
};
714726

715727
struct hnae3_dcb_ops {

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,18 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,
17991799
WRITE_ONCE(ring->last_to_use, ring->next_to_use);
18001800
}
18011801

1802+
static void hns3_tsyn(struct net_device *netdev, struct sk_buff *skb,
1803+
struct hns3_desc *desc)
1804+
{
1805+
struct hnae3_handle *h = hns3_get_handle(netdev);
1806+
1807+
if (!(h->ae_algo->ops->set_tx_hwts_info &&
1808+
h->ae_algo->ops->set_tx_hwts_info(h, skb)))
1809+
return;
1810+
1811+
desc->tx.bdtp_fe_sc_vld_ra_ri |= cpu_to_le16(BIT(HNS3_TXD_TSYN_B));
1812+
}
1813+
18021814
netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
18031815
{
18041816
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)
18511863

18521864
pre_ntu = ring->next_to_use ? (ring->next_to_use - 1) :
18531865
(ring->desc_num - 1);
1866+
1867+
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
1868+
hns3_tsyn(netdev, skb, &ring->desc[pre_ntu]);
1869+
18541870
ring->desc[pre_ntu].tx.bdtp_fe_sc_vld_ra_ri |=
18551871
cpu_to_le16(BIT(HNS3_TXD_FE_B));
18561872
trace_hns3_tx_desc(ring, pre_ntu);
18571873

1874+
skb_tx_timestamp(skb);
1875+
18581876
/* Complete translate all packets */
18591877
dev_queue = netdev_get_tx_queue(netdev, ring->queue_index);
18601878
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)
35853603
ol_info = le32_to_cpu(desc->rx.ol_info);
35863604
csum = le16_to_cpu(desc->csum);
35873605

3606+
if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B))) {
3607+
struct hnae3_handle *h = hns3_get_handle(netdev);
3608+
u32 nsec = le32_to_cpu(desc->ts_nsec);
3609+
u32 sec = le32_to_cpu(desc->ts_sec);
3610+
3611+
if (h->ae_algo->ops->get_rx_hwts)
3612+
h->ae_algo->ops->get_rx_hwts(h, skb, nsec, sec);
3613+
}
3614+
35883615
/* Based on hw strategy, the tag offloaded will be stored at
35893616
* ot_vlan_tag in two layer tag case, and stored at vlan_tag
35903617
* in one layer tag case.

drivers/net/ethernet/hisilicon/hns3/hns3_enet.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ enum hns3_nic_state {
122122
#define HNS3_RXD_LUM_B 9
123123
#define HNS3_RXD_CRCP_B 10
124124
#define HNS3_RXD_L3L4P_B 11
125-
#define HNS3_RXD_TSIND_S 12
126-
#define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S)
125+
#define HNS3_RXD_TSIDX_S 12
126+
#define HNS3_RXD_TSIDX_M (0x3 << HNS3_RXD_TSIDX_S)
127+
#define HNS3_RXD_TS_VLD_B 14
127128
#define HNS3_RXD_LKBK_B 15
128129
#define HNS3_RXD_GRO_SIZE_S 16
129130
#define HNS3_RXD_GRO_SIZE_M (0x3fff << HNS3_RXD_GRO_SIZE_S)
@@ -240,6 +241,10 @@ struct __packed hns3_desc {
240241
union {
241242
__le64 addr;
242243
__le16 csum;
244+
struct {
245+
__le32 ts_nsec;
246+
__le32 ts_sec;
247+
};
243248
};
244249
union {
245250
struct {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,17 @@ static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
15981598
ETHTOOL_COALESCE_TX_USECS_HIGH | \
15991599
ETHTOOL_COALESCE_MAX_FRAMES)
16001600

1601+
static int hns3_get_ts_info(struct net_device *netdev,
1602+
struct ethtool_ts_info *info)
1603+
{
1604+
struct hnae3_handle *handle = hns3_get_handle(netdev);
1605+
1606+
if (handle->ae_algo->ops->get_ts_info)
1607+
return handle->ae_algo->ops->get_ts_info(handle, info);
1608+
1609+
return ethtool_op_get_ts_info(netdev, info);
1610+
}
1611+
16011612
static const struct ethtool_ops hns3vf_ethtool_ops = {
16021613
.supported_coalesce_params = HNS3_ETHTOOL_COALESCE,
16031614
.get_drvinfo = hns3_get_drvinfo,
@@ -1662,6 +1673,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
16621673
.get_module_eeprom = hns3_get_module_eeprom,
16631674
.get_priv_flags = hns3_get_priv_flags,
16641675
.set_priv_flags = hns3_set_priv_flags,
1676+
.get_ts_info = hns3_get_ts_info,
16651677
};
16661678

16671679
void hns3_ethtool_set_ops(struct net_device *netdev)

drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ ccflags-y := -I $(srctree)/drivers/net/ethernet/hisilicon/hns3
77
ccflags-y += -I $(srctree)/$(src)
88

99
obj-$(CONFIG_HNS3_HCLGE) += hclge.o
10-
hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o hclge_mbx.o hclge_err.o hclge_debugfs.o
10+
hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o hclge_mbx.o hclge_err.o hclge_debugfs.o hclge_ptp.o
1111

1212
hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ enum hclge_opcode_type {
130130
HCLGE_OPC_COMMON_LOOPBACK = 0x0315,
131131
HCLGE_OPC_CONFIG_FEC_MODE = 0x031A,
132132

133+
/* PTP commands */
134+
HCLGE_OPC_PTP_INT_EN = 0x0501,
135+
HCLGE_OPC_PTP_MODE_CFG = 0x0507,
136+
133137
/* PFC/Pause commands */
134138
HCLGE_OPC_CFG_MAC_PAUSE_EN = 0x0701,
135139
HCLGE_OPC_CFG_PFC_PAUSE_EN = 0x0702,

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,6 +3346,12 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
33463346
hw_err_src_reg & HCLGE_RAS_REG_ERR_MASK)
33473347
return HCLGE_VECTOR0_EVENT_ERR;
33483348

3349+
/* check for vector0 ptp event source */
3350+
if (BIT(HCLGE_VECTOR0_REG_PTP_INT_B) & msix_src_reg) {
3351+
*clearval = msix_src_reg;
3352+
return HCLGE_VECTOR0_EVENT_PTP;
3353+
}
3354+
33493355
/* check for vector0 mailbox(=CMDQ RX) event source */
33503356
if (BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) {
33513357
cmdq_src_reg &= ~BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B);
@@ -3365,6 +3371,7 @@ static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type,
33653371
u32 regclr)
33663372
{
33673373
switch (event_type) {
3374+
case HCLGE_VECTOR0_EVENT_PTP:
33683375
case HCLGE_VECTOR0_EVENT_RST:
33693376
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr);
33703377
break;
@@ -3393,6 +3400,7 @@ static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable)
33933400
static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
33943401
{
33953402
struct hclge_dev *hdev = data;
3403+
unsigned long flags;
33963404
u32 clearval = 0;
33973405
u32 event_cause;
33983406

@@ -3407,6 +3415,11 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
34073415
case HCLGE_VECTOR0_EVENT_RST:
34083416
hclge_reset_task_schedule(hdev);
34093417
break;
3418+
case HCLGE_VECTOR0_EVENT_PTP:
3419+
spin_lock_irqsave(&hdev->ptp->lock, flags);
3420+
hclge_ptp_clean_tx_hwts(hdev);
3421+
spin_unlock_irqrestore(&hdev->ptp->lock, flags);
3422+
break;
34103423
case HCLGE_VECTOR0_EVENT_MBX:
34113424
/* If we are here then,
34123425
* 1. Either we are not handling any mbx task and we are not
@@ -3428,7 +3441,8 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
34283441
hclge_clear_event_cause(hdev, event_cause, clearval);
34293442

34303443
/* Enable interrupt if it is not caused by reset event or error event */
3431-
if (event_cause == HCLGE_VECTOR0_EVENT_MBX ||
3444+
if (event_cause == HCLGE_VECTOR0_EVENT_PTP ||
3445+
event_cause == HCLGE_VECTOR0_EVENT_MBX ||
34323446
event_cause == HCLGE_VECTOR0_EVENT_OTHER)
34333447
hclge_enable_vector(&hdev->misc_vector, true);
34343448

@@ -4375,13 +4389,35 @@ static void hclge_periodic_service_task(struct hclge_dev *hdev)
43754389
hclge_task_schedule(hdev, delta);
43764390
}
43774391

4392+
static void hclge_ptp_service_task(struct hclge_dev *hdev)
4393+
{
4394+
unsigned long flags;
4395+
4396+
if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state) ||
4397+
!test_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state) ||
4398+
!time_is_before_jiffies(hdev->ptp->tx_start + HZ))
4399+
return;
4400+
4401+
/* to prevent concurrence with the irq handler */
4402+
spin_lock_irqsave(&hdev->ptp->lock, flags);
4403+
4404+
/* check HCLGE_STATE_PTP_TX_HANDLING here again, since the irq
4405+
* handler may handle it just before spin_lock_irqsave().
4406+
*/
4407+
if (test_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state))
4408+
hclge_ptp_clean_tx_hwts(hdev);
4409+
4410+
spin_unlock_irqrestore(&hdev->ptp->lock, flags);
4411+
}
4412+
43784413
static void hclge_service_task(struct work_struct *work)
43794414
{
43804415
struct hclge_dev *hdev =
43814416
container_of(work, struct hclge_dev, service_task.work);
43824417

43834418
hclge_errhand_service_task(hdev);
43844419
hclge_reset_service_task(hdev);
4420+
hclge_ptp_service_task(hdev);
43854421
hclge_mailbox_service_task(hdev);
43864422
hclge_periodic_service_task(hdev);
43874423

@@ -9413,8 +9449,15 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr,
94139449
struct hclge_vport *vport = hclge_get_vport(handle);
94149450
struct hclge_dev *hdev = vport->back;
94159451

9416-
if (!hdev->hw.mac.phydev)
9417-
return hclge_mii_ioctl(hdev, ifr, cmd);
9452+
switch (cmd) {
9453+
case SIOCGHWTSTAMP:
9454+
return hclge_ptp_get_cfg(hdev, ifr);
9455+
case SIOCSHWTSTAMP:
9456+
return hclge_ptp_set_cfg(hdev, ifr);
9457+
default:
9458+
if (!hdev->hw.mac.phydev)
9459+
return hclge_mii_ioctl(hdev, ifr, cmd);
9460+
}
94189461

94199462
return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd);
94209463
}
@@ -11530,6 +11573,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
1153011573
goto err_mdiobus_unreg;
1153111574
}
1153211575

11576+
ret = hclge_ptp_init(hdev);
11577+
if (ret)
11578+
goto err_mdiobus_unreg;
11579+
1153311580
INIT_KFIFO(hdev->mac_tnl_log);
1153411581

1153511582
hclge_dcb_ops_set(hdev);
@@ -11901,6 +11948,10 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
1190111948
return ret;
1190211949
}
1190311950

11951+
ret = hclge_ptp_init(hdev);
11952+
if (ret)
11953+
return ret;
11954+
1190411955
/* Log and clear the hw errors those already occurred */
1190511956
if (hnae3_dev_ras_imp_supported(hdev))
1190611957
hclge_handle_occurred_error(hdev);
@@ -11954,6 +12005,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
1195412005
hclge_clear_vf_vlan(hdev);
1195512006
hclge_misc_affinity_teardown(hdev);
1195612007
hclge_state_uninit(hdev);
12008+
hclge_ptp_uninit(hdev);
1195712009
hclge_uninit_rxd_adv_layout(hdev);
1195812010
hclge_uninit_mac_table(hdev);
1195912011
hclge_del_all_fd_entries(hdev);
@@ -12850,6 +12902,9 @@ static const struct hnae3_ae_ops hclge_ops = {
1285012902
.cls_flower_active = hclge_is_cls_flower_active,
1285112903
.get_phy_link_ksettings = hclge_get_phy_link_ksettings,
1285212904
.set_phy_link_ksettings = hclge_set_phy_link_ksettings,
12905+
.set_tx_hwts_info = hclge_ptp_set_tx_info,
12906+
.get_rx_hwts = hclge_ptp_get_rx_hwts,
12907+
.get_ts_info = hclge_ptp_get_ts_info,
1285312908
};
1285412909

1285512910
static struct hnae3_ae_algo ae_algo = {

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/kfifo.h>
1111

1212
#include "hclge_cmd.h"
13+
#include "hclge_ptp.h"
1314
#include "hnae3.h"
1415

1516
#define HCLGE_MOD_VERSION "1.0"
@@ -178,6 +179,7 @@ enum HLCGE_PORT_TYPE {
178179
#define HCLGE_FUN_RST_ING_B 0
179180

180181
/* Vector0 register bits define */
182+
#define HCLGE_VECTOR0_REG_PTP_INT_B 0
181183
#define HCLGE_VECTOR0_GLOBALRESET_INT_B 5
182184
#define HCLGE_VECTOR0_CORERESET_INT_B 6
183185
#define HCLGE_VECTOR0_IMPRESET_INT_B 7
@@ -230,13 +232,16 @@ enum HCLGE_DEV_STATE {
230232
HCLGE_STATE_FD_TBL_CHANGED,
231233
HCLGE_STATE_FD_CLEAR_ALL,
232234
HCLGE_STATE_FD_USER_DEF_CHANGED,
235+
HCLGE_STATE_PTP_EN,
236+
HCLGE_STATE_PTP_TX_HANDLING,
233237
HCLGE_STATE_MAX
234238
};
235239

236240
enum hclge_evt_cause {
237241
HCLGE_VECTOR0_EVENT_RST,
238242
HCLGE_VECTOR0_EVENT_MBX,
239243
HCLGE_VECTOR0_EVENT_ERR,
244+
HCLGE_VECTOR0_EVENT_PTP,
240245
HCLGE_VECTOR0_EVENT_OTHER,
241246
};
242247

@@ -935,6 +940,7 @@ struct hclge_dev {
935940
/* affinity mask and notify for misc interrupt */
936941
cpumask_t affinity_mask;
937942
struct irq_affinity_notify affinity_notify;
943+
struct hclge_ptp *ptp;
938944
};
939945

940946
/* VPort level vlan tag configuration for TX direction */

0 commit comments

Comments
 (0)