Back to home page

OSCL-LXR

 
 

    


0001 /* Broadcom NetXtreme-C/E network driver.
0002  *
0003  * Copyright (c) 2021 Broadcom Inc.
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation.
0008  */
0009 #include <linux/kernel.h>
0010 #include <linux/errno.h>
0011 #include <linux/pci.h>
0012 #include <linux/netdevice.h>
0013 #include <linux/etherdevice.h>
0014 #include <linux/net_tstamp.h>
0015 #include <linux/timekeeping.h>
0016 #include <linux/ptp_classify.h>
0017 #include "bnxt_hsi.h"
0018 #include "bnxt.h"
0019 #include "bnxt_hwrm.h"
0020 #include "bnxt_ptp.h"
0021 
0022 static int bnxt_ptp_cfg_settime(struct bnxt *bp, u64 time)
0023 {
0024     struct hwrm_func_ptp_cfg_input *req;
0025     int rc;
0026 
0027     rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
0028     if (rc)
0029         return rc;
0030 
0031     req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_SET_TIME);
0032     req->ptp_set_time = cpu_to_le64(time);
0033     return hwrm_req_send(bp, req);
0034 }
0035 
0036 int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off)
0037 {
0038     unsigned int ptp_class;
0039     struct ptp_header *hdr;
0040 
0041     ptp_class = ptp_classify_raw(skb);
0042 
0043     switch (ptp_class & PTP_CLASS_VMASK) {
0044     case PTP_CLASS_V1:
0045     case PTP_CLASS_V2:
0046         hdr = ptp_parse_header(skb, ptp_class);
0047         if (!hdr)
0048             return -EINVAL;
0049 
0050         *hdr_off = (u8 *)hdr - skb->data;
0051         *seq_id  = ntohs(hdr->sequence_id);
0052         return 0;
0053     default:
0054         return -ERANGE;
0055     }
0056 }
0057 
0058 static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
0059                 const struct timespec64 *ts)
0060 {
0061     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0062                         ptp_info);
0063     u64 ns = timespec64_to_ns(ts);
0064 
0065     if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
0066         return bnxt_ptp_cfg_settime(ptp->bp, ns);
0067 
0068     spin_lock_bh(&ptp->ptp_lock);
0069     timecounter_init(&ptp->tc, &ptp->cc, ns);
0070     spin_unlock_bh(&ptp->ptp_lock);
0071     return 0;
0072 }
0073 
0074 /* Caller holds ptp_lock */
0075 static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts,
0076                 u64 *ns)
0077 {
0078     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0079     u32 high_before, high_now, low;
0080 
0081     if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
0082         return -EIO;
0083 
0084     high_before = readl(bp->bar0 + ptp->refclk_mapped_regs[1]);
0085     ptp_read_system_prets(sts);
0086     low = readl(bp->bar0 + ptp->refclk_mapped_regs[0]);
0087     ptp_read_system_postts(sts);
0088     high_now = readl(bp->bar0 + ptp->refclk_mapped_regs[1]);
0089     if (high_now != high_before) {
0090         ptp_read_system_prets(sts);
0091         low = readl(bp->bar0 + ptp->refclk_mapped_regs[0]);
0092         ptp_read_system_postts(sts);
0093     }
0094     *ns = ((u64)high_now << 32) | low;
0095 
0096     return 0;
0097 }
0098 
0099 static void bnxt_ptp_get_current_time(struct bnxt *bp)
0100 {
0101     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0102 
0103     if (!ptp)
0104         return;
0105     spin_lock_bh(&ptp->ptp_lock);
0106     WRITE_ONCE(ptp->old_time, ptp->current_time);
0107     bnxt_refclk_read(bp, NULL, &ptp->current_time);
0108     spin_unlock_bh(&ptp->ptp_lock);
0109 }
0110 
0111 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts)
0112 {
0113     struct hwrm_port_ts_query_output *resp;
0114     struct hwrm_port_ts_query_input *req;
0115     int rc;
0116 
0117     rc = hwrm_req_init(bp, req, HWRM_PORT_TS_QUERY);
0118     if (rc)
0119         return rc;
0120 
0121     req->flags = cpu_to_le32(flags);
0122     if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) ==
0123         PORT_TS_QUERY_REQ_FLAGS_PATH_TX) {
0124         req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES);
0125         req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid);
0126         req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off);
0127         req->ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT);
0128     }
0129     resp = hwrm_req_hold(bp, req);
0130 
0131     rc = hwrm_req_send(bp, req);
0132     if (!rc)
0133         *ts = le64_to_cpu(resp->ptp_msg_ts);
0134     hwrm_req_drop(bp, req);
0135     return rc;
0136 }
0137 
0138 static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info,
0139                  struct timespec64 *ts,
0140                  struct ptp_system_timestamp *sts)
0141 {
0142     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0143                         ptp_info);
0144     u64 ns, cycles;
0145     int rc;
0146 
0147     spin_lock_bh(&ptp->ptp_lock);
0148     rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
0149     if (rc) {
0150         spin_unlock_bh(&ptp->ptp_lock);
0151         return rc;
0152     }
0153     ns = timecounter_cyc2time(&ptp->tc, cycles);
0154     spin_unlock_bh(&ptp->ptp_lock);
0155     *ts = ns_to_timespec64(ns);
0156 
0157     return 0;
0158 }
0159 
0160 /* Caller holds ptp_lock */
0161 void bnxt_ptp_update_current_time(struct bnxt *bp)
0162 {
0163     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0164 
0165     bnxt_refclk_read(ptp->bp, NULL, &ptp->current_time);
0166     WRITE_ONCE(ptp->old_time, ptp->current_time);
0167 }
0168 
0169 static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
0170 {
0171     struct hwrm_port_mac_cfg_input *req;
0172     int rc;
0173 
0174     rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG);
0175     if (rc)
0176         return rc;
0177 
0178     req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_ADJ_PHASE);
0179     req->ptp_adj_phase = cpu_to_le64(delta);
0180 
0181     rc = hwrm_req_send(ptp->bp, req);
0182     if (rc) {
0183         netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc);
0184     } else {
0185         spin_lock_bh(&ptp->ptp_lock);
0186         bnxt_ptp_update_current_time(ptp->bp);
0187         spin_unlock_bh(&ptp->ptp_lock);
0188     }
0189 
0190     return rc;
0191 }
0192 
0193 static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
0194 {
0195     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0196                         ptp_info);
0197 
0198     if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
0199         return bnxt_ptp_adjphc(ptp, delta);
0200 
0201     spin_lock_bh(&ptp->ptp_lock);
0202     timecounter_adjtime(&ptp->tc, delta);
0203     spin_unlock_bh(&ptp->ptp_lock);
0204     return 0;
0205 }
0206 
0207 static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
0208 {
0209     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0210                         ptp_info);
0211     struct hwrm_port_mac_cfg_input *req;
0212     struct bnxt *bp = ptp->bp;
0213     int rc;
0214 
0215     rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
0216     if (rc)
0217         return rc;
0218 
0219     req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
0220     req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
0221     rc = hwrm_req_send(ptp->bp, req);
0222     if (rc)
0223         netdev_err(ptp->bp->dev,
0224                "ptp adjfreq failed. rc = %d\n", rc);
0225     return rc;
0226 }
0227 
0228 void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
0229 {
0230     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0231     struct ptp_clock_event event;
0232     u64 ns, pps_ts;
0233 
0234     pps_ts = EVENT_PPS_TS(data2, data1);
0235     spin_lock_bh(&ptp->ptp_lock);
0236     ns = timecounter_cyc2time(&ptp->tc, pps_ts);
0237     spin_unlock_bh(&ptp->ptp_lock);
0238 
0239     switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) {
0240     case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL:
0241         event.pps_times.ts_real = ns_to_timespec64(ns);
0242         event.type = PTP_CLOCK_PPSUSR;
0243         event.index = EVENT_DATA2_PPS_PIN_NUM(data2);
0244         break;
0245     case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_EXTERNAL:
0246         event.timestamp = ns;
0247         event.type = PTP_CLOCK_EXTTS;
0248         event.index = EVENT_DATA2_PPS_PIN_NUM(data2);
0249         break;
0250     }
0251 
0252     ptp_clock_event(bp->ptp_cfg->ptp_clock, &event);
0253 }
0254 
0255 static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage)
0256 {
0257     struct hwrm_func_ptp_pin_cfg_input *req;
0258     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0259     u8 state = usage != BNXT_PPS_PIN_NONE;
0260     u8 *pin_state, *pin_usg;
0261     u32 enables;
0262     int rc;
0263 
0264     if (!TSIO_PIN_VALID(pin)) {
0265         netdev_err(ptp->bp->dev, "1PPS: Invalid pin. Check pin-function configuration\n");
0266         return -EOPNOTSUPP;
0267     }
0268 
0269     rc = hwrm_req_init(ptp->bp, req, HWRM_FUNC_PTP_PIN_CFG);
0270     if (rc)
0271         return rc;
0272 
0273     enables = (FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_STATE |
0274            FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_USAGE) << (pin * 2);
0275     req->enables = cpu_to_le32(enables);
0276 
0277     pin_state = &req->pin0_state;
0278     pin_usg = &req->pin0_usage;
0279 
0280     *(pin_state + (pin * 2)) = state;
0281     *(pin_usg + (pin * 2)) = usage;
0282 
0283     rc = hwrm_req_send(ptp->bp, req);
0284     if (rc)
0285         return rc;
0286 
0287     ptp->pps_info.pins[pin].usage = usage;
0288     ptp->pps_info.pins[pin].state = state;
0289 
0290     return 0;
0291 }
0292 
0293 static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event)
0294 {
0295     struct hwrm_func_ptp_cfg_input *req;
0296     int rc;
0297 
0298     rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
0299     if (rc)
0300         return rc;
0301 
0302     req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_PPS_EVENT);
0303     req->ptp_pps_event = event;
0304     return hwrm_req_send(bp, req);
0305 }
0306 
0307 void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp)
0308 {
0309     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0310     struct hwrm_port_mac_cfg_input *req;
0311 
0312     if (!ptp || !ptp->tstamp_filters)
0313         return;
0314 
0315     if (hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG))
0316         goto out;
0317 
0318     if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters &
0319         (PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
0320          PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE))) {
0321         ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
0322                      PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE);
0323         netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n");
0324     }
0325 
0326     req->flags = cpu_to_le32(ptp->tstamp_filters);
0327     req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
0328     req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
0329 
0330     if (!hwrm_req_send(bp, req)) {
0331         bp->ptp_all_rx_tstamp = !!(ptp->tstamp_filters &
0332                        PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE);
0333         return;
0334     }
0335     ptp->tstamp_filters = 0;
0336 out:
0337     bp->ptp_all_rx_tstamp = 0;
0338     netdev_warn(bp->dev, "Failed to configure HW packet timestamp filters\n");
0339 }
0340 
0341 void bnxt_ptp_reapply_pps(struct bnxt *bp)
0342 {
0343     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0344     struct bnxt_pps *pps;
0345     u32 pin = 0;
0346     int rc;
0347 
0348     if (!ptp || !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) ||
0349         !(ptp->ptp_info.pin_config))
0350         return;
0351     pps = &ptp->pps_info;
0352     for (pin = 0; pin < BNXT_MAX_TSIO_PINS; pin++) {
0353         if (pps->pins[pin].state) {
0354             rc = bnxt_ptp_cfg_pin(bp, pin, pps->pins[pin].usage);
0355             if (!rc && pps->pins[pin].event)
0356                 rc = bnxt_ptp_cfg_event(bp,
0357                             pps->pins[pin].event);
0358             if (rc)
0359                 netdev_err(bp->dev, "1PPS: Failed to configure pin%d\n",
0360                        pin);
0361         }
0362     }
0363 }
0364 
0365 static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns,
0366                   u64 *cycles_delta)
0367 {
0368     u64 cycles_now;
0369     u64 nsec_now, nsec_delta;
0370     int rc;
0371 
0372     spin_lock_bh(&ptp->ptp_lock);
0373     rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now);
0374     if (rc) {
0375         spin_unlock_bh(&ptp->ptp_lock);
0376         return rc;
0377     }
0378     nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now);
0379     spin_unlock_bh(&ptp->ptp_lock);
0380 
0381     nsec_delta = target_ns - nsec_now;
0382     *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult);
0383     return 0;
0384 }
0385 
0386 static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp,
0387                    struct ptp_clock_request *rq)
0388 {
0389     struct hwrm_func_ptp_cfg_input *req;
0390     struct bnxt *bp = ptp->bp;
0391     struct timespec64 ts;
0392     u64 target_ns, delta;
0393     u16 enables;
0394     int rc;
0395 
0396     ts.tv_sec = rq->perout.start.sec;
0397     ts.tv_nsec = rq->perout.start.nsec;
0398     target_ns = timespec64_to_ns(&ts);
0399 
0400     rc = bnxt_get_target_cycles(ptp, target_ns, &delta);
0401     if (rc)
0402         return rc;
0403 
0404     rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
0405     if (rc)
0406         return rc;
0407 
0408     enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD |
0409           FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP |
0410           FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE;
0411     req->enables = cpu_to_le16(enables);
0412     req->ptp_pps_event = 0;
0413     req->ptp_freq_adj_dll_source = 0;
0414     req->ptp_freq_adj_dll_phase = 0;
0415     req->ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC);
0416     req->ptp_freq_adj_ext_up = 0;
0417     req->ptp_freq_adj_ext_phase_lower = cpu_to_le32(delta);
0418 
0419     return hwrm_req_send(bp, req);
0420 }
0421 
0422 static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info,
0423                struct ptp_clock_request *rq, int on)
0424 {
0425     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0426                         ptp_info);
0427     struct bnxt *bp = ptp->bp;
0428     int pin_id;
0429     int rc;
0430 
0431     switch (rq->type) {
0432     case PTP_CLK_REQ_EXTTS:
0433         /* Configure an External PPS IN */
0434         pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS,
0435                       rq->extts.index);
0436         if (!TSIO_PIN_VALID(pin_id))
0437             return -EOPNOTSUPP;
0438         if (!on)
0439             break;
0440         rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_IN);
0441         if (rc)
0442             return rc;
0443         rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_EXTERNAL);
0444         if (!rc)
0445             ptp->pps_info.pins[pin_id].event = BNXT_PPS_EVENT_EXTERNAL;
0446         return rc;
0447     case PTP_CLK_REQ_PEROUT:
0448         /* Configure a Periodic PPS OUT */
0449         pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT,
0450                       rq->perout.index);
0451         if (!TSIO_PIN_VALID(pin_id))
0452             return -EOPNOTSUPP;
0453         if (!on)
0454             break;
0455 
0456         rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_OUT);
0457         if (!rc)
0458             rc = bnxt_ptp_perout_cfg(ptp, rq);
0459 
0460         return rc;
0461     case PTP_CLK_REQ_PPS:
0462         /* Configure PHC PPS IN */
0463         rc = bnxt_ptp_cfg_pin(bp, 0, BNXT_PPS_PIN_PPS_IN);
0464         if (rc)
0465             return rc;
0466         rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_INTERNAL);
0467         if (!rc)
0468             ptp->pps_info.pins[0].event = BNXT_PPS_EVENT_INTERNAL;
0469         return rc;
0470     default:
0471         netdev_err(ptp->bp->dev, "Unrecognized PIN function\n");
0472         return -EOPNOTSUPP;
0473     }
0474 
0475     return bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_NONE);
0476 }
0477 
0478 static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
0479 {
0480     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0481     u32 flags = 0;
0482     int rc = 0;
0483 
0484     switch (ptp->rx_filter) {
0485     case HWTSTAMP_FILTER_ALL:
0486         flags = PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE;
0487         break;
0488     case HWTSTAMP_FILTER_NONE:
0489         flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE;
0490         if (bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS)
0491             flags |= PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE;
0492         break;
0493     case HWTSTAMP_FILTER_PTP_V2_EVENT:
0494     case HWTSTAMP_FILTER_PTP_V2_SYNC:
0495     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
0496         flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
0497         break;
0498     }
0499 
0500     if (ptp->tx_tstamp_en)
0501         flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
0502     else
0503         flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
0504 
0505     ptp->tstamp_filters = flags;
0506 
0507     if (netif_running(bp->dev)) {
0508         rc = bnxt_close_nic(bp, false, false);
0509         if (!rc)
0510             rc = bnxt_open_nic(bp, false, false);
0511         if (!rc && !ptp->tstamp_filters)
0512             rc = -EIO;
0513     }
0514 
0515     return rc;
0516 }
0517 
0518 int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
0519 {
0520     struct bnxt *bp = netdev_priv(dev);
0521     struct hwtstamp_config stmpconf;
0522     struct bnxt_ptp_cfg *ptp;
0523     u16 old_rxctl;
0524     int old_rx_filter, rc;
0525     u8 old_tx_tstamp_en;
0526 
0527     ptp = bp->ptp_cfg;
0528     if (!ptp)
0529         return -EOPNOTSUPP;
0530 
0531     if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf)))
0532         return -EFAULT;
0533 
0534     if (stmpconf.tx_type != HWTSTAMP_TX_ON &&
0535         stmpconf.tx_type != HWTSTAMP_TX_OFF)
0536         return -ERANGE;
0537 
0538     old_rx_filter = ptp->rx_filter;
0539     old_rxctl = ptp->rxctl;
0540     old_tx_tstamp_en = ptp->tx_tstamp_en;
0541     switch (stmpconf.rx_filter) {
0542     case HWTSTAMP_FILTER_NONE:
0543         ptp->rxctl = 0;
0544         ptp->rx_filter = HWTSTAMP_FILTER_NONE;
0545         break;
0546     case HWTSTAMP_FILTER_ALL:
0547         if (bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) {
0548             ptp->rx_filter = HWTSTAMP_FILTER_ALL;
0549             break;
0550         }
0551         return -EOPNOTSUPP;
0552     case HWTSTAMP_FILTER_PTP_V2_EVENT:
0553     case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
0554     case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
0555         ptp->rxctl = BNXT_PTP_MSG_EVENTS;
0556         ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
0557         break;
0558     case HWTSTAMP_FILTER_PTP_V2_SYNC:
0559     case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
0560     case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
0561         ptp->rxctl = BNXT_PTP_MSG_SYNC;
0562         ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC;
0563         break;
0564     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
0565     case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
0566     case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
0567         ptp->rxctl = BNXT_PTP_MSG_DELAY_REQ;
0568         ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
0569         break;
0570     default:
0571         return -ERANGE;
0572     }
0573 
0574     if (stmpconf.tx_type == HWTSTAMP_TX_ON)
0575         ptp->tx_tstamp_en = 1;
0576     else
0577         ptp->tx_tstamp_en = 0;
0578 
0579     rc = bnxt_hwrm_ptp_cfg(bp);
0580     if (rc)
0581         goto ts_set_err;
0582 
0583     stmpconf.rx_filter = ptp->rx_filter;
0584     return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
0585         -EFAULT : 0;
0586 
0587 ts_set_err:
0588     ptp->rx_filter = old_rx_filter;
0589     ptp->rxctl = old_rxctl;
0590     ptp->tx_tstamp_en = old_tx_tstamp_en;
0591     return rc;
0592 }
0593 
0594 int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
0595 {
0596     struct bnxt *bp = netdev_priv(dev);
0597     struct hwtstamp_config stmpconf;
0598     struct bnxt_ptp_cfg *ptp;
0599 
0600     ptp = bp->ptp_cfg;
0601     if (!ptp)
0602         return -EOPNOTSUPP;
0603 
0604     stmpconf.flags = 0;
0605     stmpconf.tx_type = ptp->tx_tstamp_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
0606 
0607     stmpconf.rx_filter = ptp->rx_filter;
0608     return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
0609         -EFAULT : 0;
0610 }
0611 
0612 static int bnxt_map_regs(struct bnxt *bp, u32 *reg_arr, int count, int reg_win)
0613 {
0614     u32 reg_base = *reg_arr & BNXT_GRC_BASE_MASK;
0615     u32 win_off;
0616     int i;
0617 
0618     for (i = 0; i < count; i++) {
0619         if ((reg_arr[i] & BNXT_GRC_BASE_MASK) != reg_base)
0620             return -ERANGE;
0621     }
0622     win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4;
0623     writel(reg_base, bp->bar0 + win_off);
0624     return 0;
0625 }
0626 
0627 static int bnxt_map_ptp_regs(struct bnxt *bp)
0628 {
0629     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0630     u32 *reg_arr;
0631     int rc, i;
0632 
0633     reg_arr = ptp->refclk_regs;
0634     if (bp->flags & BNXT_FLAG_CHIP_P5) {
0635         rc = bnxt_map_regs(bp, reg_arr, 2, BNXT_PTP_GRC_WIN);
0636         if (rc)
0637             return rc;
0638         for (i = 0; i < 2; i++)
0639             ptp->refclk_mapped_regs[i] = BNXT_PTP_GRC_WIN_BASE +
0640                 (ptp->refclk_regs[i] & BNXT_GRC_OFFSET_MASK);
0641         return 0;
0642     }
0643     return -ENODEV;
0644 }
0645 
0646 static void bnxt_unmap_ptp_regs(struct bnxt *bp)
0647 {
0648     writel(0, bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT +
0649           (BNXT_PTP_GRC_WIN - 1) * 4);
0650 }
0651 
0652 static u64 bnxt_cc_read(const struct cyclecounter *cc)
0653 {
0654     struct bnxt_ptp_cfg *ptp = container_of(cc, struct bnxt_ptp_cfg, cc);
0655     u64 ns = 0;
0656 
0657     bnxt_refclk_read(ptp->bp, NULL, &ns);
0658     return ns;
0659 }
0660 
0661 static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
0662 {
0663     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0664     struct skb_shared_hwtstamps timestamp;
0665     u64 ts = 0, ns = 0;
0666     int rc;
0667 
0668     rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts);
0669     if (!rc) {
0670         memset(&timestamp, 0, sizeof(timestamp));
0671         spin_lock_bh(&ptp->ptp_lock);
0672         ns = timecounter_cyc2time(&ptp->tc, ts);
0673         spin_unlock_bh(&ptp->ptp_lock);
0674         timestamp.hwtstamp = ns_to_ktime(ns);
0675         skb_tstamp_tx(ptp->tx_skb, &timestamp);
0676     } else {
0677         netdev_err(bp->dev, "TS query for TX timer failed rc = %x\n",
0678                rc);
0679     }
0680 
0681     dev_kfree_skb_any(ptp->tx_skb);
0682     ptp->tx_skb = NULL;
0683     atomic_inc(&ptp->tx_avail);
0684 }
0685 
0686 static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
0687 {
0688     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0689                         ptp_info);
0690     unsigned long now = jiffies;
0691     struct bnxt *bp = ptp->bp;
0692 
0693     if (ptp->tx_skb)
0694         bnxt_stamp_tx_skb(bp, ptp->tx_skb);
0695 
0696     if (!time_after_eq(now, ptp->next_period))
0697         return ptp->next_period - now;
0698 
0699     bnxt_ptp_get_current_time(bp);
0700     ptp->next_period = now + HZ;
0701     if (time_after_eq(now, ptp->next_overflow_check)) {
0702         spin_lock_bh(&ptp->ptp_lock);
0703         timecounter_read(&ptp->tc);
0704         spin_unlock_bh(&ptp->ptp_lock);
0705         ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
0706     }
0707     return HZ;
0708 }
0709 
0710 int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb)
0711 {
0712     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0713 
0714     if (ptp->tx_skb) {
0715         netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n");
0716         return -EBUSY;
0717     }
0718     ptp->tx_skb = skb;
0719     ptp_schedule_worker(ptp->ptp_clock, 0);
0720     return 0;
0721 }
0722 
0723 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts)
0724 {
0725     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0726     u64 time;
0727 
0728     if (!ptp)
0729         return -ENODEV;
0730 
0731     BNXT_READ_TIME64(ptp, time, ptp->old_time);
0732     *ts = (time & BNXT_HI_TIMER_MASK) | pkt_ts;
0733     if (pkt_ts < (time & BNXT_LO_TIMER_MASK))
0734         *ts += BNXT_LO_TIMER_MASK + 1;
0735 
0736     return 0;
0737 }
0738 
0739 static const struct ptp_clock_info bnxt_ptp_caps = {
0740     .owner      = THIS_MODULE,
0741     .name       = "bnxt clock",
0742     .max_adj    = BNXT_MAX_PHC_DRIFT,
0743     .n_alarm    = 0,
0744     .n_ext_ts   = 0,
0745     .n_per_out  = 0,
0746     .n_pins     = 0,
0747     .pps        = 0,
0748     .adjfreq    = bnxt_ptp_adjfreq,
0749     .adjtime    = bnxt_ptp_adjtime,
0750     .do_aux_work    = bnxt_ptp_ts_aux_work,
0751     .gettimex64 = bnxt_ptp_gettimex,
0752     .settime64  = bnxt_ptp_settime,
0753     .enable     = bnxt_ptp_enable,
0754 };
0755 
0756 static int bnxt_ptp_verify(struct ptp_clock_info *ptp_info, unsigned int pin,
0757                enum ptp_pin_function func, unsigned int chan)
0758 {
0759     struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
0760                         ptp_info);
0761     /* Allow only PPS pin function configuration */
0762     if (ptp->pps_info.pins[pin].usage <= BNXT_PPS_PIN_PPS_OUT &&
0763         func != PTP_PF_PHYSYNC)
0764         return 0;
0765     else
0766         return -EOPNOTSUPP;
0767 }
0768 
0769 static int bnxt_ptp_pps_init(struct bnxt *bp)
0770 {
0771     struct hwrm_func_ptp_pin_qcfg_output *resp;
0772     struct hwrm_func_ptp_pin_qcfg_input *req;
0773     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0774     struct ptp_clock_info *ptp_info;
0775     struct bnxt_pps *pps_info;
0776     u8 *pin_usg;
0777     u32 i, rc;
0778 
0779     /* Query current/default PIN CFG */
0780     rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_PIN_QCFG);
0781     if (rc)
0782         return rc;
0783 
0784     resp = hwrm_req_hold(bp, req);
0785     rc = hwrm_req_send(bp, req);
0786     if (rc || !resp->num_pins) {
0787         hwrm_req_drop(bp, req);
0788         return -EOPNOTSUPP;
0789     }
0790 
0791     ptp_info = &ptp->ptp_info;
0792     pps_info = &ptp->pps_info;
0793     pps_info->num_pins = resp->num_pins;
0794     ptp_info->n_pins = pps_info->num_pins;
0795     ptp_info->pin_config = kcalloc(ptp_info->n_pins,
0796                        sizeof(*ptp_info->pin_config),
0797                        GFP_KERNEL);
0798     if (!ptp_info->pin_config) {
0799         hwrm_req_drop(bp, req);
0800         return -ENOMEM;
0801     }
0802 
0803     /* Report the TSIO capability to kernel */
0804     pin_usg = &resp->pin0_usage;
0805     for (i = 0; i < pps_info->num_pins; i++, pin_usg++) {
0806         snprintf(ptp_info->pin_config[i].name,
0807              sizeof(ptp_info->pin_config[i].name), "bnxt_pps%d", i);
0808         ptp_info->pin_config[i].index = i;
0809         ptp_info->pin_config[i].chan = i;
0810         if (*pin_usg == BNXT_PPS_PIN_PPS_IN)
0811             ptp_info->pin_config[i].func = PTP_PF_EXTTS;
0812         else if (*pin_usg == BNXT_PPS_PIN_PPS_OUT)
0813             ptp_info->pin_config[i].func = PTP_PF_PEROUT;
0814         else
0815             ptp_info->pin_config[i].func = PTP_PF_NONE;
0816 
0817         pps_info->pins[i].usage = *pin_usg;
0818     }
0819     hwrm_req_drop(bp, req);
0820 
0821     /* Only 1 each of ext_ts and per_out pins is available in HW */
0822     ptp_info->n_ext_ts = 1;
0823     ptp_info->n_per_out = 1;
0824     ptp_info->pps = 1;
0825     ptp_info->verify = bnxt_ptp_verify;
0826 
0827     return 0;
0828 }
0829 
0830 static bool bnxt_pps_config_ok(struct bnxt *bp)
0831 {
0832     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0833 
0834     return !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) == !ptp->ptp_info.pin_config;
0835 }
0836 
0837 static void bnxt_ptp_timecounter_init(struct bnxt *bp, bool init_tc)
0838 {
0839     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0840 
0841     if (!ptp->ptp_clock) {
0842         memset(&ptp->cc, 0, sizeof(ptp->cc));
0843         ptp->cc.read = bnxt_cc_read;
0844         ptp->cc.mask = CYCLECOUNTER_MASK(48);
0845         ptp->cc.shift = 0;
0846         ptp->cc.mult = 1;
0847         ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD;
0848     }
0849     if (init_tc)
0850         timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real()));
0851 }
0852 
0853 /* Caller holds ptp_lock */
0854 void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns)
0855 {
0856     timecounter_init(&ptp->tc, &ptp->cc, ns);
0857     /* For RTC, cycle_last must be in sync with the timecounter value. */
0858     ptp->tc.cycle_last = ns & ptp->cc.mask;
0859 }
0860 
0861 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
0862 {
0863     struct timespec64 tsp;
0864     u64 ns;
0865     int rc;
0866 
0867     if (!bp->ptp_cfg || !(bp->fw_cap & BNXT_FW_CAP_PTP_RTC))
0868         return -ENODEV;
0869 
0870     if (!phc_cfg) {
0871         ktime_get_real_ts64(&tsp);
0872         ns = timespec64_to_ns(&tsp);
0873         rc = bnxt_ptp_cfg_settime(bp, ns);
0874         if (rc)
0875             return rc;
0876     } else {
0877         rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, &ns);
0878         if (rc)
0879             return rc;
0880     }
0881     spin_lock_bh(&bp->ptp_cfg->ptp_lock);
0882     bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns);
0883     spin_unlock_bh(&bp->ptp_cfg->ptp_lock);
0884 
0885     return 0;
0886 }
0887 
0888 static void bnxt_ptp_free(struct bnxt *bp)
0889 {
0890     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0891 
0892     if (ptp->ptp_clock) {
0893         ptp_clock_unregister(ptp->ptp_clock);
0894         ptp->ptp_clock = NULL;
0895         kfree(ptp->ptp_info.pin_config);
0896         ptp->ptp_info.pin_config = NULL;
0897     }
0898 }
0899 
0900 int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
0901 {
0902     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0903     int rc;
0904 
0905     if (!ptp)
0906         return 0;
0907 
0908     rc = bnxt_map_ptp_regs(bp);
0909     if (rc)
0910         return rc;
0911 
0912     if (ptp->ptp_clock && bnxt_pps_config_ok(bp))
0913         return 0;
0914 
0915     bnxt_ptp_free(bp);
0916 
0917     atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
0918     spin_lock_init(&ptp->ptp_lock);
0919 
0920     if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) {
0921         bnxt_ptp_timecounter_init(bp, false);
0922         rc = bnxt_ptp_init_rtc(bp, phc_cfg);
0923         if (rc)
0924             goto out;
0925     } else {
0926         bnxt_ptp_timecounter_init(bp, true);
0927     }
0928 
0929     ptp->ptp_info = bnxt_ptp_caps;
0930     if ((bp->fw_cap & BNXT_FW_CAP_PTP_PPS)) {
0931         if (bnxt_ptp_pps_init(bp))
0932             netdev_err(bp->dev, "1pps not initialized, continuing without 1pps support\n");
0933     }
0934     ptp->ptp_clock = ptp_clock_register(&ptp->ptp_info, &bp->pdev->dev);
0935     if (IS_ERR(ptp->ptp_clock)) {
0936         int err = PTR_ERR(ptp->ptp_clock);
0937 
0938         ptp->ptp_clock = NULL;
0939         rc = err;
0940         goto out;
0941     }
0942     if (bp->flags & BNXT_FLAG_CHIP_P5) {
0943         spin_lock_bh(&ptp->ptp_lock);
0944         bnxt_refclk_read(bp, NULL, &ptp->current_time);
0945         WRITE_ONCE(ptp->old_time, ptp->current_time);
0946         spin_unlock_bh(&ptp->ptp_lock);
0947         ptp_schedule_worker(ptp->ptp_clock, 0);
0948     }
0949     return 0;
0950 
0951 out:
0952     bnxt_ptp_free(bp);
0953     bnxt_unmap_ptp_regs(bp);
0954     return rc;
0955 }
0956 
0957 void bnxt_ptp_clear(struct bnxt *bp)
0958 {
0959     struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
0960 
0961     if (!ptp)
0962         return;
0963 
0964     if (ptp->ptp_clock)
0965         ptp_clock_unregister(ptp->ptp_clock);
0966 
0967     ptp->ptp_clock = NULL;
0968     kfree(ptp->ptp_info.pin_config);
0969     ptp->ptp_info.pin_config = NULL;
0970 
0971     if (ptp->tx_skb) {
0972         dev_kfree_skb_any(ptp->tx_skb);
0973         ptp->tx_skb = NULL;
0974     }
0975     bnxt_unmap_ptp_regs(bp);
0976 }