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/ptp_clock_kernel.h> 15 #include <linux/net_tstamp.h> 16 #include <linux/timecounter.h> 17 #include <linux/timekeeping.h> 18 #include <linux/ptp_classify.h> 19 #include "bnxt_hsi.h" 20 #include "bnxt.h" 21 #include "bnxt_ptp.h" 22 23 int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off) 24 { 25 unsigned int ptp_class; 26 struct ptp_header *hdr; 27 28 ptp_class = ptp_classify_raw(skb); 29 30 switch (ptp_class & PTP_CLASS_VMASK) { 31 case PTP_CLASS_V1: 32 case PTP_CLASS_V2: 33 hdr = ptp_parse_header(skb, ptp_class); 34 if (!hdr) 35 return -EINVAL; 36 37 *hdr_off = (u8 *)hdr - skb->data; 38 *seq_id = ntohs(hdr->sequence_id); 39 return 0; 40 default: 41 return -ERANGE; 42 } 43 } 44 45 static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, 46 const struct timespec64 *ts) 47 { 48 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 49 ptp_info); 50 u64 ns = timespec64_to_ns(ts); 51 52 spin_lock_bh(&ptp->ptp_lock); 53 timecounter_init(&ptp->tc, &ptp->cc, ns); 54 spin_unlock_bh(&ptp->ptp_lock); 55 return 0; 56 } 57 58 /* Caller holds ptp_lock */ 59 static u64 bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts) 60 { 61 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 62 u64 ns; 63 64 ptp_read_system_prets(sts); 65 ns = readl(bp->bar0 + ptp->refclk_mapped_regs[0]); 66 ptp_read_system_postts(sts); 67 ns |= (u64)readl(bp->bar0 + ptp->refclk_mapped_regs[1]) << 32; 68 return ns; 69 } 70 71 static void bnxt_ptp_get_current_time(struct bnxt *bp) 72 { 73 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 74 75 if (!ptp) 76 return; 77 spin_lock_bh(&ptp->ptp_lock); 78 WRITE_ONCE(ptp->old_time, ptp->current_time); 79 ptp->current_time = bnxt_refclk_read(bp, NULL); 80 spin_unlock_bh(&ptp->ptp_lock); 81 } 82 83 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts) 84 { 85 struct hwrm_port_ts_query_output *resp = bp->hwrm_cmd_resp_addr; 86 struct hwrm_port_ts_query_input req = {0}; 87 int rc; 88 89 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_TS_QUERY, -1, -1); 90 req.flags = cpu_to_le32(flags); 91 if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) == 92 PORT_TS_QUERY_REQ_FLAGS_PATH_TX) { 93 req.enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES); 94 req.ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid); 95 req.ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off); 96 req.ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT); 97 } 98 mutex_lock(&bp->hwrm_cmd_lock); 99 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 100 if (!rc) 101 *ts = le64_to_cpu(resp->ptp_msg_ts); 102 mutex_unlock(&bp->hwrm_cmd_lock); 103 return rc; 104 } 105 106 static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info, 107 struct timespec64 *ts, 108 struct ptp_system_timestamp *sts) 109 { 110 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 111 ptp_info); 112 u64 ns, cycles; 113 114 spin_lock_bh(&ptp->ptp_lock); 115 cycles = bnxt_refclk_read(ptp->bp, sts); 116 ns = timecounter_cyc2time(&ptp->tc, cycles); 117 spin_unlock_bh(&ptp->ptp_lock); 118 *ts = ns_to_timespec64(ns); 119 120 return 0; 121 } 122 123 static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 124 { 125 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 126 ptp_info); 127 128 spin_lock_bh(&ptp->ptp_lock); 129 timecounter_adjtime(&ptp->tc, delta); 130 spin_unlock_bh(&ptp->ptp_lock); 131 return 0; 132 } 133 134 static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb) 135 { 136 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 137 ptp_info); 138 struct hwrm_port_mac_cfg_input req = {0}; 139 struct bnxt *bp = ptp->bp; 140 int rc; 141 142 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_CFG, -1, -1); 143 req.ptp_freq_adj_ppb = cpu_to_le32(ppb); 144 req.enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB); 145 rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 146 if (rc) 147 netdev_err(ptp->bp->dev, 148 "ptp adjfreq failed. rc = %d\n", rc); 149 return rc; 150 } 151 152 static int bnxt_ptp_enable(struct ptp_clock_info *ptp, 153 struct ptp_clock_request *rq, int on) 154 { 155 return -EOPNOTSUPP; 156 } 157 158 static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) 159 { 160 struct hwrm_port_mac_cfg_input req = {0}; 161 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 162 u32 flags = 0; 163 164 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_CFG, -1, -1); 165 if (ptp->rx_filter) 166 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE; 167 else 168 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE; 169 if (ptp->tx_tstamp_en) 170 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE; 171 else 172 flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE; 173 req.flags = cpu_to_le32(flags); 174 req.enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE); 175 req.rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl); 176 177 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 178 } 179 180 int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) 181 { 182 struct bnxt *bp = netdev_priv(dev); 183 struct hwtstamp_config stmpconf; 184 struct bnxt_ptp_cfg *ptp; 185 u16 old_rxctl; 186 int old_rx_filter, rc; 187 u8 old_tx_tstamp_en; 188 189 ptp = bp->ptp_cfg; 190 if (!ptp) 191 return -EOPNOTSUPP; 192 193 if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf))) 194 return -EFAULT; 195 196 if (stmpconf.flags) 197 return -EINVAL; 198 199 if (stmpconf.tx_type != HWTSTAMP_TX_ON && 200 stmpconf.tx_type != HWTSTAMP_TX_OFF) 201 return -ERANGE; 202 203 old_rx_filter = ptp->rx_filter; 204 old_rxctl = ptp->rxctl; 205 old_tx_tstamp_en = ptp->tx_tstamp_en; 206 switch (stmpconf.rx_filter) { 207 case HWTSTAMP_FILTER_NONE: 208 ptp->rxctl = 0; 209 ptp->rx_filter = HWTSTAMP_FILTER_NONE; 210 break; 211 case HWTSTAMP_FILTER_PTP_V2_EVENT: 212 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 213 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 214 ptp->rxctl = BNXT_PTP_MSG_EVENTS; 215 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 216 break; 217 case HWTSTAMP_FILTER_PTP_V2_SYNC: 218 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 219 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 220 ptp->rxctl = BNXT_PTP_MSG_SYNC; 221 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 222 break; 223 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 224 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 225 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 226 ptp->rxctl = BNXT_PTP_MSG_DELAY_REQ; 227 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 228 break; 229 default: 230 return -ERANGE; 231 } 232 233 if (stmpconf.tx_type == HWTSTAMP_TX_ON) 234 ptp->tx_tstamp_en = 1; 235 else 236 ptp->tx_tstamp_en = 0; 237 238 rc = bnxt_hwrm_ptp_cfg(bp); 239 if (rc) 240 goto ts_set_err; 241 242 stmpconf.rx_filter = ptp->rx_filter; 243 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? 244 -EFAULT : 0; 245 246 ts_set_err: 247 ptp->rx_filter = old_rx_filter; 248 ptp->rxctl = old_rxctl; 249 ptp->tx_tstamp_en = old_tx_tstamp_en; 250 return rc; 251 } 252 253 int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) 254 { 255 struct bnxt *bp = netdev_priv(dev); 256 struct hwtstamp_config stmpconf; 257 struct bnxt_ptp_cfg *ptp; 258 259 ptp = bp->ptp_cfg; 260 if (!ptp) 261 return -EOPNOTSUPP; 262 263 stmpconf.flags = 0; 264 stmpconf.tx_type = ptp->tx_tstamp_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 265 266 stmpconf.rx_filter = ptp->rx_filter; 267 return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? 268 -EFAULT : 0; 269 } 270 271 static int bnxt_map_regs(struct bnxt *bp, u32 *reg_arr, int count, int reg_win) 272 { 273 u32 reg_base = *reg_arr & BNXT_GRC_BASE_MASK; 274 u32 win_off; 275 int i; 276 277 for (i = 0; i < count; i++) { 278 if ((reg_arr[i] & BNXT_GRC_BASE_MASK) != reg_base) 279 return -ERANGE; 280 } 281 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4; 282 writel(reg_base, bp->bar0 + win_off); 283 return 0; 284 } 285 286 static int bnxt_map_ptp_regs(struct bnxt *bp) 287 { 288 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 289 u32 *reg_arr; 290 int rc, i; 291 292 reg_arr = ptp->refclk_regs; 293 if (bp->flags & BNXT_FLAG_CHIP_P5) { 294 rc = bnxt_map_regs(bp, reg_arr, 2, BNXT_PTP_GRC_WIN); 295 if (rc) 296 return rc; 297 for (i = 0; i < 2; i++) 298 ptp->refclk_mapped_regs[i] = BNXT_PTP_GRC_WIN_BASE + 299 (ptp->refclk_regs[i] & BNXT_GRC_OFFSET_MASK); 300 return 0; 301 } 302 return -ENODEV; 303 } 304 305 static void bnxt_unmap_ptp_regs(struct bnxt *bp) 306 { 307 writel(0, bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 308 (BNXT_PTP_GRC_WIN - 1) * 4); 309 } 310 311 static u64 bnxt_cc_read(const struct cyclecounter *cc) 312 { 313 struct bnxt_ptp_cfg *ptp = container_of(cc, struct bnxt_ptp_cfg, cc); 314 315 return bnxt_refclk_read(ptp->bp, NULL); 316 } 317 318 static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb) 319 { 320 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 321 struct skb_shared_hwtstamps timestamp; 322 u64 ts = 0, ns = 0; 323 int rc; 324 325 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts); 326 if (!rc) { 327 memset(×tamp, 0, sizeof(timestamp)); 328 spin_lock_bh(&ptp->ptp_lock); 329 ns = timecounter_cyc2time(&ptp->tc, ts); 330 spin_unlock_bh(&ptp->ptp_lock); 331 timestamp.hwtstamp = ns_to_ktime(ns); 332 skb_tstamp_tx(ptp->tx_skb, ×tamp); 333 } else { 334 netdev_err(bp->dev, "TS query for TX timer failed rc = %x\n", 335 rc); 336 } 337 338 dev_kfree_skb_any(ptp->tx_skb); 339 ptp->tx_skb = NULL; 340 atomic_inc(&ptp->tx_avail); 341 } 342 343 static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) 344 { 345 struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, 346 ptp_info); 347 unsigned long now = jiffies; 348 struct bnxt *bp = ptp->bp; 349 350 if (ptp->tx_skb) 351 bnxt_stamp_tx_skb(bp, ptp->tx_skb); 352 353 if (!time_after_eq(now, ptp->next_period)) 354 return ptp->next_period - now; 355 356 bnxt_ptp_get_current_time(bp); 357 ptp->next_period = now + HZ; 358 if (time_after_eq(now, ptp->next_overflow_check)) { 359 spin_lock_bh(&ptp->ptp_lock); 360 timecounter_read(&ptp->tc); 361 spin_unlock_bh(&ptp->ptp_lock); 362 ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; 363 } 364 return HZ; 365 } 366 367 int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb) 368 { 369 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 370 371 if (ptp->tx_skb) { 372 netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n"); 373 return -EBUSY; 374 } 375 ptp->tx_skb = skb; 376 ptp_schedule_worker(ptp->ptp_clock, 0); 377 return 0; 378 } 379 380 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts) 381 { 382 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 383 u64 time; 384 385 if (!ptp) 386 return -ENODEV; 387 388 BNXT_READ_TIME64(ptp, time, ptp->old_time); 389 *ts = (time & BNXT_HI_TIMER_MASK) | pkt_ts; 390 if (pkt_ts < (time & BNXT_LO_TIMER_MASK)) 391 *ts += BNXT_LO_TIMER_MASK + 1; 392 393 return 0; 394 } 395 396 static const struct ptp_clock_info bnxt_ptp_caps = { 397 .owner = THIS_MODULE, 398 .name = "bnxt clock", 399 .max_adj = BNXT_MAX_PHC_DRIFT, 400 .n_alarm = 0, 401 .n_ext_ts = 0, 402 .n_per_out = 0, 403 .n_pins = 0, 404 .pps = 0, 405 .adjfreq = bnxt_ptp_adjfreq, 406 .adjtime = bnxt_ptp_adjtime, 407 .do_aux_work = bnxt_ptp_ts_aux_work, 408 .gettimex64 = bnxt_ptp_gettimex, 409 .settime64 = bnxt_ptp_settime, 410 .enable = bnxt_ptp_enable, 411 }; 412 413 int bnxt_ptp_init(struct bnxt *bp) 414 { 415 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 416 int rc; 417 418 if (!ptp) 419 return 0; 420 421 rc = bnxt_map_ptp_regs(bp); 422 if (rc) 423 return rc; 424 425 atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS); 426 spin_lock_init(&ptp->ptp_lock); 427 428 memset(&ptp->cc, 0, sizeof(ptp->cc)); 429 ptp->cc.read = bnxt_cc_read; 430 ptp->cc.mask = CYCLECOUNTER_MASK(48); 431 ptp->cc.shift = 0; 432 ptp->cc.mult = 1; 433 434 ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD; 435 timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); 436 437 ptp->ptp_info = bnxt_ptp_caps; 438 ptp->ptp_clock = ptp_clock_register(&ptp->ptp_info, &bp->pdev->dev); 439 if (IS_ERR(ptp->ptp_clock)) { 440 int err = PTR_ERR(ptp->ptp_clock); 441 442 ptp->ptp_clock = NULL; 443 bnxt_unmap_ptp_regs(bp); 444 return err; 445 } 446 if (bp->flags & BNXT_FLAG_CHIP_P5) { 447 spin_lock_bh(&ptp->ptp_lock); 448 ptp->current_time = bnxt_refclk_read(bp, NULL); 449 WRITE_ONCE(ptp->old_time, ptp->current_time); 450 spin_unlock_bh(&ptp->ptp_lock); 451 ptp_schedule_worker(ptp->ptp_clock, 0); 452 } 453 return 0; 454 } 455 456 void bnxt_ptp_clear(struct bnxt *bp) 457 { 458 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 459 460 if (!ptp) 461 return; 462 463 if (ptp->ptp_clock) 464 ptp_clock_unregister(ptp->ptp_clock); 465 466 ptp->ptp_clock = NULL; 467 if (ptp->tx_skb) { 468 dev_kfree_skb_any(ptp->tx_skb); 469 ptp->tx_skb = NULL; 470 } 471 bnxt_unmap_ptp_regs(bp); 472 } 473