0001
0002
0003
0004 #include <linux/skbuff.h>
0005 #include "hclge_main.h"
0006 #include "hnae3.h"
0007
0008 static int hclge_ptp_get_cycle(struct hclge_dev *hdev)
0009 {
0010 struct hclge_ptp *ptp = hdev->ptp;
0011
0012 ptp->cycle.quo = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG) &
0013 HCLGE_PTP_CYCLE_QUO_MASK;
0014 ptp->cycle.numer = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
0015 ptp->cycle.den = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
0016
0017 if (ptp->cycle.den == 0) {
0018 dev_err(&hdev->pdev->dev, "invalid ptp cycle denominator!\n");
0019 return -EINVAL;
0020 }
0021
0022 return 0;
0023 }
0024
0025 static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
0026 {
0027 struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
0028 struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle;
0029 u64 adj_val, adj_base, diff;
0030 unsigned long flags;
0031 bool is_neg = false;
0032 u32 quo, numerator;
0033
0034 if (ppb < 0) {
0035 ppb = -ppb;
0036 is_neg = true;
0037 }
0038
0039 adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer;
0040 adj_val = adj_base * ppb;
0041 diff = div_u64(adj_val, 1000000000ULL);
0042
0043 if (is_neg)
0044 adj_val = adj_base - diff;
0045 else
0046 adj_val = adj_base + diff;
0047
0048
0049
0050
0051
0052
0053 quo = div_u64_rem(adj_val, cycle->den, &numerator);
0054
0055 spin_lock_irqsave(&hdev->ptp->lock, flags);
0056 writel(quo & HCLGE_PTP_CYCLE_QUO_MASK,
0057 hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG);
0058 writel(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
0059 writel(cycle->den, hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
0060 writel(HCLGE_PTP_CYCLE_ADJ_EN,
0061 hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG);
0062 spin_unlock_irqrestore(&hdev->ptp->lock, flags);
0063
0064 return 0;
0065 }
0066
0067 bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
0068 {
0069 struct hclge_vport *vport = hclge_get_vport(handle);
0070 struct hclge_dev *hdev = vport->back;
0071 struct hclge_ptp *ptp = hdev->ptp;
0072
0073 if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
0074 test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
0075 ptp->tx_skipped++;
0076 return false;
0077 }
0078
0079 ptp->tx_start = jiffies;
0080 ptp->tx_skb = skb_get(skb);
0081 ptp->tx_cnt++;
0082
0083 return true;
0084 }
0085
0086 void hclge_ptp_clean_tx_hwts(struct hclge_dev *hdev)
0087 {
0088 struct sk_buff *skb = hdev->ptp->tx_skb;
0089 struct skb_shared_hwtstamps hwts;
0090 u32 hi, lo;
0091 u64 ns;
0092
0093 ns = readl(hdev->ptp->io_base + HCLGE_PTP_TX_TS_NSEC_REG) &
0094 HCLGE_PTP_TX_TS_NSEC_MASK;
0095 lo = readl(hdev->ptp->io_base + HCLGE_PTP_TX_TS_SEC_L_REG);
0096 hi = readl(hdev->ptp->io_base + HCLGE_PTP_TX_TS_SEC_H_REG) &
0097 HCLGE_PTP_TX_TS_SEC_H_MASK;
0098 hdev->ptp->last_tx_seqid = readl(hdev->ptp->io_base +
0099 HCLGE_PTP_TX_TS_SEQID_REG);
0100
0101 if (skb) {
0102 hdev->ptp->tx_skb = NULL;
0103 hdev->ptp->tx_cleaned++;
0104
0105 ns += (((u64)hi) << 32 | lo) * NSEC_PER_SEC;
0106 hwts.hwtstamp = ns_to_ktime(ns);
0107 skb_tstamp_tx(skb, &hwts);
0108 dev_kfree_skb_any(skb);
0109 }
0110
0111 clear_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state);
0112 }
0113
0114 void hclge_ptp_get_rx_hwts(struct hnae3_handle *handle, struct sk_buff *skb,
0115 u32 nsec, u32 sec)
0116 {
0117 struct hclge_vport *vport = hclge_get_vport(handle);
0118 struct hclge_dev *hdev = vport->back;
0119 unsigned long flags;
0120 u64 ns = nsec;
0121 u32 sec_h;
0122
0123 if (!test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
0124 return;
0125
0126
0127
0128
0129
0130 spin_lock_irqsave(&hdev->ptp->lock, flags);
0131 sec_h = readl(hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_H_REG);
0132 spin_unlock_irqrestore(&hdev->ptp->lock, flags);
0133
0134 ns += (((u64)sec_h) << HCLGE_PTP_SEC_H_OFFSET | sec) * NSEC_PER_SEC;
0135 skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
0136 hdev->ptp->last_rx = jiffies;
0137 hdev->ptp->rx_cnt++;
0138 }
0139
0140 static int hclge_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
0141 struct ptp_system_timestamp *sts)
0142 {
0143 struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
0144 unsigned long flags;
0145 u32 hi, lo;
0146 u64 ns;
0147
0148 spin_lock_irqsave(&hdev->ptp->lock, flags);
0149 ns = readl(hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_NSEC_REG);
0150 hi = readl(hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_H_REG);
0151 lo = readl(hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_L_REG);
0152 spin_unlock_irqrestore(&hdev->ptp->lock, flags);
0153
0154 ns += (((u64)hi) << HCLGE_PTP_SEC_H_OFFSET | lo) * NSEC_PER_SEC;
0155 *ts = ns_to_timespec64(ns);
0156
0157 return 0;
0158 }
0159
0160 static int hclge_ptp_settime(struct ptp_clock_info *ptp,
0161 const struct timespec64 *ts)
0162 {
0163 struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
0164 unsigned long flags;
0165
0166 spin_lock_irqsave(&hdev->ptp->lock, flags);
0167 writel(ts->tv_nsec, hdev->ptp->io_base + HCLGE_PTP_TIME_NSEC_REG);
0168 writel(ts->tv_sec >> HCLGE_PTP_SEC_H_OFFSET,
0169 hdev->ptp->io_base + HCLGE_PTP_TIME_SEC_H_REG);
0170 writel(ts->tv_sec & HCLGE_PTP_SEC_L_MASK,
0171 hdev->ptp->io_base + HCLGE_PTP_TIME_SEC_L_REG);
0172
0173 writel(HCLGE_PTP_TIME_SYNC_EN,
0174 hdev->ptp->io_base + HCLGE_PTP_TIME_SYNC_REG);
0175 spin_unlock_irqrestore(&hdev->ptp->lock, flags);
0176
0177 return 0;
0178 }
0179
0180 static int hclge_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
0181 {
0182 struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
0183 unsigned long flags;
0184 bool is_neg = false;
0185 u32 adj_val = 0;
0186
0187 if (delta < 0) {
0188 adj_val |= HCLGE_PTP_TIME_NSEC_NEG;
0189 delta = -delta;
0190 is_neg = true;
0191 }
0192
0193 if (delta > HCLGE_PTP_TIME_NSEC_MASK) {
0194 struct timespec64 ts;
0195 s64 ns;
0196
0197 hclge_ptp_gettimex(ptp, &ts, NULL);
0198 ns = timespec64_to_ns(&ts);
0199 ns = is_neg ? ns - delta : ns + delta;
0200 ts = ns_to_timespec64(ns);
0201 return hclge_ptp_settime(ptp, &ts);
0202 }
0203
0204 adj_val |= delta & HCLGE_PTP_TIME_NSEC_MASK;
0205
0206 spin_lock_irqsave(&hdev->ptp->lock, flags);
0207 writel(adj_val, hdev->ptp->io_base + HCLGE_PTP_TIME_NSEC_REG);
0208 writel(HCLGE_PTP_TIME_ADJ_EN,
0209 hdev->ptp->io_base + HCLGE_PTP_TIME_ADJ_REG);
0210 spin_unlock_irqrestore(&hdev->ptp->lock, flags);
0211
0212 return 0;
0213 }
0214
0215 int hclge_ptp_get_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
0216 {
0217 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state))
0218 return -EOPNOTSUPP;
0219
0220 return copy_to_user(ifr->ifr_data, &hdev->ptp->ts_cfg,
0221 sizeof(struct hwtstamp_config)) ? -EFAULT : 0;
0222 }
0223
0224 static int hclge_ptp_int_en(struct hclge_dev *hdev, bool en)
0225 {
0226 struct hclge_ptp_int_cmd *req;
0227 struct hclge_desc desc;
0228 int ret;
0229
0230 req = (struct hclge_ptp_int_cmd *)desc.data;
0231 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_INT_EN, false);
0232 req->int_en = en ? 1 : 0;
0233
0234 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0235 if (ret)
0236 dev_err(&hdev->pdev->dev,
0237 "failed to %s ptp interrupt, ret = %d\n",
0238 en ? "enable" : "disable", ret);
0239
0240 return ret;
0241 }
0242
0243 int hclge_ptp_cfg_qry(struct hclge_dev *hdev, u32 *cfg)
0244 {
0245 struct hclge_ptp_cfg_cmd *req;
0246 struct hclge_desc desc;
0247 int ret;
0248
0249 req = (struct hclge_ptp_cfg_cmd *)desc.data;
0250 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_MODE_CFG, true);
0251 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0252 if (ret) {
0253 dev_err(&hdev->pdev->dev,
0254 "failed to query ptp config, ret = %d\n", ret);
0255 return ret;
0256 }
0257
0258 *cfg = le32_to_cpu(req->cfg);
0259
0260 return 0;
0261 }
0262
0263 static int hclge_ptp_cfg(struct hclge_dev *hdev, u32 cfg)
0264 {
0265 struct hclge_ptp_cfg_cmd *req;
0266 struct hclge_desc desc;
0267 int ret;
0268
0269 req = (struct hclge_ptp_cfg_cmd *)desc.data;
0270 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_MODE_CFG, false);
0271 req->cfg = cpu_to_le32(cfg);
0272 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
0273 if (ret)
0274 dev_err(&hdev->pdev->dev,
0275 "failed to config ptp, ret = %d\n", ret);
0276
0277 return ret;
0278 }
0279
0280 static int hclge_ptp_set_tx_mode(struct hwtstamp_config *cfg,
0281 unsigned long *flags, u32 *ptp_cfg)
0282 {
0283 switch (cfg->tx_type) {
0284 case HWTSTAMP_TX_OFF:
0285 clear_bit(HCLGE_PTP_FLAG_TX_EN, flags);
0286 break;
0287 case HWTSTAMP_TX_ON:
0288 set_bit(HCLGE_PTP_FLAG_TX_EN, flags);
0289 *ptp_cfg |= HCLGE_PTP_TX_EN_B;
0290 break;
0291 default:
0292 return -ERANGE;
0293 }
0294
0295 return 0;
0296 }
0297
0298 static int hclge_ptp_set_rx_mode(struct hwtstamp_config *cfg,
0299 unsigned long *flags, u32 *ptp_cfg)
0300 {
0301 int rx_filter = cfg->rx_filter;
0302
0303 switch (cfg->rx_filter) {
0304 case HWTSTAMP_FILTER_NONE:
0305 clear_bit(HCLGE_PTP_FLAG_RX_EN, flags);
0306 break;
0307 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
0308 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
0309 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
0310 set_bit(HCLGE_PTP_FLAG_RX_EN, flags);
0311 *ptp_cfg |= HCLGE_PTP_RX_EN_B;
0312 *ptp_cfg |= HCLGE_PTP_UDP_FULL_TYPE << HCLGE_PTP_UDP_EN_SHIFT;
0313 rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
0314 break;
0315 case HWTSTAMP_FILTER_PTP_V2_EVENT:
0316 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
0317 case HWTSTAMP_FILTER_PTP_V2_SYNC:
0318 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
0319 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
0320 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
0321 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
0322 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
0323 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
0324 set_bit(HCLGE_PTP_FLAG_RX_EN, flags);
0325 *ptp_cfg |= HCLGE_PTP_RX_EN_B;
0326 *ptp_cfg |= HCLGE_PTP_UDP_FULL_TYPE << HCLGE_PTP_UDP_EN_SHIFT;
0327 *ptp_cfg |= HCLGE_PTP_MSG1_V2_DEFAULT << HCLGE_PTP_MSG1_SHIFT;
0328 *ptp_cfg |= HCLGE_PTP_MSG0_V2_EVENT << HCLGE_PTP_MSG0_SHIFT;
0329 *ptp_cfg |= HCLGE_PTP_MSG_TYPE_V2 << HCLGE_PTP_MSG_TYPE_SHIFT;
0330 rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
0331 break;
0332 case HWTSTAMP_FILTER_ALL:
0333 default:
0334 return -ERANGE;
0335 }
0336
0337 cfg->rx_filter = rx_filter;
0338
0339 return 0;
0340 }
0341
0342 static int hclge_ptp_set_ts_mode(struct hclge_dev *hdev,
0343 struct hwtstamp_config *cfg)
0344 {
0345 unsigned long flags = hdev->ptp->flags;
0346 u32 ptp_cfg = 0;
0347 int ret;
0348
0349 if (test_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags))
0350 ptp_cfg |= HCLGE_PTP_EN_B;
0351
0352 ret = hclge_ptp_set_tx_mode(cfg, &flags, &ptp_cfg);
0353 if (ret)
0354 return ret;
0355
0356 ret = hclge_ptp_set_rx_mode(cfg, &flags, &ptp_cfg);
0357 if (ret)
0358 return ret;
0359
0360 ret = hclge_ptp_cfg(hdev, ptp_cfg);
0361 if (ret)
0362 return ret;
0363
0364 hdev->ptp->flags = flags;
0365 hdev->ptp->ptp_cfg = ptp_cfg;
0366
0367 return 0;
0368 }
0369
0370 int hclge_ptp_set_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
0371 {
0372 struct hwtstamp_config cfg;
0373 int ret;
0374
0375 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state)) {
0376 dev_err(&hdev->pdev->dev, "phc is unsupported\n");
0377 return -EOPNOTSUPP;
0378 }
0379
0380 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
0381 return -EFAULT;
0382
0383 ret = hclge_ptp_set_ts_mode(hdev, &cfg);
0384 if (ret)
0385 return ret;
0386
0387 hdev->ptp->ts_cfg = cfg;
0388
0389 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
0390 }
0391
0392 int hclge_ptp_get_ts_info(struct hnae3_handle *handle,
0393 struct ethtool_ts_info *info)
0394 {
0395 struct hclge_vport *vport = hclge_get_vport(handle);
0396 struct hclge_dev *hdev = vport->back;
0397
0398 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state)) {
0399 dev_err(&hdev->pdev->dev, "phc is unsupported\n");
0400 return -EOPNOTSUPP;
0401 }
0402
0403 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
0404 SOF_TIMESTAMPING_RX_SOFTWARE |
0405 SOF_TIMESTAMPING_SOFTWARE |
0406 SOF_TIMESTAMPING_TX_HARDWARE |
0407 SOF_TIMESTAMPING_RX_HARDWARE |
0408 SOF_TIMESTAMPING_RAW_HARDWARE;
0409
0410 if (hdev->ptp->clock)
0411 info->phc_index = ptp_clock_index(hdev->ptp->clock);
0412 else
0413 info->phc_index = -1;
0414
0415 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
0416
0417 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
0418 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
0419 BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
0420 BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
0421
0422 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
0423 BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
0424 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
0425 BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
0426 BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
0427 BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
0428 BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
0429 BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
0430
0431 return 0;
0432 }
0433
0434 static int hclge_ptp_create_clock(struct hclge_dev *hdev)
0435 {
0436 struct hclge_ptp *ptp;
0437
0438 ptp = devm_kzalloc(&hdev->pdev->dev, sizeof(*ptp), GFP_KERNEL);
0439 if (!ptp)
0440 return -ENOMEM;
0441
0442 ptp->hdev = hdev;
0443 snprintf(ptp->info.name, sizeof(ptp->info.name), "%s",
0444 HCLGE_DRIVER_NAME);
0445 ptp->info.owner = THIS_MODULE;
0446 ptp->info.max_adj = HCLGE_PTP_CYCLE_ADJ_MAX;
0447 ptp->info.n_ext_ts = 0;
0448 ptp->info.pps = 0;
0449 ptp->info.adjfreq = hclge_ptp_adjfreq;
0450 ptp->info.adjtime = hclge_ptp_adjtime;
0451 ptp->info.gettimex64 = hclge_ptp_gettimex;
0452 ptp->info.settime64 = hclge_ptp_settime;
0453
0454 ptp->info.n_alarm = 0;
0455 ptp->clock = ptp_clock_register(&ptp->info, &hdev->pdev->dev);
0456 if (IS_ERR(ptp->clock)) {
0457 dev_err(&hdev->pdev->dev,
0458 "%d failed to register ptp clock, ret = %ld\n",
0459 ptp->info.n_alarm, PTR_ERR(ptp->clock));
0460 return -ENODEV;
0461 } else if (!ptp->clock) {
0462 dev_err(&hdev->pdev->dev, "failed to register ptp clock\n");
0463 return -ENODEV;
0464 }
0465
0466 spin_lock_init(&ptp->lock);
0467 ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
0468 ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
0469 ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
0470 hdev->ptp = ptp;
0471
0472 return 0;
0473 }
0474
0475 static void hclge_ptp_destroy_clock(struct hclge_dev *hdev)
0476 {
0477 ptp_clock_unregister(hdev->ptp->clock);
0478 hdev->ptp->clock = NULL;
0479 devm_kfree(&hdev->pdev->dev, hdev->ptp);
0480 hdev->ptp = NULL;
0481 }
0482
0483 int hclge_ptp_init(struct hclge_dev *hdev)
0484 {
0485 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
0486 struct timespec64 ts;
0487 int ret;
0488
0489 if (!test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps))
0490 return 0;
0491
0492 if (!hdev->ptp) {
0493 ret = hclge_ptp_create_clock(hdev);
0494 if (ret)
0495 return ret;
0496
0497 ret = hclge_ptp_get_cycle(hdev);
0498 if (ret)
0499 return ret;
0500 }
0501
0502 ret = hclge_ptp_int_en(hdev, true);
0503 if (ret)
0504 goto out;
0505
0506 set_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags);
0507 ret = hclge_ptp_adjfreq(&hdev->ptp->info, 0);
0508 if (ret) {
0509 dev_err(&hdev->pdev->dev,
0510 "failed to init freq, ret = %d\n", ret);
0511 goto out;
0512 }
0513
0514 ret = hclge_ptp_set_ts_mode(hdev, &hdev->ptp->ts_cfg);
0515 if (ret) {
0516 dev_err(&hdev->pdev->dev,
0517 "failed to init ts mode, ret = %d\n", ret);
0518 goto out;
0519 }
0520
0521 ktime_get_real_ts64(&ts);
0522 ret = hclge_ptp_settime(&hdev->ptp->info, &ts);
0523 if (ret) {
0524 dev_err(&hdev->pdev->dev,
0525 "failed to init ts time, ret = %d\n", ret);
0526 goto out;
0527 }
0528
0529 set_bit(HCLGE_STATE_PTP_EN, &hdev->state);
0530 dev_info(&hdev->pdev->dev, "phc initializes ok!\n");
0531
0532 return 0;
0533
0534 out:
0535 hclge_ptp_destroy_clock(hdev);
0536
0537 return ret;
0538 }
0539
0540 void hclge_ptp_uninit(struct hclge_dev *hdev)
0541 {
0542 struct hclge_ptp *ptp = hdev->ptp;
0543
0544 if (!ptp)
0545 return;
0546
0547 hclge_ptp_int_en(hdev, false);
0548 clear_bit(HCLGE_STATE_PTP_EN, &hdev->state);
0549 clear_bit(HCLGE_PTP_FLAG_EN, &ptp->flags);
0550 ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
0551 ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
0552
0553 if (hclge_ptp_set_ts_mode(hdev, &ptp->ts_cfg))
0554 dev_err(&hdev->pdev->dev, "failed to disable phc\n");
0555
0556 if (ptp->tx_skb) {
0557 struct sk_buff *skb = ptp->tx_skb;
0558
0559 ptp->tx_skb = NULL;
0560 dev_kfree_skb_any(skb);
0561 }
0562
0563 hclge_ptp_destroy_clock(hdev);
0564 }