bnxt_en: Update firmware interface to 1.10.2.95
[linux-2.6-block.git] / drivers / net / ethernet / broadcom / bnxt / bnxt_ptp.c
CommitLineData
118612d5
MC
1/* Broadcom NetXtreme-C/E network driver.
2 *
3 * Copyright (c) 2021 Broadcom Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation.
8 */
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/pci.h>
12#include <linux/netdevice.h>
13#include <linux/etherdevice.h>
118612d5 14#include <linux/net_tstamp.h>
118612d5 15#include <linux/timekeeping.h>
83bb623c 16#include <linux/ptp_classify.h>
118612d5
MC
17#include "bnxt_hsi.h"
18#include "bnxt.h"
3c8c20db 19#include "bnxt_hwrm.h"
118612d5
MC
20#include "bnxt_ptp.h"
21
24ac1ecd
PC
22static int bnxt_ptp_cfg_settime(struct bnxt *bp, u64 time)
23{
24 struct hwrm_func_ptp_cfg_input *req;
25 int rc;
26
27 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
28 if (rc)
29 return rc;
30
31 req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_SET_TIME);
32 req->ptp_set_time = cpu_to_le64(time);
33 return hwrm_req_send(bp, req);
34}
35
9e266807 36int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off)
83bb623c
PC
37{
38 unsigned int ptp_class;
39 struct ptp_header *hdr;
40
41 ptp_class = ptp_classify_raw(skb);
42
43 switch (ptp_class & PTP_CLASS_VMASK) {
44 case PTP_CLASS_V1:
45 case PTP_CLASS_V2:
46 hdr = ptp_parse_header(skb, ptp_class);
47 if (!hdr)
48 return -EINVAL;
49
9e266807 50 *hdr_off = (u8 *)hdr - skb->data;
83bb623c
PC
51 *seq_id = ntohs(hdr->sequence_id);
52 return 0;
53 default:
54 return -ERANGE;
55 }
56}
57
118612d5
MC
58static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
59 const struct timespec64 *ts)
60{
61 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
62 ptp_info);
63 u64 ns = timespec64_to_ns(ts);
64
24ac1ecd
PC
65 if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
66 return bnxt_ptp_cfg_settime(ptp->bp, ns);
67
118612d5
MC
68 spin_lock_bh(&ptp->ptp_lock);
69 timecounter_init(&ptp->tc, &ptp->cc, ns);
70 spin_unlock_bh(&ptp->ptp_lock);
71 return 0;
72}
73
74/* Caller holds ptp_lock */
30e96f48
MC
75static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts,
76 u64 *ns)
118612d5
MC
77{
78 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
30e96f48
MC
79
80 if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
81 return -EIO;
118612d5
MC
82
83 ptp_read_system_prets(sts);
30e96f48 84 *ns = readl(bp->bar0 + ptp->refclk_mapped_regs[0]);
118612d5 85 ptp_read_system_postts(sts);
30e96f48
MC
86 *ns |= (u64)readl(bp->bar0 + ptp->refclk_mapped_regs[1]) << 32;
87 return 0;
118612d5
MC
88}
89
390862f4
PC
90static void bnxt_ptp_get_current_time(struct bnxt *bp)
91{
92 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
93
94 if (!ptp)
95 return;
96 spin_lock_bh(&ptp->ptp_lock);
97 WRITE_ONCE(ptp->old_time, ptp->current_time);
30e96f48 98 bnxt_refclk_read(bp, NULL, &ptp->current_time);
390862f4
PC
99 spin_unlock_bh(&ptp->ptp_lock);
100}
101
83bb623c
PC
102static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts)
103{
bbf33d1d
EP
104 struct hwrm_port_ts_query_output *resp;
105 struct hwrm_port_ts_query_input *req;
83bb623c
PC
106 int rc;
107
bbf33d1d
EP
108 rc = hwrm_req_init(bp, req, HWRM_PORT_TS_QUERY);
109 if (rc)
110 return rc;
111
112 req->flags = cpu_to_le32(flags);
83bb623c
PC
113 if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) ==
114 PORT_TS_QUERY_REQ_FLAGS_PATH_TX) {
bbf33d1d
EP
115 req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES);
116 req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid);
117 req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off);
118 req->ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT);
83bb623c 119 }
bbf33d1d
EP
120 resp = hwrm_req_hold(bp, req);
121
122 rc = hwrm_req_send(bp, req);
83bb623c
PC
123 if (!rc)
124 *ts = le64_to_cpu(resp->ptp_msg_ts);
bbf33d1d 125 hwrm_req_drop(bp, req);
83bb623c
PC
126 return rc;
127}
128
118612d5
MC
129static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info,
130 struct timespec64 *ts,
131 struct ptp_system_timestamp *sts)
132{
133 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
134 ptp_info);
135 u64 ns, cycles;
30e96f48 136 int rc;
118612d5
MC
137
138 spin_lock_bh(&ptp->ptp_lock);
30e96f48
MC
139 rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
140 if (rc) {
141 spin_unlock_bh(&ptp->ptp_lock);
142 return rc;
143 }
118612d5
MC
144 ns = timecounter_cyc2time(&ptp->tc, cycles);
145 spin_unlock_bh(&ptp->ptp_lock);
146 *ts = ns_to_timespec64(ns);
147
148 return 0;
149}
150
e7b0afb6
PC
151/* Caller holds ptp_lock */
152void bnxt_ptp_update_current_time(struct bnxt *bp)
153{
154 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
155
156 bnxt_refclk_read(ptp->bp, NULL, &ptp->current_time);
157 WRITE_ONCE(ptp->old_time, ptp->current_time);
158}
159
160static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
161{
162 struct hwrm_port_mac_cfg_input *req;
163 int rc;
164
165 rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG);
166 if (rc)
167 return rc;
168
169 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_ADJ_PHASE);
170 req->ptp_adj_phase = cpu_to_le64(delta);
171
172 rc = hwrm_req_send(ptp->bp, req);
173 if (rc) {
174 netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc);
175 } else {
176 spin_lock_bh(&ptp->ptp_lock);
177 bnxt_ptp_update_current_time(ptp->bp);
178 spin_unlock_bh(&ptp->ptp_lock);
179 }
180
181 return rc;
182}
183
118612d5
MC
184static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
185{
186 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
187 ptp_info);
188
e7b0afb6
PC
189 if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
190 return bnxt_ptp_adjphc(ptp, delta);
191
118612d5
MC
192 spin_lock_bh(&ptp->ptp_lock);
193 timecounter_adjtime(&ptp->tc, delta);
194 spin_unlock_bh(&ptp->ptp_lock);
195 return 0;
196}
197
198static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
199{
200 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
201 ptp_info);
bbf33d1d 202 struct hwrm_port_mac_cfg_input *req;
118612d5
MC
203 struct bnxt *bp = ptp->bp;
204 int rc;
205
bbf33d1d
EP
206 rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
207 if (rc)
208 return rc;
209
210 req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
211 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
212 rc = hwrm_req_send(ptp->bp, req);
118612d5
MC
213 if (rc)
214 netdev_err(ptp->bp->dev,
215 "ptp adjfreq failed. rc = %d\n", rc);
216 return rc;
217}
218
099fdeda
PC
219void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
220{
221 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
222 struct ptp_clock_event event;
223 u64 ns, pps_ts;
224
225 pps_ts = EVENT_PPS_TS(data2, data1);
226 spin_lock_bh(&ptp->ptp_lock);
227 ns = timecounter_cyc2time(&ptp->tc, pps_ts);
228 spin_unlock_bh(&ptp->ptp_lock);
229
230 switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) {
231 case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL:
232 event.pps_times.ts_real = ns_to_timespec64(ns);
233 event.type = PTP_CLOCK_PPSUSR;
234 event.index = EVENT_DATA2_PPS_PIN_NUM(data2);
235 break;
236 case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_EXTERNAL:
237 event.timestamp = ns;
238 event.type = PTP_CLOCK_EXTTS;
239 event.index = EVENT_DATA2_PPS_PIN_NUM(data2);
240 break;
241 }
242
243 ptp_clock_event(bp->ptp_cfg->ptp_clock, &event);
244}
245
9e518f25
PC
246static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage)
247{
bbf33d1d 248 struct hwrm_func_ptp_pin_cfg_input *req;
9e518f25
PC
249 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
250 u8 state = usage != BNXT_PPS_PIN_NONE;
251 u8 *pin_state, *pin_usg;
252 u32 enables;
253 int rc;
254
255 if (!TSIO_PIN_VALID(pin)) {
256 netdev_err(ptp->bp->dev, "1PPS: Invalid pin. Check pin-function configuration\n");
257 return -EOPNOTSUPP;
258 }
259
bbf33d1d
EP
260 rc = hwrm_req_init(ptp->bp, req, HWRM_FUNC_PTP_PIN_CFG);
261 if (rc)
262 return rc;
263
9e518f25
PC
264 enables = (FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_STATE |
265 FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_USAGE) << (pin * 2);
bbf33d1d 266 req->enables = cpu_to_le32(enables);
9e518f25 267
bbf33d1d
EP
268 pin_state = &req->pin0_state;
269 pin_usg = &req->pin0_usage;
9e518f25
PC
270
271 *(pin_state + (pin * 2)) = state;
272 *(pin_usg + (pin * 2)) = usage;
273
bbf33d1d 274 rc = hwrm_req_send(ptp->bp, req);
9e518f25
PC
275 if (rc)
276 return rc;
277
278 ptp->pps_info.pins[pin].usage = usage;
279 ptp->pps_info.pins[pin].state = state;
280
281 return 0;
282}
283
284static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event)
285{
bbf33d1d
EP
286 struct hwrm_func_ptp_cfg_input *req;
287 int rc;
288
289 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
290 if (rc)
291 return rc;
9e518f25 292
bbf33d1d
EP
293 req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_PPS_EVENT);
294 req->ptp_pps_event = event;
295 return hwrm_req_send(bp, req);
9e518f25
PC
296}
297
298void bnxt_ptp_reapply_pps(struct bnxt *bp)
299{
300 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
301 struct bnxt_pps *pps;
302 u32 pin = 0;
303 int rc;
304
305 if (!ptp || !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) ||
306 !(ptp->ptp_info.pin_config))
307 return;
308 pps = &ptp->pps_info;
309 for (pin = 0; pin < BNXT_MAX_TSIO_PINS; pin++) {
310 if (pps->pins[pin].state) {
311 rc = bnxt_ptp_cfg_pin(bp, pin, pps->pins[pin].usage);
312 if (!rc && pps->pins[pin].event)
313 rc = bnxt_ptp_cfg_event(bp,
314 pps->pins[pin].event);
315 if (rc)
316 netdev_err(bp->dev, "1PPS: Failed to configure pin%d\n",
317 pin);
318 }
319 }
320}
321
322static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns,
323 u64 *cycles_delta)
324{
325 u64 cycles_now;
326 u64 nsec_now, nsec_delta;
327 int rc;
328
329 spin_lock_bh(&ptp->ptp_lock);
330 rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now);
331 if (rc) {
332 spin_unlock_bh(&ptp->ptp_lock);
333 return rc;
334 }
335 nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now);
336 spin_unlock_bh(&ptp->ptp_lock);
337
338 nsec_delta = target_ns - nsec_now;
339 *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult);
340 return 0;
341}
342
343static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp,
344 struct ptp_clock_request *rq)
345{
bbf33d1d 346 struct hwrm_func_ptp_cfg_input *req;
9e518f25
PC
347 struct bnxt *bp = ptp->bp;
348 struct timespec64 ts;
349 u64 target_ns, delta;
350 u16 enables;
351 int rc;
352
353 ts.tv_sec = rq->perout.start.sec;
354 ts.tv_nsec = rq->perout.start.nsec;
355 target_ns = timespec64_to_ns(&ts);
356
357 rc = bnxt_get_target_cycles(ptp, target_ns, &delta);
358 if (rc)
359 return rc;
360
bbf33d1d
EP
361 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
362 if (rc)
363 return rc;
9e518f25
PC
364
365 enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD |
366 FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP |
367 FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE;
bbf33d1d
EP
368 req->enables = cpu_to_le16(enables);
369 req->ptp_pps_event = 0;
370 req->ptp_freq_adj_dll_source = 0;
371 req->ptp_freq_adj_dll_phase = 0;
372 req->ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC);
373 req->ptp_freq_adj_ext_up = 0;
374 req->ptp_freq_adj_ext_phase_lower = cpu_to_le32(delta);
375
376 return hwrm_req_send(bp, req);
9e518f25
PC
377}
378
379static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info,
118612d5
MC
380 struct ptp_clock_request *rq, int on)
381{
9e518f25
PC
382 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
383 ptp_info);
384 struct bnxt *bp = ptp->bp;
dcf50006 385 int pin_id;
9e518f25
PC
386 int rc;
387
388 switch (rq->type) {
389 case PTP_CLK_REQ_EXTTS:
390 /* Configure an External PPS IN */
391 pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS,
392 rq->extts.index);
dcf50006
DLM
393 if (!TSIO_PIN_VALID(pin_id))
394 return -EOPNOTSUPP;
9e518f25
PC
395 if (!on)
396 break;
397 rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_IN);
398 if (rc)
399 return rc;
400 rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_EXTERNAL);
401 if (!rc)
402 ptp->pps_info.pins[pin_id].event = BNXT_PPS_EVENT_EXTERNAL;
403 return rc;
404 case PTP_CLK_REQ_PEROUT:
405 /* Configure a Periodic PPS OUT */
406 pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT,
407 rq->perout.index);
dcf50006
DLM
408 if (!TSIO_PIN_VALID(pin_id))
409 return -EOPNOTSUPP;
9e518f25
PC
410 if (!on)
411 break;
412
413 rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_OUT);
414 if (!rc)
415 rc = bnxt_ptp_perout_cfg(ptp, rq);
416
417 return rc;
418 case PTP_CLK_REQ_PPS:
419 /* Configure PHC PPS IN */
420 rc = bnxt_ptp_cfg_pin(bp, 0, BNXT_PPS_PIN_PPS_IN);
421 if (rc)
422 return rc;
423 rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_INTERNAL);
424 if (!rc)
425 ptp->pps_info.pins[0].event = BNXT_PPS_EVENT_INTERNAL;
426 return rc;
427 default:
428 netdev_err(ptp->bp->dev, "Unrecognized PIN function\n");
429 return -EOPNOTSUPP;
430 }
431
432 return bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_NONE);
118612d5
MC
433}
434
435static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
436{
118612d5 437 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
bbf33d1d 438 struct hwrm_port_mac_cfg_input *req;
118612d5 439 u32 flags = 0;
bbf33d1d
EP
440 int rc;
441
442 rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
443 if (rc)
444 return rc;
118612d5 445
118612d5
MC
446 if (ptp->rx_filter)
447 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
448 else
449 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE;
450 if (ptp->tx_tstamp_en)
451 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
452 else
453 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
bbf33d1d
EP
454 req->flags = cpu_to_le32(flags);
455 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
456 req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
118612d5 457
bbf33d1d 458 return hwrm_req_send(bp, req);
118612d5
MC
459}
460
461int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
462{
463 struct bnxt *bp = netdev_priv(dev);
464 struct hwtstamp_config stmpconf;
465 struct bnxt_ptp_cfg *ptp;
466 u16 old_rxctl;
467 int old_rx_filter, rc;
468 u8 old_tx_tstamp_en;
469
470 ptp = bp->ptp_cfg;
471 if (!ptp)
472 return -EOPNOTSUPP;
473
474 if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf)))
475 return -EFAULT;
476
118612d5
MC
477 if (stmpconf.tx_type != HWTSTAMP_TX_ON &&
478 stmpconf.tx_type != HWTSTAMP_TX_OFF)
479 return -ERANGE;
480
481 old_rx_filter = ptp->rx_filter;
482 old_rxctl = ptp->rxctl;
483 old_tx_tstamp_en = ptp->tx_tstamp_en;
484 switch (stmpconf.rx_filter) {
485 case HWTSTAMP_FILTER_NONE:
486 ptp->rxctl = 0;
487 ptp->rx_filter = HWTSTAMP_FILTER_NONE;
488 break;
489 case HWTSTAMP_FILTER_PTP_V2_EVENT:
490 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
491 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
492 ptp->rxctl = BNXT_PTP_MSG_EVENTS;
493 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
494 break;
495 case HWTSTAMP_FILTER_PTP_V2_SYNC:
496 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
497 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
498 ptp->rxctl = BNXT_PTP_MSG_SYNC;
499 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC;
500 break;
501 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
502 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
503 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
504 ptp->rxctl = BNXT_PTP_MSG_DELAY_REQ;
505 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
506 break;
507 default:
508 return -ERANGE;
509 }
510
511 if (stmpconf.tx_type == HWTSTAMP_TX_ON)
512 ptp->tx_tstamp_en = 1;
513 else
514 ptp->tx_tstamp_en = 0;
515
516 rc = bnxt_hwrm_ptp_cfg(bp);
517 if (rc)
518 goto ts_set_err;
519
520 stmpconf.rx_filter = ptp->rx_filter;
521 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
522 -EFAULT : 0;
523
524ts_set_err:
525 ptp->rx_filter = old_rx_filter;
526 ptp->rxctl = old_rxctl;
527 ptp->tx_tstamp_en = old_tx_tstamp_en;
528 return rc;
529}
530
531int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
532{
533 struct bnxt *bp = netdev_priv(dev);
534 struct hwtstamp_config stmpconf;
535 struct bnxt_ptp_cfg *ptp;
536
537 ptp = bp->ptp_cfg;
538 if (!ptp)
539 return -EOPNOTSUPP;
540
541 stmpconf.flags = 0;
542 stmpconf.tx_type = ptp->tx_tstamp_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
543
544 stmpconf.rx_filter = ptp->rx_filter;
545 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
546 -EFAULT : 0;
547}
548
549static int bnxt_map_regs(struct bnxt *bp, u32 *reg_arr, int count, int reg_win)
550{
551 u32 reg_base = *reg_arr & BNXT_GRC_BASE_MASK;
552 u32 win_off;
553 int i;
554
555 for (i = 0; i < count; i++) {
556 if ((reg_arr[i] & BNXT_GRC_BASE_MASK) != reg_base)
557 return -ERANGE;
558 }
559 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4;
560 writel(reg_base, bp->bar0 + win_off);
561 return 0;
562}
563
564static int bnxt_map_ptp_regs(struct bnxt *bp)
565{
566 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
567 u32 *reg_arr;
568 int rc, i;
569
570 reg_arr = ptp->refclk_regs;
571 if (bp->flags & BNXT_FLAG_CHIP_P5) {
572 rc = bnxt_map_regs(bp, reg_arr, 2, BNXT_PTP_GRC_WIN);
573 if (rc)
574 return rc;
575 for (i = 0; i < 2; i++)
576 ptp->refclk_mapped_regs[i] = BNXT_PTP_GRC_WIN_BASE +
577 (ptp->refclk_regs[i] & BNXT_GRC_OFFSET_MASK);
578 return 0;
579 }
580 return -ENODEV;
581}
582
583static void bnxt_unmap_ptp_regs(struct bnxt *bp)
584{
585 writel(0, bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT +
586 (BNXT_PTP_GRC_WIN - 1) * 4);
587}
588
589static u64 bnxt_cc_read(const struct cyclecounter *cc)
590{
591 struct bnxt_ptp_cfg *ptp = container_of(cc, struct bnxt_ptp_cfg, cc);
30e96f48 592 u64 ns = 0;
118612d5 593
30e96f48
MC
594 bnxt_refclk_read(ptp->bp, NULL, &ns);
595 return ns;
118612d5
MC
596}
597
83bb623c
PC
598static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
599{
600 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
601 struct skb_shared_hwtstamps timestamp;
602 u64 ts = 0, ns = 0;
603 int rc;
604
605 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts);
606 if (!rc) {
607 memset(&timestamp, 0, sizeof(timestamp));
608 spin_lock_bh(&ptp->ptp_lock);
609 ns = timecounter_cyc2time(&ptp->tc, ts);
610 spin_unlock_bh(&ptp->ptp_lock);
611 timestamp.hwtstamp = ns_to_ktime(ns);
612 skb_tstamp_tx(ptp->tx_skb, &timestamp);
613 } else {
614 netdev_err(bp->dev, "TS query for TX timer failed rc = %x\n",
615 rc);
616 }
617
618 dev_kfree_skb_any(ptp->tx_skb);
619 ptp->tx_skb = NULL;
620 atomic_inc(&ptp->tx_avail);
621}
622
390862f4
PC
623static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
624{
625 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
626 ptp_info);
83bb623c 627 unsigned long now = jiffies;
390862f4
PC
628 struct bnxt *bp = ptp->bp;
629
83bb623c
PC
630 if (ptp->tx_skb)
631 bnxt_stamp_tx_skb(bp, ptp->tx_skb);
632
633 if (!time_after_eq(now, ptp->next_period))
634 return ptp->next_period - now;
635
390862f4 636 bnxt_ptp_get_current_time(bp);
83bb623c 637 ptp->next_period = now + HZ;
89bc7f45
MC
638 if (time_after_eq(now, ptp->next_overflow_check)) {
639 spin_lock_bh(&ptp->ptp_lock);
640 timecounter_read(&ptp->tc);
641 spin_unlock_bh(&ptp->ptp_lock);
642 ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
643 }
390862f4
PC
644 return HZ;
645}
646
83bb623c
PC
647int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb)
648{
649 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
650
651 if (ptp->tx_skb) {
652 netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n");
653 return -EBUSY;
654 }
655 ptp->tx_skb = skb;
656 ptp_schedule_worker(ptp->ptp_clock, 0);
657 return 0;
658}
659
7f5515d1
PC
660int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts)
661{
662 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
663 u64 time;
664
665 if (!ptp)
666 return -ENODEV;
667
668 BNXT_READ_TIME64(ptp, time, ptp->old_time);
669 *ts = (time & BNXT_HI_TIMER_MASK) | pkt_ts;
670 if (pkt_ts < (time & BNXT_LO_TIMER_MASK))
671 *ts += BNXT_LO_TIMER_MASK + 1;
672
673 return 0;
674}
675
118612d5
MC
676static const struct ptp_clock_info bnxt_ptp_caps = {
677 .owner = THIS_MODULE,
678 .name = "bnxt clock",
679 .max_adj = BNXT_MAX_PHC_DRIFT,
680 .n_alarm = 0,
681 .n_ext_ts = 0,
682 .n_per_out = 0,
683 .n_pins = 0,
684 .pps = 0,
685 .adjfreq = bnxt_ptp_adjfreq,
686 .adjtime = bnxt_ptp_adjtime,
390862f4 687 .do_aux_work = bnxt_ptp_ts_aux_work,
118612d5
MC
688 .gettimex64 = bnxt_ptp_gettimex,
689 .settime64 = bnxt_ptp_settime,
690 .enable = bnxt_ptp_enable,
691};
692
caf3eedb
PC
693static int bnxt_ptp_verify(struct ptp_clock_info *ptp_info, unsigned int pin,
694 enum ptp_pin_function func, unsigned int chan)
695{
696 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
697 ptp_info);
698 /* Allow only PPS pin function configuration */
699 if (ptp->pps_info.pins[pin].usage <= BNXT_PPS_PIN_PPS_OUT &&
700 func != PTP_PF_PHYSYNC)
701 return 0;
702 else
703 return -EOPNOTSUPP;
704}
705
caf3eedb
PC
706static int bnxt_ptp_pps_init(struct bnxt *bp)
707{
bbf33d1d
EP
708 struct hwrm_func_ptp_pin_qcfg_output *resp;
709 struct hwrm_func_ptp_pin_qcfg_input *req;
caf3eedb
PC
710 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
711 struct ptp_clock_info *ptp_info;
712 struct bnxt_pps *pps_info;
713 u8 *pin_usg;
714 u32 i, rc;
715
716 /* Query current/default PIN CFG */
bbf33d1d
EP
717 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_PIN_QCFG);
718 if (rc)
719 return rc;
caf3eedb 720
bbf33d1d
EP
721 resp = hwrm_req_hold(bp, req);
722 rc = hwrm_req_send(bp, req);
723 if (rc || !resp->num_pins) {
724 hwrm_req_drop(bp, req);
caf3eedb 725 return -EOPNOTSUPP;
bbf33d1d 726 }
caf3eedb
PC
727
728 ptp_info = &ptp->ptp_info;
729 pps_info = &ptp->pps_info;
730 pps_info->num_pins = resp->num_pins;
731 ptp_info->n_pins = pps_info->num_pins;
732 ptp_info->pin_config = kcalloc(ptp_info->n_pins,
733 sizeof(*ptp_info->pin_config),
734 GFP_KERNEL);
bbf33d1d
EP
735 if (!ptp_info->pin_config) {
736 hwrm_req_drop(bp, req);
caf3eedb 737 return -ENOMEM;
bbf33d1d 738 }
caf3eedb
PC
739
740 /* Report the TSIO capability to kernel */
741 pin_usg = &resp->pin0_usage;
742 for (i = 0; i < pps_info->num_pins; i++, pin_usg++) {
743 snprintf(ptp_info->pin_config[i].name,
744 sizeof(ptp_info->pin_config[i].name), "bnxt_pps%d", i);
745 ptp_info->pin_config[i].index = i;
746 ptp_info->pin_config[i].chan = i;
747 if (*pin_usg == BNXT_PPS_PIN_PPS_IN)
748 ptp_info->pin_config[i].func = PTP_PF_EXTTS;
749 else if (*pin_usg == BNXT_PPS_PIN_PPS_OUT)
750 ptp_info->pin_config[i].func = PTP_PF_PEROUT;
751 else
752 ptp_info->pin_config[i].func = PTP_PF_NONE;
753
754 pps_info->pins[i].usage = *pin_usg;
755 }
bbf33d1d 756 hwrm_req_drop(bp, req);
caf3eedb
PC
757
758 /* Only 1 each of ext_ts and per_out pins is available in HW */
759 ptp_info->n_ext_ts = 1;
760 ptp_info->n_per_out = 1;
761 ptp_info->pps = 1;
762 ptp_info->verify = bnxt_ptp_verify;
763
764 return 0;
765}
766
767static bool bnxt_pps_config_ok(struct bnxt *bp)
768{
769 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
770
771 return !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) == !ptp->ptp_info.pin_config;
772}
773
740c342e
PC
774static void bnxt_ptp_timecounter_init(struct bnxt *bp, bool init_tc)
775{
776 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
777
778 if (!ptp->ptp_clock) {
779 memset(&ptp->cc, 0, sizeof(ptp->cc));
780 ptp->cc.read = bnxt_cc_read;
781 ptp->cc.mask = CYCLECOUNTER_MASK(48);
782 ptp->cc.shift = 0;
783 ptp->cc.mult = 1;
784 ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD;
785 }
786 if (init_tc)
787 timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real()));
788}
789
24ac1ecd
PC
790/* Caller holds ptp_lock */
791void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns)
792{
793 timecounter_init(&ptp->tc, &ptp->cc, ns);
794 /* For RTC, cycle_last must be in sync with the timecounter value. */
795 ptp->tc.cycle_last = ns & ptp->cc.mask;
796}
797
798int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
799{
800 struct timespec64 tsp;
801 u64 ns;
802 int rc;
803
804 if (!bp->ptp_cfg || !(bp->fw_cap & BNXT_FW_CAP_PTP_RTC))
805 return -ENODEV;
806
807 if (!phc_cfg) {
808 ktime_get_real_ts64(&tsp);
809 ns = timespec64_to_ns(&tsp);
810 rc = bnxt_ptp_cfg_settime(bp, ns);
811 if (rc)
812 return rc;
813 } else {
814 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, &ns);
815 if (rc)
816 return rc;
817 }
818 spin_lock_bh(&bp->ptp_cfg->ptp_lock);
819 bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns);
820 spin_unlock_bh(&bp->ptp_cfg->ptp_lock);
821
822 return 0;
823}
824
740c342e
PC
825static void bnxt_ptp_free(struct bnxt *bp)
826{
827 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
828
829 if (ptp->ptp_clock) {
830 ptp_clock_unregister(ptp->ptp_clock);
831 ptp->ptp_clock = NULL;
832 kfree(ptp->ptp_info.pin_config);
833 ptp->ptp_info.pin_config = NULL;
834 }
835}
836
24ac1ecd 837int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
118612d5
MC
838{
839 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
840 int rc;
841
842 if (!ptp)
843 return 0;
844
845 rc = bnxt_map_ptp_regs(bp);
846 if (rc)
847 return rc;
848
caf3eedb 849 if (ptp->ptp_clock && bnxt_pps_config_ok(bp))
a521c8a0
MC
850 return 0;
851
740c342e
PC
852 bnxt_ptp_free(bp);
853
118612d5
MC
854 atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
855 spin_lock_init(&ptp->ptp_lock);
856
2b156fb5
MC
857 if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) {
858 bnxt_ptp_timecounter_init(bp, false);
859 rc = bnxt_ptp_init_rtc(bp, phc_cfg);
860 if (rc)
861 goto out;
862 } else {
24ac1ecd 863 bnxt_ptp_timecounter_init(bp, true);
2b156fb5 864 }
118612d5
MC
865
866 ptp->ptp_info = bnxt_ptp_caps;
caf3eedb
PC
867 if ((bp->fw_cap & BNXT_FW_CAP_PTP_PPS)) {
868 if (bnxt_ptp_pps_init(bp))
869 netdev_err(bp->dev, "1pps not initialized, continuing without 1pps support\n");
870 }
118612d5
MC
871 ptp->ptp_clock = ptp_clock_register(&ptp->ptp_info, &bp->pdev->dev);
872 if (IS_ERR(ptp->ptp_clock)) {
873 int err = PTR_ERR(ptp->ptp_clock);
874
875 ptp->ptp_clock = NULL;
24ac1ecd
PC
876 rc = err;
877 goto out;
118612d5 878 }
d7859afb
MC
879 if (bp->flags & BNXT_FLAG_CHIP_P5) {
880 spin_lock_bh(&ptp->ptp_lock);
30e96f48 881 bnxt_refclk_read(bp, NULL, &ptp->current_time);
d7859afb
MC
882 WRITE_ONCE(ptp->old_time, ptp->current_time);
883 spin_unlock_bh(&ptp->ptp_lock);
884 ptp_schedule_worker(ptp->ptp_clock, 0);
885 }
118612d5 886 return 0;
24ac1ecd
PC
887
888out:
889 bnxt_ptp_free(bp);
890 bnxt_unmap_ptp_regs(bp);
891 return rc;
118612d5
MC
892}
893
894void bnxt_ptp_clear(struct bnxt *bp)
895{
896 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
897
898 if (!ptp)
899 return;
900
901 if (ptp->ptp_clock)
902 ptp_clock_unregister(ptp->ptp_clock);
903
904 ptp->ptp_clock = NULL;
caf3eedb
PC
905 kfree(ptp->ptp_info.pin_config);
906 ptp->ptp_info.pin_config = NULL;
907
83bb623c
PC
908 if (ptp->tx_skb) {
909 dev_kfree_skb_any(ptp->tx_skb);
910 ptp->tx_skb = NULL;
911 }
118612d5
MC
912 bnxt_unmap_ptp_regs(bp);
913}