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> 14 #include <linux/net_tstamp.h> 15 #include <linux/timekeeping.h> 16 #include <linux/ptp_classify.h> 17 #include <linux/clocksource.h> 18 #include "bnxt_hsi.h" 19 #include "bnxt.h" 20 #include "bnxt_hwrm.h" 21 #include "bnxt_ptp.h" 22 23 static int bnxt_ptp_cfg_settime(struct bnxt *bp, u64 time) 24 { 25 struct hwrm_func_ptp_cfg_input *req; 26 int rc; 27 28 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG); 29 if (rc) 30 return rc; 31 32 req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_SET_TIME); 33 req->ptp_set_time = cpu_to_le64(time); 34 return hwrm_req_send(bp, req); 35 } 36 37 int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off) 38 { 39 unsigned int ptp_class; 40 struct ptp_header *hdr; 41 42 ptp_class = ptp_classify_raw(skb); 43 44 switch (ptp_class & PTP_CLASS_VMASK) { 45 case PTP_CLASS_V1: 46 case PTP_CLASS_V2: 47 hdr = ptp_parse_header(skb, ptp_class); 48 if (!hdr) 49 return -EINVAL; 50 51 *hdr_off = (u8 *)hdr - skb->data; 52 *seq_id = ntohs(hdr->sequence_id); 53 return 0; 54 default: 55 return -ERANGE; 56 } 57 } 58 59 static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, 60 const struct timespec64 *ts) 61 { 62 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 63 ptp_info); 64 u64 ns = timespec64_to_ns(ts); 65 unsigned long flags; 66 67 if (BNXT_PTP_USE_RTC(ptp->bp)) 68 return bnxt_ptp_cfg_settime(ptp->bp, ns); 69 70 write_seqlock_irqsave(&ptp->ptp_lock, flags); 71 timecounter_init(&ptp->tc, &ptp->cc, ns); 72 write_sequnlock_irqrestore(&ptp->ptp_lock, flags); 73 return 0; 74 } 75 76 static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts, 77 u64 *ns) 78 { 79 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 80 u32 high_before, high_now, low; 81 unsigned long flags; 82 83 /* We have to serialize reg access and FW reset */ 84 read_seqlock_excl_irqsave(&ptp->ptp_lock, flags); 85 if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { 86 read_sequnlock_excl_irqrestore(&ptp->ptp_lock, flags); 87 return -EIO; 88 } 89 90 high_before = readl(bp->bar0 + ptp->refclk_mapped_regs[1]); 91 ptp_read_system_prets(sts); 92 low = readl(bp->bar0 + ptp->refclk_mapped_regs[0]); 93 ptp_read_system_postts(sts); 94 high_now = readl(bp->bar0 + ptp->refclk_mapped_regs[1]); 95 if (high_now != high_before) { 96 ptp_read_system_prets(sts); 97 low = readl(bp->bar0 + ptp->refclk_mapped_regs[0]); 98 ptp_read_system_postts(sts); 99 } 100 read_sequnlock_excl_irqrestore(&ptp->ptp_lock, flags); 101 *ns = ((u64)high_now << 32) | low; 102 103 return 0; 104 } 105 106 static void bnxt_ptp_get_current_time(struct bnxt *bp) 107 { 108 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 109 110 if (!ptp) 111 return; 112 WRITE_ONCE(ptp->old_time, ptp->current_time >> BNXT_HI_TIMER_SHIFT); 113 bnxt_refclk_read(bp, NULL, &ptp->current_time); 114 } 115 116 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, 117 u32 txts_tmo, int slot) 118 { 119 struct hwrm_port_ts_query_output *resp; 120 struct hwrm_port_ts_query_input *req; 121 int rc; 122 123 rc = hwrm_req_init(bp, req, HWRM_PORT_TS_QUERY); 124 if (rc) 125 return rc; 126 127 req->flags = cpu_to_le32(flags); 128 if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) == 129 PORT_TS_QUERY_REQ_FLAGS_PATH_TX) { 130 struct bnxt_ptp_tx_req *txts_req = &bp->ptp_cfg->txts_req[slot]; 131 u32 tmo_us = txts_tmo * 1000; 132 133 req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES); 134 req->ptp_seq_id = cpu_to_le32(txts_req->tx_seqid); 135 req->ptp_hdr_offset = cpu_to_le16(txts_req->tx_hdr_off); 136 if (!tmo_us) 137 tmo_us = BNXT_PTP_QTS_TIMEOUT; 138 tmo_us = min(tmo_us, BNXT_PTP_QTS_MAX_TMO_US); 139 req->ts_req_timeout = cpu_to_le16(tmo_us); 140 } 141 resp = hwrm_req_hold(bp, req); 142 143 rc = hwrm_req_send_silent(bp, req); 144 if (!rc) 145 *ts = le64_to_cpu(resp->ptp_msg_ts); 146 hwrm_req_drop(bp, req); 147 return rc; 148 } 149 150 static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info, 151 struct timespec64 *ts, 152 struct ptp_system_timestamp *sts) 153 { 154 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 155 ptp_info); 156 u64 ns, cycles; 157 int rc; 158 159 rc = bnxt_refclk_read(ptp->bp, sts, &cycles); 160 if (rc) 161 return rc; 162 163 ns = bnxt_timecounter_cyc2time(ptp, cycles); 164 *ts = ns_to_timespec64(ns); 165 166 return 0; 167 } 168 169 void bnxt_ptp_update_current_time(struct bnxt *bp) 170 { 171 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 172 173 bnxt_refclk_read(ptp->bp, NULL, &ptp->current_time); 174 WRITE_ONCE(ptp->old_time, ptp->current_time >> BNXT_HI_TIMER_SHIFT); 175 } 176 177 static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) 178 { 179 struct hwrm_port_mac_cfg_input *req; 180 int rc; 181 182 rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); 183 if (rc) 184 return rc; 185 186 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_ADJ_PHASE); 187 req->ptp_adj_phase = cpu_to_le64(delta); 188 189 rc = hwrm_req_send(ptp->bp, req); 190 if (rc) { 191 netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); 192 } else { 193 bnxt_ptp_update_current_time(ptp->bp); 194 } 195 196 return rc; 197 } 198 199 static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 200 { 201 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 202 ptp_info); 203 unsigned long flags; 204 205 if (BNXT_PTP_USE_RTC(ptp->bp)) 206 return bnxt_ptp_adjphc(ptp, delta); 207 208 write_seqlock_irqsave(&ptp->ptp_lock, flags); 209 timecounter_adjtime(&ptp->tc, delta); 210 write_sequnlock_irqrestore(&ptp->ptp_lock, flags); 211 return 0; 212 } 213 214 static int bnxt_ptp_adjfine_rtc(struct bnxt *bp, long scaled_ppm) 215 { 216 s32 ppb = scaled_ppm_to_ppb(scaled_ppm); 217 struct hwrm_port_mac_cfg_input *req; 218 int rc; 219 220 rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG); 221 if (rc) 222 return rc; 223 224 req->ptp_freq_adj_ppb = cpu_to_le32(ppb); 225 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB); 226 rc = hwrm_req_send(bp, req); 227 if (rc) 228 netdev_err(bp->dev, 229 "ptp adjfine failed. rc = %d\n", rc); 230 return rc; 231 } 232 233 static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) 234 { 235 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 236 ptp_info); 237 struct bnxt *bp = ptp->bp; 238 unsigned long flags; 239 240 if (!BNXT_MH(bp)) 241 return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); 242 243 write_seqlock_irqsave(&ptp->ptp_lock, flags); 244 timecounter_read(&ptp->tc); 245 ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); 246 write_sequnlock_irqrestore(&ptp->ptp_lock, flags); 247 return 0; 248 } 249 250 void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) 251 { 252 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 253 struct ptp_clock_event event; 254 u64 ns, pps_ts; 255 256 pps_ts = EVENT_PPS_TS(data2, data1); 257 ns = bnxt_timecounter_cyc2time(ptp, pps_ts); 258 259 switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { 260 case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: 261 event.pps_times.ts_real = ns_to_timespec64(ns); 262 event.type = PTP_CLOCK_PPSUSR; 263 event.index = EVENT_DATA2_PPS_PIN_NUM(data2); 264 break; 265 case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_EXTERNAL: 266 event.timestamp = ns; 267 event.type = PTP_CLOCK_EXTTS; 268 event.index = EVENT_DATA2_PPS_PIN_NUM(data2); 269 break; 270 } 271 272 ptp_clock_event(bp->ptp_cfg->ptp_clock, &event); 273 } 274 275 static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage) 276 { 277 struct hwrm_func_ptp_pin_cfg_input *req; 278 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 279 u8 state = usage != BNXT_PPS_PIN_NONE; 280 u8 *pin_state, *pin_usg; 281 u32 enables; 282 int rc; 283 284 if (!TSIO_PIN_VALID(pin)) { 285 netdev_err(ptp->bp->dev, "1PPS: Invalid pin. Check pin-function configuration\n"); 286 return -EOPNOTSUPP; 287 } 288 289 rc = hwrm_req_init(ptp->bp, req, HWRM_FUNC_PTP_PIN_CFG); 290 if (rc) 291 return rc; 292 293 enables = (FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_STATE | 294 FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_USAGE) << (pin * 2); 295 req->enables = cpu_to_le32(enables); 296 297 pin_state = &req->pin0_state; 298 pin_usg = &req->pin0_usage; 299 300 *(pin_state + (pin * 2)) = state; 301 *(pin_usg + (pin * 2)) = usage; 302 303 rc = hwrm_req_send(ptp->bp, req); 304 if (rc) 305 return rc; 306 307 ptp->pps_info.pins[pin].usage = usage; 308 ptp->pps_info.pins[pin].state = state; 309 310 return 0; 311 } 312 313 static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event) 314 { 315 struct hwrm_func_ptp_cfg_input *req; 316 int rc; 317 318 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG); 319 if (rc) 320 return rc; 321 322 req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_PPS_EVENT); 323 req->ptp_pps_event = event; 324 return hwrm_req_send(bp, req); 325 } 326 327 int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp) 328 { 329 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 330 struct hwrm_port_mac_cfg_input *req; 331 int rc; 332 333 if (!ptp || !ptp->tstamp_filters) 334 return -EIO; 335 336 rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG); 337 if (rc) 338 goto out; 339 340 if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters & 341 (PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE | 342 PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE))) { 343 ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE | 344 PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE); 345 netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n"); 346 } 347 348 req->flags = cpu_to_le32(ptp->tstamp_filters); 349 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE); 350 req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl); 351 352 rc = hwrm_req_send(bp, req); 353 if (!rc) { 354 bp->ptp_all_rx_tstamp = !!(ptp->tstamp_filters & 355 PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE); 356 return 0; 357 } 358 ptp->tstamp_filters = 0; 359 out: 360 bp->ptp_all_rx_tstamp = 0; 361 netdev_warn(bp->dev, "Failed to configure HW packet timestamp filters\n"); 362 return rc; 363 } 364 365 void bnxt_ptp_reapply_pps(struct bnxt *bp) 366 { 367 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 368 struct bnxt_pps *pps; 369 u32 pin = 0; 370 int rc; 371 372 if (!ptp || !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) || 373 !(ptp->ptp_info.pin_config)) 374 return; 375 pps = &ptp->pps_info; 376 for (pin = 0; pin < BNXT_MAX_TSIO_PINS; pin++) { 377 if (pps->pins[pin].state) { 378 rc = bnxt_ptp_cfg_pin(bp, pin, pps->pins[pin].usage); 379 if (!rc && pps->pins[pin].event) 380 rc = bnxt_ptp_cfg_event(bp, 381 pps->pins[pin].event); 382 if (rc) 383 netdev_err(bp->dev, "1PPS: Failed to configure pin%d\n", 384 pin); 385 } 386 } 387 } 388 389 static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns, 390 u64 *cycles_delta) 391 { 392 u64 cycles_now; 393 u64 nsec_now, nsec_delta; 394 int rc; 395 396 rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); 397 if (rc) 398 return rc; 399 400 nsec_now = bnxt_timecounter_cyc2time(ptp, cycles_now); 401 402 nsec_delta = target_ns - nsec_now; 403 *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); 404 return 0; 405 } 406 407 static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp, 408 struct ptp_clock_request *rq) 409 { 410 struct hwrm_func_ptp_cfg_input *req; 411 struct bnxt *bp = ptp->bp; 412 struct timespec64 ts; 413 u64 target_ns, delta; 414 u16 enables; 415 int rc; 416 417 ts.tv_sec = rq->perout.start.sec; 418 ts.tv_nsec = rq->perout.start.nsec; 419 target_ns = timespec64_to_ns(&ts); 420 421 rc = bnxt_get_target_cycles(ptp, target_ns, &delta); 422 if (rc) 423 return rc; 424 425 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG); 426 if (rc) 427 return rc; 428 429 enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD | 430 FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP | 431 FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE; 432 req->enables = cpu_to_le16(enables); 433 req->ptp_pps_event = 0; 434 req->ptp_freq_adj_dll_source = 0; 435 req->ptp_freq_adj_dll_phase = 0; 436 req->ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC); 437 req->ptp_freq_adj_ext_up = 0; 438 req->ptp_freq_adj_ext_phase_lower = cpu_to_le32(delta); 439 440 return hwrm_req_send(bp, req); 441 } 442 443 static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info, 444 struct ptp_clock_request *rq, int on) 445 { 446 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 447 ptp_info); 448 struct bnxt *bp = ptp->bp; 449 int pin_id; 450 int rc; 451 452 switch (rq->type) { 453 case PTP_CLK_REQ_EXTTS: 454 /* Configure an External PPS IN */ 455 pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, 456 rq->extts.index); 457 if (!TSIO_PIN_VALID(pin_id)) 458 return -EOPNOTSUPP; 459 if (!on) 460 break; 461 rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_IN); 462 if (rc) 463 return rc; 464 rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_EXTERNAL); 465 if (!rc) 466 ptp->pps_info.pins[pin_id].event = BNXT_PPS_EVENT_EXTERNAL; 467 return rc; 468 case PTP_CLK_REQ_PEROUT: 469 /* Configure a Periodic PPS OUT */ 470 pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT, 471 rq->perout.index); 472 if (!TSIO_PIN_VALID(pin_id)) 473 return -EOPNOTSUPP; 474 if (!on) 475 break; 476 477 rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_OUT); 478 if (!rc) 479 rc = bnxt_ptp_perout_cfg(ptp, rq); 480 481 return rc; 482 case PTP_CLK_REQ_PPS: 483 /* Configure PHC PPS IN */ 484 rc = bnxt_ptp_cfg_pin(bp, 0, BNXT_PPS_PIN_PPS_IN); 485 if (rc) 486 return rc; 487 rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_INTERNAL); 488 if (!rc) 489 ptp->pps_info.pins[0].event = BNXT_PPS_EVENT_INTERNAL; 490 return rc; 491 default: 492 netdev_err(ptp->bp->dev, "Unrecognized PIN function\n"); 493 return -EOPNOTSUPP; 494 } 495 496 return bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_NONE); 497 } 498 499 static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) 500 { 501 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 502 u32 flags = 0; 503 504 switch (ptp->rx_filter) { 505 case HWTSTAMP_FILTER_ALL: 506 flags = PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE; 507 break; 508 case HWTSTAMP_FILTER_NONE: 509 flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE; 510 if (bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) 511 flags |= PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE; 512 break; 513 case HWTSTAMP_FILTER_PTP_V2_EVENT: 514 case HWTSTAMP_FILTER_PTP_V2_SYNC: 515 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 516 flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE; 517 break; 518 } 519 520 if (ptp->tx_tstamp_en) 521 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE; 522 else 523 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE; 524 525 ptp->tstamp_filters = flags; 526 527 return bnxt_ptp_cfg_tstamp_filters(bp); 528 } 529 530 int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) 531 { 532 struct bnxt *bp = netdev_priv(dev); 533 struct hwtstamp_config stmpconf; 534 struct bnxt_ptp_cfg *ptp; 535 u16 old_rxctl; 536 int old_rx_filter, rc; 537 u8 old_tx_tstamp_en; 538 539 ptp = bp->ptp_cfg; 540 if (!ptp) 541 return -EOPNOTSUPP; 542 543 if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf))) 544 return -EFAULT; 545 546 if (stmpconf.tx_type != HWTSTAMP_TX_ON && 547 stmpconf.tx_type != HWTSTAMP_TX_OFF) 548 return -ERANGE; 549 550 old_rx_filter = ptp->rx_filter; 551 old_rxctl = ptp->rxctl; 552 old_tx_tstamp_en = ptp->tx_tstamp_en; 553 switch (stmpconf.rx_filter) { 554 case HWTSTAMP_FILTER_NONE: 555 ptp->rxctl = 0; 556 ptp->rx_filter = HWTSTAMP_FILTER_NONE; 557 break; 558 case HWTSTAMP_FILTER_ALL: 559 if (bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) { 560 ptp->rx_filter = HWTSTAMP_FILTER_ALL; 561 break; 562 } 563 return -EOPNOTSUPP; 564 case HWTSTAMP_FILTER_PTP_V2_EVENT: 565 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 566 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 567 ptp->rxctl = BNXT_PTP_MSG_EVENTS; 568 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 569 break; 570 case HWTSTAMP_FILTER_PTP_V2_SYNC: 571 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 572 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 573 ptp->rxctl = BNXT_PTP_MSG_SYNC; 574 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 575 break; 576 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 577 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 578 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 579 ptp->rxctl = BNXT_PTP_MSG_DELAY_REQ; 580 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 581 break; 582 default: 583 return -ERANGE; 584 } 585 586 if (stmpconf.tx_type == HWTSTAMP_TX_ON) 587 ptp->tx_tstamp_en = 1; 588 else 589 ptp->tx_tstamp_en = 0; 590 591 rc = bnxt_hwrm_ptp_cfg(bp); 592 if (rc) 593 goto ts_set_err; 594 595 stmpconf.rx_filter = ptp->rx_filter; 596 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? 597 -EFAULT : 0; 598 599 ts_set_err: 600 ptp->rx_filter = old_rx_filter; 601 ptp->rxctl = old_rxctl; 602 ptp->tx_tstamp_en = old_tx_tstamp_en; 603 return rc; 604 } 605 606 int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) 607 { 608 struct bnxt *bp = netdev_priv(dev); 609 struct hwtstamp_config stmpconf; 610 struct bnxt_ptp_cfg *ptp; 611 612 ptp = bp->ptp_cfg; 613 if (!ptp) 614 return -EOPNOTSUPP; 615 616 stmpconf.flags = 0; 617 stmpconf.tx_type = ptp->tx_tstamp_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 618 619 stmpconf.rx_filter = ptp->rx_filter; 620 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? 621 -EFAULT : 0; 622 } 623 624 static int bnxt_map_regs(struct bnxt *bp, u32 *reg_arr, int count, int reg_win) 625 { 626 u32 reg_base = *reg_arr & BNXT_GRC_BASE_MASK; 627 u32 win_off; 628 int i; 629 630 for (i = 0; i < count; i++) { 631 if ((reg_arr[i] & BNXT_GRC_BASE_MASK) != reg_base) 632 return -ERANGE; 633 } 634 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4; 635 writel(reg_base, bp->bar0 + win_off); 636 return 0; 637 } 638 639 static int bnxt_map_ptp_regs(struct bnxt *bp) 640 { 641 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 642 u32 *reg_arr; 643 int rc, i; 644 645 reg_arr = ptp->refclk_regs; 646 if (BNXT_CHIP_P5(bp)) { 647 rc = bnxt_map_regs(bp, reg_arr, 2, BNXT_PTP_GRC_WIN); 648 if (rc) 649 return rc; 650 for (i = 0; i < 2; i++) 651 ptp->refclk_mapped_regs[i] = BNXT_PTP_GRC_WIN_BASE + 652 (ptp->refclk_regs[i] & BNXT_GRC_OFFSET_MASK); 653 return 0; 654 } 655 if (bp->flags & BNXT_FLAG_CHIP_P7) { 656 for (i = 0; i < 2; i++) { 657 if (reg_arr[i] & BNXT_GRC_BASE_MASK) 658 return -EINVAL; 659 ptp->refclk_mapped_regs[i] = reg_arr[i]; 660 } 661 return 0; 662 } 663 return -ENODEV; 664 } 665 666 static void bnxt_unmap_ptp_regs(struct bnxt *bp) 667 { 668 writel(0, bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 669 (BNXT_PTP_GRC_WIN - 1) * 4); 670 } 671 672 static u64 bnxt_cc_read(const struct cyclecounter *cc) 673 { 674 struct bnxt_ptp_cfg *ptp = container_of(cc, struct bnxt_ptp_cfg, cc); 675 u64 ns = 0; 676 677 bnxt_refclk_read(ptp->bp, NULL, &ns); 678 return ns; 679 } 680 681 static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) 682 { 683 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 684 struct skb_shared_hwtstamps timestamp; 685 struct bnxt_ptp_tx_req *txts_req; 686 unsigned long now = jiffies; 687 u64 ts = 0, ns = 0; 688 u32 tmo = 0; 689 int rc; 690 691 txts_req = &ptp->txts_req[slot]; 692 /* make sure bnxt_get_tx_ts_p5() has updated abs_txts_tmo */ 693 smp_rmb(); 694 if (!time_after_eq(now, txts_req->abs_txts_tmo)) 695 tmo = jiffies_to_msecs(txts_req->abs_txts_tmo - now); 696 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts, 697 tmo, slot); 698 if (!rc) { 699 memset(×tamp, 0, sizeof(timestamp)); 700 ns = bnxt_timecounter_cyc2time(ptp, ts); 701 timestamp.hwtstamp = ns_to_ktime(ns); 702 skb_tstamp_tx(txts_req->tx_skb, ×tamp); 703 ptp->stats.ts_pkts++; 704 } else { 705 if (!time_after_eq(jiffies, txts_req->abs_txts_tmo)) 706 return -EAGAIN; 707 708 ptp->stats.ts_lost++; 709 netdev_warn_once(bp->dev, 710 "TS query for TX timer failed rc = %x\n", rc); 711 } 712 713 dev_kfree_skb_any(txts_req->tx_skb); 714 txts_req->tx_skb = NULL; 715 716 return 0; 717 } 718 719 static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) 720 { 721 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 722 ptp_info); 723 unsigned long now = jiffies; 724 struct bnxt *bp = ptp->bp; 725 u16 cons = ptp->txts_cons; 726 unsigned long flags; 727 u32 num_requests; 728 int rc = 0; 729 730 num_requests = BNXT_MAX_TX_TS - READ_ONCE(ptp->tx_avail); 731 while (num_requests--) { 732 if (IS_ERR(ptp->txts_req[cons].tx_skb)) 733 goto next_slot; 734 if (!ptp->txts_req[cons].tx_skb) 735 break; 736 rc = bnxt_stamp_tx_skb(bp, cons); 737 if (rc == -EAGAIN) 738 break; 739 next_slot: 740 BNXT_PTP_INC_TX_AVAIL(ptp); 741 cons = NEXT_TXTS(cons); 742 } 743 ptp->txts_cons = cons; 744 745 if (!time_after_eq(now, ptp->next_period)) { 746 if (rc == -EAGAIN) 747 return 0; 748 return ptp->next_period - now; 749 } 750 751 bnxt_ptp_get_current_time(bp); 752 ptp->next_period = now + HZ; 753 if (time_after_eq(now, ptp->next_overflow_check)) { 754 write_seqlock_irqsave(&ptp->ptp_lock, flags); 755 timecounter_read(&ptp->tc); 756 write_sequnlock_irqrestore(&ptp->ptp_lock, flags); 757 ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; 758 } 759 if (rc == -EAGAIN) 760 return 0; 761 return HZ; 762 } 763 764 int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod) 765 { 766 spin_lock_bh(&ptp->ptp_tx_lock); 767 if (ptp->tx_avail) { 768 *prod = ptp->txts_prod; 769 ptp->txts_prod = NEXT_TXTS(*prod); 770 ptp->tx_avail--; 771 spin_unlock_bh(&ptp->ptp_tx_lock); 772 return 0; 773 } 774 spin_unlock_bh(&ptp->ptp_tx_lock); 775 atomic64_inc(&ptp->stats.ts_err); 776 return -ENOSPC; 777 } 778 779 void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod) 780 { 781 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 782 struct bnxt_ptp_tx_req *txts_req; 783 784 txts_req = &ptp->txts_req[prod]; 785 txts_req->abs_txts_tmo = jiffies + msecs_to_jiffies(ptp->txts_tmo); 786 /* make sure abs_txts_tmo is written first */ 787 smp_wmb(); 788 txts_req->tx_skb = skb; 789 ptp_schedule_worker(ptp->ptp_clock, 0); 790 } 791 792 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts) 793 { 794 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 795 u64 time; 796 797 if (!ptp) 798 return -ENODEV; 799 800 time = (u64)READ_ONCE(ptp->old_time) << BNXT_HI_TIMER_SHIFT; 801 *ts = (time & BNXT_HI_TIMER_MASK) | pkt_ts; 802 if (pkt_ts < (time & BNXT_LO_TIMER_MASK)) 803 *ts += BNXT_LO_TIMER_MASK + 1; 804 805 return 0; 806 } 807 808 void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, 809 struct tx_ts_cmp *tscmp) 810 { 811 struct skb_shared_hwtstamps timestamp = {}; 812 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 813 u32 opaque = tscmp->tx_ts_cmp_opaque; 814 struct bnxt_tx_ring_info *txr; 815 struct bnxt_sw_tx_bd *tx_buf; 816 u64 ts, ns; 817 u16 cons; 818 819 txr = bnapi->tx_ring[TX_OPAQUE_RING(opaque)]; 820 ts = BNXT_GET_TX_TS_48B_NS(tscmp); 821 cons = TX_OPAQUE_IDX(opaque); 822 tx_buf = &txr->tx_buf_ring[RING_TX(bp, cons)]; 823 if (tx_buf->is_ts_pkt) { 824 if (BNXT_TX_TS_ERR(tscmp)) { 825 netdev_err(bp->dev, 826 "timestamp completion error 0x%x 0x%x\n", 827 le32_to_cpu(tscmp->tx_ts_cmp_flags_type), 828 le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); 829 } else { 830 ns = bnxt_timecounter_cyc2time(ptp, ts); 831 timestamp.hwtstamp = ns_to_ktime(ns); 832 skb_tstamp_tx(tx_buf->skb, ×tamp); 833 } 834 tx_buf->is_ts_pkt = 0; 835 } 836 } 837 838 static const struct ptp_clock_info bnxt_ptp_caps = { 839 .owner = THIS_MODULE, 840 .name = "bnxt clock", 841 .max_adj = BNXT_MAX_PHC_DRIFT, 842 .n_alarm = 0, 843 .n_ext_ts = 0, 844 .n_per_out = 0, 845 .n_pins = 0, 846 .pps = 0, 847 .adjfine = bnxt_ptp_adjfine, 848 .adjtime = bnxt_ptp_adjtime, 849 .do_aux_work = bnxt_ptp_ts_aux_work, 850 .gettimex64 = bnxt_ptp_gettimex, 851 .settime64 = bnxt_ptp_settime, 852 .enable = bnxt_ptp_enable, 853 }; 854 855 static int bnxt_ptp_verify(struct ptp_clock_info *ptp_info, unsigned int pin, 856 enum ptp_pin_function func, unsigned int chan) 857 { 858 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 859 ptp_info); 860 /* Allow only PPS pin function configuration */ 861 if (ptp->pps_info.pins[pin].usage <= BNXT_PPS_PIN_PPS_OUT && 862 func != PTP_PF_PHYSYNC) 863 return 0; 864 else 865 return -EOPNOTSUPP; 866 } 867 868 static int bnxt_ptp_pps_init(struct bnxt *bp) 869 { 870 struct hwrm_func_ptp_pin_qcfg_output *resp; 871 struct hwrm_func_ptp_pin_qcfg_input *req; 872 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 873 struct ptp_clock_info *ptp_info; 874 struct bnxt_pps *pps_info; 875 u8 *pin_usg; 876 u32 i, rc; 877 878 /* Query current/default PIN CFG */ 879 rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_PIN_QCFG); 880 if (rc) 881 return rc; 882 883 resp = hwrm_req_hold(bp, req); 884 rc = hwrm_req_send(bp, req); 885 if (rc || !resp->num_pins) { 886 hwrm_req_drop(bp, req); 887 return -EOPNOTSUPP; 888 } 889 890 ptp_info = &ptp->ptp_info; 891 pps_info = &ptp->pps_info; 892 pps_info->num_pins = resp->num_pins; 893 ptp_info->n_pins = pps_info->num_pins; 894 ptp_info->pin_config = kcalloc(ptp_info->n_pins, 895 sizeof(*ptp_info->pin_config), 896 GFP_KERNEL); 897 if (!ptp_info->pin_config) { 898 hwrm_req_drop(bp, req); 899 return -ENOMEM; 900 } 901 902 /* Report the TSIO capability to kernel */ 903 pin_usg = &resp->pin0_usage; 904 for (i = 0; i < pps_info->num_pins; i++, pin_usg++) { 905 snprintf(ptp_info->pin_config[i].name, 906 sizeof(ptp_info->pin_config[i].name), "bnxt_pps%d", i); 907 ptp_info->pin_config[i].index = i; 908 ptp_info->pin_config[i].chan = i; 909 if (*pin_usg == BNXT_PPS_PIN_PPS_IN) 910 ptp_info->pin_config[i].func = PTP_PF_EXTTS; 911 else if (*pin_usg == BNXT_PPS_PIN_PPS_OUT) 912 ptp_info->pin_config[i].func = PTP_PF_PEROUT; 913 else 914 ptp_info->pin_config[i].func = PTP_PF_NONE; 915 916 pps_info->pins[i].usage = *pin_usg; 917 } 918 hwrm_req_drop(bp, req); 919 920 /* Only 1 each of ext_ts and per_out pins is available in HW */ 921 ptp_info->n_ext_ts = 1; 922 ptp_info->n_per_out = 1; 923 ptp_info->pps = 1; 924 ptp_info->verify = bnxt_ptp_verify; 925 926 return 0; 927 } 928 929 static bool bnxt_pps_config_ok(struct bnxt *bp) 930 { 931 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 932 933 return !(bp->fw_cap & BNXT_FW_CAP_PTP_PPS) == !ptp->ptp_info.pin_config; 934 } 935 936 static void bnxt_ptp_timecounter_init(struct bnxt *bp, bool init_tc) 937 { 938 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 939 940 if (!ptp->ptp_clock) { 941 memset(&ptp->cc, 0, sizeof(ptp->cc)); 942 ptp->cc.read = bnxt_cc_read; 943 ptp->cc.mask = CYCLECOUNTER_MASK(48); 944 if (BNXT_MH(bp)) { 945 /* Use timecounter based non-real time mode */ 946 ptp->cc.shift = BNXT_CYCLES_SHIFT; 947 ptp->cc.mult = clocksource_khz2mult(BNXT_DEVCLK_FREQ, ptp->cc.shift); 948 ptp->cmult = ptp->cc.mult; 949 } else { 950 ptp->cc.shift = 0; 951 ptp->cc.mult = 1; 952 } 953 ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD; 954 } 955 if (init_tc) 956 timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); 957 } 958 959 /* Caller holds ptp_lock */ 960 void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns) 961 { 962 timecounter_init(&ptp->tc, &ptp->cc, ns); 963 /* For RTC, cycle_last must be in sync with the timecounter value. */ 964 ptp->tc.cycle_last = ns & ptp->cc.mask; 965 } 966 967 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) 968 { 969 struct timespec64 tsp; 970 unsigned long flags; 971 u64 ns; 972 int rc; 973 974 if (!bp->ptp_cfg || !BNXT_PTP_USE_RTC(bp)) 975 return -ENODEV; 976 977 if (!phc_cfg) { 978 ktime_get_real_ts64(&tsp); 979 ns = timespec64_to_ns(&tsp); 980 rc = bnxt_ptp_cfg_settime(bp, ns); 981 if (rc) 982 return rc; 983 } else { 984 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, 985 &ns, 0, 0); 986 if (rc) 987 return rc; 988 } 989 write_seqlock_irqsave(&bp->ptp_cfg->ptp_lock, flags); 990 bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); 991 write_sequnlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags); 992 993 return 0; 994 } 995 996 static void bnxt_ptp_free(struct bnxt *bp) 997 { 998 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 999 1000 if (ptp->ptp_clock) { 1001 ptp_clock_unregister(ptp->ptp_clock); 1002 ptp->ptp_clock = NULL; 1003 kfree(ptp->ptp_info.pin_config); 1004 ptp->ptp_info.pin_config = NULL; 1005 } 1006 } 1007 1008 int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) 1009 { 1010 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 1011 int rc; 1012 1013 if (!ptp) 1014 return 0; 1015 1016 rc = bnxt_map_ptp_regs(bp); 1017 if (rc) 1018 return rc; 1019 1020 if (ptp->ptp_clock && bnxt_pps_config_ok(bp)) 1021 return 0; 1022 1023 bnxt_ptp_free(bp); 1024 1025 WRITE_ONCE(ptp->tx_avail, BNXT_MAX_TX_TS); 1026 seqlock_init(&ptp->ptp_lock); 1027 spin_lock_init(&ptp->ptp_tx_lock); 1028 1029 if (BNXT_PTP_USE_RTC(bp)) { 1030 bnxt_ptp_timecounter_init(bp, false); 1031 rc = bnxt_ptp_init_rtc(bp, phc_cfg); 1032 if (rc) 1033 goto out; 1034 } else { 1035 bnxt_ptp_timecounter_init(bp, true); 1036 bnxt_ptp_adjfine_rtc(bp, 0); 1037 } 1038 bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, true); 1039 1040 ptp->ptp_info = bnxt_ptp_caps; 1041 if ((bp->fw_cap & BNXT_FW_CAP_PTP_PPS)) { 1042 if (bnxt_ptp_pps_init(bp)) 1043 netdev_err(bp->dev, "1pps not initialized, continuing without 1pps support\n"); 1044 } 1045 ptp->ptp_clock = ptp_clock_register(&ptp->ptp_info, &bp->pdev->dev); 1046 if (IS_ERR(ptp->ptp_clock)) { 1047 int err = PTR_ERR(ptp->ptp_clock); 1048 1049 ptp->ptp_clock = NULL; 1050 rc = err; 1051 goto out; 1052 } 1053 1054 ptp->stats.ts_pkts = 0; 1055 ptp->stats.ts_lost = 0; 1056 atomic64_set(&ptp->stats.ts_err, 0); 1057 1058 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { 1059 bnxt_refclk_read(bp, NULL, &ptp->current_time); 1060 WRITE_ONCE(ptp->old_time, ptp->current_time >> BNXT_HI_TIMER_SHIFT); 1061 ptp_schedule_worker(ptp->ptp_clock, 0); 1062 } 1063 ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; 1064 return 0; 1065 1066 out: 1067 bnxt_ptp_free(bp); 1068 bnxt_unmap_ptp_regs(bp); 1069 return rc; 1070 } 1071 1072 void bnxt_ptp_clear(struct bnxt *bp) 1073 { 1074 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 1075 int i; 1076 1077 if (!ptp) 1078 return; 1079 1080 if (ptp->ptp_clock) 1081 ptp_clock_unregister(ptp->ptp_clock); 1082 1083 ptp->ptp_clock = NULL; 1084 kfree(ptp->ptp_info.pin_config); 1085 ptp->ptp_info.pin_config = NULL; 1086 1087 for (i = 0; i < BNXT_MAX_TX_TS; i++) { 1088 if (ptp->txts_req[i].tx_skb) { 1089 dev_kfree_skb_any(ptp->txts_req[i].tx_skb); 1090 ptp->txts_req[i].tx_skb = NULL; 1091 } 1092 } 1093 1094 bnxt_unmap_ptp_regs(bp); 1095 } 1096