@@ -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)
33933400static  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+ 
43784413static  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
1285512910static  struct  hnae3_ae_algo  ae_algo  =  {
0 commit comments