Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bnxt_en-ptp' into main

Michael Chan says:

====================
bnxt_en: PTP updates for net-next

The first 5 patches implement the PTP feature on the new BCM5760X
chips. The main new hardware feature is the new TX timestamp
completion which enables the driver to retrieve the TX timestamp
in NAPI without deferring to the PTP worker.

The last 5 patches increase the number of TX PTP packets in-flight
from 1 to 4 on the older BCM5750X chips. On these older chips, we
need to call firmware in the PTP worker to retrieve the timestamp.
We use an arry to keep track of the in-flight TX PTP packets.

v2: Patch #2: Fix the unwind of txr->is_ts_pkt when bnxt_start_xmit() aborts.
Patch #4: Set the SKBTX_IN_PROGRESS flag for timestamp packets.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+251 -82
+69 -37
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 456 456 dma_addr_t mapping; 457 457 unsigned int length, pad = 0; 458 458 u32 len, free_size, vlan_tag_flags, cfa_action, flags; 459 - u16 prod, last_frag; 459 + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 460 460 struct pci_dev *pdev = bp->pdev; 461 + u16 prod, last_frag, txts_prod; 461 462 struct bnxt_tx_ring_info *txr; 462 463 struct bnxt_sw_tx_bd *tx_buf; 463 464 __le32 lflags = 0; ··· 510 509 vlan_tag_flags |= 1 << TX_BD_CFA_META_TPID_SHIFT; 511 510 } 512 511 513 - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 514 - struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 512 + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && ptp && 513 + ptp->tx_tstamp_en) { 514 + if (bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP) { 515 + lflags |= cpu_to_le32(TX_BD_FLAGS_STAMP); 516 + tx_buf->is_ts_pkt = 1; 517 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 518 + } else if (!skb_is_gso(skb)) { 519 + u16 seq_id, hdr_off; 515 520 516 - if (ptp && ptp->tx_tstamp_en && !skb_is_gso(skb)) { 517 - if (atomic_dec_if_positive(&ptp->tx_avail) < 0) { 518 - atomic64_inc(&ptp->stats.ts_err); 519 - goto tx_no_ts; 520 - } 521 - if (!bnxt_ptp_parse(skb, &ptp->tx_seqid, 522 - &ptp->tx_hdr_off)) { 521 + if (!bnxt_ptp_parse(skb, &seq_id, &hdr_off) && 522 + !bnxt_ptp_get_txts_prod(ptp, &txts_prod)) { 523 523 if (vlan_tag_flags) 524 - ptp->tx_hdr_off += VLAN_HLEN; 524 + hdr_off += VLAN_HLEN; 525 525 lflags |= cpu_to_le32(TX_BD_FLAGS_STAMP); 526 + tx_buf->is_ts_pkt = 1; 526 527 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 527 - } else { 528 - atomic_inc(&bp->ptp_cfg->tx_avail); 528 + 529 + ptp->txts_req[txts_prod].tx_seqid = seq_id; 530 + ptp->txts_req[txts_prod].tx_hdr_off = hdr_off; 531 + tx_buf->txts_prod = txts_prod; 529 532 } 530 533 } 531 534 } 532 - 533 - tx_no_ts: 534 535 if (unlikely(skb->no_fcs)) 535 536 lflags |= cpu_to_le32(TX_BD_FLAGS_NO_CRC); 536 537 ··· 761 758 dev_kfree_skb_any(skb); 762 759 tx_kick_pending: 763 760 if (BNXT_TX_PTP_IS_SET(lflags)) { 761 + txr->tx_buf_ring[txr->tx_prod].is_ts_pkt = 0; 764 762 atomic64_inc(&bp->ptp_cfg->stats.ts_err); 765 - atomic_inc(&bp->ptp_cfg->tx_avail); 763 + if (!(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) 764 + /* set SKB to err so PTP worker will clean up */ 765 + ptp->txts_req[txts_prod].tx_skb = ERR_PTR(-EIO); 766 766 } 767 767 if (txr->kick_pending) 768 768 bnxt_txr_db_kick(bp, txr, txr->tx_prod); ··· 774 768 return NETDEV_TX_OK; 775 769 } 776 770 777 - static void __bnxt_tx_int(struct bnxt *bp, struct bnxt_tx_ring_info *txr, 771 + /* Returns true if some remaining TX packets not processed. */ 772 + static bool __bnxt_tx_int(struct bnxt *bp, struct bnxt_tx_ring_info *txr, 778 773 int budget) 779 774 { 780 775 struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txr->txq_index); ··· 784 777 unsigned int tx_bytes = 0; 785 778 u16 cons = txr->tx_cons; 786 779 int tx_pkts = 0; 780 + bool rc = false; 787 781 788 782 while (RING_TX(bp, cons) != hw_cons) { 789 783 struct bnxt_sw_tx_bd *tx_buf; 790 784 struct sk_buff *skb; 785 + bool is_ts_pkt; 791 786 int j, last; 792 787 793 788 tx_buf = &txr->tx_buf_ring[RING_TX(bp, cons)]; 794 - cons = NEXT_TX(cons); 795 789 skb = tx_buf->skb; 796 - tx_buf->skb = NULL; 797 790 798 791 if (unlikely(!skb)) { 799 792 bnxt_sched_reset_txr(bp, txr, cons); 800 - return; 793 + return rc; 801 794 } 802 795 796 + is_ts_pkt = tx_buf->is_ts_pkt; 797 + if (is_ts_pkt && (bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) { 798 + rc = true; 799 + break; 800 + } 801 + 802 + cons = NEXT_TX(cons); 803 803 tx_pkts++; 804 804 tx_bytes += skb->len; 805 + tx_buf->skb = NULL; 806 + tx_buf->is_ts_pkt = 0; 805 807 806 808 if (tx_buf->is_push) { 807 809 tx_buf->is_push = 0; ··· 830 814 skb_frag_size(&skb_shinfo(skb)->frags[j]), 831 815 DMA_TO_DEVICE); 832 816 } 833 - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { 817 + if (unlikely(is_ts_pkt)) { 834 818 if (BNXT_CHIP_P5(bp)) { 835 819 /* PTP worker takes ownership of the skb */ 836 - if (!bnxt_get_tx_ts_p5(bp, skb)) { 837 - skb = NULL; 838 - } else { 839 - atomic64_inc(&bp->ptp_cfg->stats.ts_err); 840 - atomic_inc(&bp->ptp_cfg->tx_avail); 841 - } 820 + bnxt_get_tx_ts_p5(bp, skb, tx_buf->txts_prod); 821 + skb = NULL; 842 822 } 843 823 } 844 824 ··· 849 837 __netif_txq_completed_wake(txq, tx_pkts, tx_bytes, 850 838 bnxt_tx_avail(bp, txr), bp->tx_wake_thresh, 851 839 READ_ONCE(txr->dev_state) == BNXT_DEV_STATE_CLOSING); 840 + 841 + return rc; 852 842 } 853 843 854 844 static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) 855 845 { 856 846 struct bnxt_tx_ring_info *txr; 847 + bool more = false; 857 848 int i; 858 849 859 850 bnxt_for_each_napi_tx(i, bnapi, txr) { 860 851 if (txr->tx_hw_cons != RING_TX(bp, txr->tx_cons)) 861 - __bnxt_tx_int(bp, txr, budget); 852 + more |= __bnxt_tx_int(bp, txr, budget); 862 853 } 863 - bnapi->events &= ~BNXT_TX_CMP_EVENT; 854 + if (!more) 855 + bnapi->events &= ~BNXT_TX_CMP_EVENT; 864 856 } 865 857 866 858 static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, ··· 2930 2914 cpr->has_more_work = 1; 2931 2915 break; 2932 2916 } 2917 + } else if (cmp_type == CMP_TYPE_TX_L2_PKT_TS_CMP) { 2918 + bnxt_tx_ts_cmp(bp, bnapi, (struct tx_ts_cmp *)txcmp); 2933 2919 } else if (cmp_type >= CMP_TYPE_RX_L2_CMP && 2934 2920 cmp_type <= CMP_TYPE_RX_L2_TPA_START_V3_CMP) { 2935 2921 if (likely(budget)) ··· 2963 2945 } 2964 2946 } 2965 2947 2966 - if (event & BNXT_REDIRECT_EVENT) 2948 + if (event & BNXT_REDIRECT_EVENT) { 2967 2949 xdp_do_flush(); 2950 + event &= ~BNXT_REDIRECT_EVENT; 2951 + } 2968 2952 2969 2953 if (event & BNXT_TX_EVENT) { 2970 2954 struct bnxt_tx_ring_info *txr = bnapi->tx_ring[0]; ··· 2976 2956 wmb(); 2977 2957 2978 2958 bnxt_db_write_relaxed(bp, &txr->tx_db, prod); 2959 + event &= ~BNXT_TX_EVENT; 2979 2960 } 2980 2961 2981 2962 cpr->cp_raw_cons = raw_cons; ··· 2994 2973 struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; 2995 2974 2996 2975 bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); 2976 + bnapi->events &= ~BNXT_RX_EVENT; 2997 2977 } 2998 2978 if (bnapi->events & BNXT_AGG_EVENT) { 2999 2979 struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; 3000 2980 3001 2981 bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); 2982 + bnapi->events &= ~BNXT_AGG_EVENT; 3002 2983 } 3003 - bnapi->events &= BNXT_TX_CMP_EVENT; 3004 2984 } 3005 2985 3006 2986 static int bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, ··· 6810 6788 switch (ring_type) { 6811 6789 case HWRM_RING_ALLOC_TX: { 6812 6790 struct bnxt_tx_ring_info *txr; 6791 + u16 flags = 0; 6813 6792 6814 6793 txr = container_of(ring, struct bnxt_tx_ring_info, 6815 6794 tx_ring_struct); ··· 6824 6801 if (bp->flags & BNXT_FLAG_TX_COAL_CMPL) 6825 6802 req->cmpl_coal_cnt = 6826 6803 RING_ALLOC_REQ_CMPL_COAL_CNT_COAL_64; 6804 + if ((bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP) && bp->ptp_cfg) 6805 + flags |= RING_ALLOC_REQ_FLAGS_TX_PKT_TS_CMPL_ENABLE; 6806 + req->flags = cpu_to_le16(flags); 6827 6807 break; 6828 6808 } 6829 6809 case HWRM_RING_ALLOC_RX: ··· 9007 8981 u8 flags; 9008 8982 int rc; 9009 8983 9010 - if (bp->hwrm_spec_code < 0x10801 || !BNXT_CHIP_P5(bp)) { 8984 + if (bp->hwrm_spec_code < 0x10801 || !BNXT_CHIP_P5_PLUS(bp)) { 9011 8985 rc = -ENODEV; 9012 8986 goto no_ptp; 9013 8987 } ··· 9023 8997 goto exit; 9024 8998 9025 8999 flags = resp->flags; 9026 - if (!(flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_HWRM_ACCESS)) { 9000 + if (BNXT_CHIP_P5_AND_MINUS(bp) && 9001 + !(flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_HWRM_ACCESS)) { 9027 9002 rc = -ENODEV; 9028 9003 goto exit; 9029 9004 } ··· 9037 9010 ptp->bp = bp; 9038 9011 bp->ptp_cfg = ptp; 9039 9012 } 9040 - if (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_PARTIAL_DIRECT_ACCESS_REF_CLOCK) { 9013 + 9014 + if (flags & 9015 + (PORT_MAC_PTP_QCFG_RESP_FLAGS_PARTIAL_DIRECT_ACCESS_REF_CLOCK | 9016 + PORT_MAC_PTP_QCFG_RESP_FLAGS_64B_PHC_TIME)) { 9041 9017 ptp->refclk_regs[0] = le32_to_cpu(resp->ts_ref_clock_reg_lower); 9042 9018 ptp->refclk_regs[1] = le32_to_cpu(resp->ts_ref_clock_reg_upper); 9043 - } else if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { 9019 + } else if (BNXT_CHIP_P5(bp)) { 9044 9020 ptp->refclk_regs[0] = BNXT_TS_REG_TIMESYNC_TS0_LOWER; 9045 9021 ptp->refclk_regs[1] = BNXT_TS_REG_TIMESYNC_TS0_UPPER; 9046 9022 } else { ··· 9125 9095 bp->fw_cap |= BNXT_FW_CAP_RX_ALL_PKT_TS; 9126 9096 if (flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_UDP_GSO_SUPPORTED) 9127 9097 bp->flags |= BNXT_FLAG_UDP_GSO_CAP; 9098 + if (flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_TX_PKT_TS_CMPL_SUPPORTED) 9099 + bp->fw_cap |= BNXT_FW_CAP_TX_TS_CMP; 9128 9100 9129 9101 bp->tx_push_thresh = 0; 9130 9102 if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) && ··· 12168 12136 /* VF-reps may need to be re-opened after the PF is re-opened */ 12169 12137 if (BNXT_PF(bp)) 12170 12138 bnxt_vf_reps_open(bp); 12171 - if (bp->ptp_cfg) 12172 - atomic_set(&bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS); 12139 + if (bp->ptp_cfg && !(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP)) 12140 + WRITE_ONCE(bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS); 12173 12141 bnxt_ptp_init_rtc(bp, true); 12174 12142 bnxt_ptp_cfg_tstamp_filters(bp); 12175 12143 if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
+40 -2
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 181 181 #define TX_CMP_SQ_CONS_IDX(txcmp) \ 182 182 (le32_to_cpu((txcmp)->sq_cons_idx) & TX_CMP_SQ_CONS_IDX_MASK) 183 183 184 + struct tx_ts_cmp { 185 + __le32 tx_ts_cmp_flags_type; 186 + #define TX_TS_CMP_FLAGS_ERROR (1 << 6) 187 + #define TX_TS_CMP_FLAGS_TS_TYPE (1 << 7) 188 + #define TX_TS_CMP_FLAGS_TS_TYPE_PM (0 << 7) 189 + #define TX_TS_CMP_FLAGS_TS_TYPE_PA (1 << 7) 190 + #define TX_TS_CMP_FLAGS_TS_FALLBACK (1 << 8) 191 + #define TX_TS_CMP_TS_SUB_NS (0xf << 12) 192 + #define TX_TS_CMP_TS_NS_MID (0xffff << 16) 193 + #define TX_TS_CMP_TS_NS_MID_SFT 16 194 + u32 tx_ts_cmp_opaque; 195 + __le32 tx_ts_cmp_errors_v; 196 + #define TX_TS_CMP_V (1 << 0) 197 + #define TX_TS_CMP_TS_INVALID_ERR (1 << 10) 198 + __le32 tx_ts_cmp_ts_ns_lo; 199 + }; 200 + 201 + #define BNXT_GET_TX_TS_48B_NS(tscmp) \ 202 + (le32_to_cpu((tscmp)->tx_ts_cmp_ts_ns_lo) | \ 203 + ((u64)(le32_to_cpu((tscmp)->tx_ts_cmp_flags_type) & \ 204 + TX_TS_CMP_TS_NS_MID) << TX_TS_CMP_TS_NS_MID_SFT)) 205 + 206 + #define BNXT_TX_TS_ERR(tscmp) \ 207 + (((tscmp)->tx_ts_cmp_flags_type & cpu_to_le32(TX_TS_CMP_FLAGS_ERROR)) &&\ 208 + ((tscmp)->tx_ts_cmp_errors_v & cpu_to_le32(TX_TS_CMP_TS_INVALID_ERR))) 209 + 184 210 struct rx_cmp { 185 211 __le32 rx_cmp_len_flags_type; 186 212 #define RX_CMP_CMP_TYPE (0x3f << 0) ··· 874 848 DEFINE_DMA_UNMAP_ADDR(mapping); 875 849 DEFINE_DMA_UNMAP_LEN(len); 876 850 struct page *page; 877 - u8 is_gso; 851 + u8 is_ts_pkt; 878 852 u8 is_push; 879 853 u8 action; 880 854 unsigned short nr_frags; 881 - u16 rx_prod; 855 + union { 856 + u16 rx_prod; 857 + u16 txts_prod; 858 + }; 882 859 }; 883 860 884 861 struct bnxt_sw_rx_bd { ··· 2266 2237 (BNXT_CHIP_NUM_58700((bp)->chip_num) && \ 2267 2238 !BNXT_CHIP_TYPE_NITRO_A0(bp))) 2268 2239 2240 + /* Chip class phase 3.x */ 2241 + #define BNXT_CHIP_P3(bp) \ 2242 + (BNXT_CHIP_NUM_57X0X((bp)->chip_num) || \ 2243 + BNXT_CHIP_TYPE_NITRO_A0(bp)) 2244 + 2269 2245 #define BNXT_CHIP_P4_PLUS(bp) \ 2270 2246 (BNXT_CHIP_P4(bp) || BNXT_CHIP_P5_PLUS(bp)) 2247 + 2248 + #define BNXT_CHIP_P5_AND_MINUS(bp) \ 2249 + (BNXT_CHIP_P3(bp) || BNXT_CHIP_P4(bp) || BNXT_CHIP_P5(bp)) 2271 2250 2272 2251 struct bnxt_aux_priv *aux_priv; 2273 2252 struct bnxt_en_dev *edev; ··· 2421 2384 #define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2 BIT_ULL(16) 2422 2385 #define BNXT_FW_CAP_PCIE_STATS_SUPPORTED BIT_ULL(17) 2423 2386 #define BNXT_FW_CAP_EXT_STATS_SUPPORTED BIT_ULL(18) 2387 + #define BNXT_FW_CAP_TX_TS_CMP BIT_ULL(19) 2424 2388 #define BNXT_FW_CAP_ERR_RECOVER_RELOAD BIT_ULL(20) 2425 2389 #define BNXT_FW_CAP_HOT_RESET BIT_ULL(21) 2426 2390 #define BNXT_FW_CAP_PTP_RTC BIT_ULL(22)
+114 -35
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
··· 110 110 } 111 111 112 112 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, 113 - u32 txts_tmo) 113 + u32 txts_tmo, int slot) 114 114 { 115 115 struct hwrm_port_ts_query_output *resp; 116 116 struct hwrm_port_ts_query_input *req; ··· 123 123 req->flags = cpu_to_le32(flags); 124 124 if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) == 125 125 PORT_TS_QUERY_REQ_FLAGS_PATH_TX) { 126 + struct bnxt_ptp_tx_req *txts_req = &bp->ptp_cfg->txts_req[slot]; 126 127 u32 tmo_us = txts_tmo * 1000; 127 128 128 129 req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES); 129 - req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid); 130 - req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off); 130 + req->ptp_seq_id = cpu_to_le32(txts_req->tx_seqid); 131 + req->ptp_hdr_offset = cpu_to_le16(txts_req->tx_hdr_off); 131 132 if (!tmo_us) 132 133 tmo_us = BNXT_PTP_QTS_TIMEOUT; 133 134 tmo_us = min(tmo_us, BNXT_PTP_QTS_MAX_TMO_US); ··· 657 656 (ptp->refclk_regs[i] & BNXT_GRC_OFFSET_MASK); 658 657 return 0; 659 658 } 659 + if (bp->flags & BNXT_FLAG_CHIP_P7) { 660 + for (i = 0; i < 2; i++) { 661 + if (reg_arr[i] & BNXT_GRC_BASE_MASK) 662 + return -EINVAL; 663 + ptp->refclk_mapped_regs[i] = reg_arr[i]; 664 + } 665 + return 0; 666 + } 660 667 return -ENODEV; 661 668 } 662 669 ··· 683 674 return ns; 684 675 } 685 676 686 - static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb) 677 + static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) 687 678 { 688 679 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 689 680 struct skb_shared_hwtstamps timestamp; 681 + struct bnxt_ptp_tx_req *txts_req; 690 682 unsigned long now = jiffies; 691 683 u64 ts = 0, ns = 0; 692 684 u32 tmo = 0; 693 685 int rc; 694 686 695 - if (!ptp->txts_pending) 696 - ptp->abs_txts_tmo = now + msecs_to_jiffies(ptp->txts_tmo); 697 - if (!time_after_eq(now, ptp->abs_txts_tmo)) 698 - tmo = jiffies_to_msecs(ptp->abs_txts_tmo - now); 687 + txts_req = &ptp->txts_req[slot]; 688 + /* make sure bnxt_get_tx_ts_p5() has updated abs_txts_tmo */ 689 + smp_rmb(); 690 + if (!time_after_eq(now, txts_req->abs_txts_tmo)) 691 + tmo = jiffies_to_msecs(txts_req->abs_txts_tmo - now); 699 692 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts, 700 - tmo); 693 + tmo, slot); 701 694 if (!rc) { 702 695 memset(&timestamp, 0, sizeof(timestamp)); 703 696 spin_lock_bh(&ptp->ptp_lock); 704 697 ns = timecounter_cyc2time(&ptp->tc, ts); 705 698 spin_unlock_bh(&ptp->ptp_lock); 706 699 timestamp.hwtstamp = ns_to_ktime(ns); 707 - skb_tstamp_tx(ptp->tx_skb, &timestamp); 700 + skb_tstamp_tx(txts_req->tx_skb, &timestamp); 708 701 ptp->stats.ts_pkts++; 709 702 } else { 710 - if (!time_after_eq(jiffies, ptp->abs_txts_tmo)) { 711 - ptp->txts_pending = true; 712 - return; 713 - } 703 + if (!time_after_eq(jiffies, txts_req->abs_txts_tmo)) 704 + return -EAGAIN; 705 + 714 706 ptp->stats.ts_lost++; 715 707 netdev_warn_once(bp->dev, 716 708 "TS query for TX timer failed rc = %x\n", rc); 717 709 } 718 710 719 - dev_kfree_skb_any(ptp->tx_skb); 720 - ptp->tx_skb = NULL; 721 - atomic_inc(&ptp->tx_avail); 722 - ptp->txts_pending = false; 711 + dev_kfree_skb_any(txts_req->tx_skb); 712 + txts_req->tx_skb = NULL; 713 + 714 + return 0; 723 715 } 724 716 725 717 static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) ··· 729 719 ptp_info); 730 720 unsigned long now = jiffies; 731 721 struct bnxt *bp = ptp->bp; 722 + u16 cons = ptp->txts_cons; 723 + u32 num_requests; 724 + int rc = 0; 732 725 733 - if (ptp->tx_skb) 734 - bnxt_stamp_tx_skb(bp, ptp->tx_skb); 726 + num_requests = BNXT_MAX_TX_TS - READ_ONCE(ptp->tx_avail); 727 + while (num_requests--) { 728 + if (IS_ERR(ptp->txts_req[cons].tx_skb)) 729 + goto next_slot; 730 + if (!ptp->txts_req[cons].tx_skb) 731 + break; 732 + rc = bnxt_stamp_tx_skb(bp, cons); 733 + if (rc == -EAGAIN) 734 + break; 735 + next_slot: 736 + BNXT_PTP_INC_TX_AVAIL(ptp); 737 + cons = NEXT_TXTS(cons); 738 + } 739 + ptp->txts_cons = cons; 735 740 736 - if (!time_after_eq(now, ptp->next_period)) 741 + if (!time_after_eq(now, ptp->next_period)) { 742 + if (rc == -EAGAIN) 743 + return 0; 737 744 return ptp->next_period - now; 745 + } 738 746 739 747 bnxt_ptp_get_current_time(bp); 740 748 ptp->next_period = now + HZ; ··· 762 734 spin_unlock_bh(&ptp->ptp_lock); 763 735 ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; 764 736 } 765 - if (ptp->txts_pending) 737 + if (rc == -EAGAIN) 766 738 return 0; 767 739 return HZ; 768 740 } 769 741 770 - int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb) 742 + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod) 743 + { 744 + spin_lock_bh(&ptp->ptp_tx_lock); 745 + if (ptp->tx_avail) { 746 + *prod = ptp->txts_prod; 747 + ptp->txts_prod = NEXT_TXTS(*prod); 748 + ptp->tx_avail--; 749 + spin_unlock_bh(&ptp->ptp_tx_lock); 750 + return 0; 751 + } 752 + spin_unlock_bh(&ptp->ptp_tx_lock); 753 + atomic64_inc(&ptp->stats.ts_err); 754 + return -ENOSPC; 755 + } 756 + 757 + void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod) 771 758 { 772 759 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 760 + struct bnxt_ptp_tx_req *txts_req; 773 761 774 - if (ptp->tx_skb) { 775 - netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n"); 776 - return -EBUSY; 777 - } 778 - ptp->tx_skb = skb; 762 + txts_req = &ptp->txts_req[prod]; 763 + txts_req->abs_txts_tmo = jiffies + msecs_to_jiffies(ptp->txts_tmo); 764 + /* make sure abs_txts_tmo is written first */ 765 + smp_wmb(); 766 + txts_req->tx_skb = skb; 779 767 ptp_schedule_worker(ptp->ptp_clock, 0); 780 - return 0; 781 768 } 782 769 783 770 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts) ··· 809 766 *ts += BNXT_LO_TIMER_MASK + 1; 810 767 811 768 return 0; 769 + } 770 + 771 + void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, 772 + struct tx_ts_cmp *tscmp) 773 + { 774 + struct skb_shared_hwtstamps timestamp = {}; 775 + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 776 + u32 opaque = tscmp->tx_ts_cmp_opaque; 777 + struct bnxt_tx_ring_info *txr; 778 + struct bnxt_sw_tx_bd *tx_buf; 779 + u64 ts, ns; 780 + u16 cons; 781 + 782 + txr = bnapi->tx_ring[TX_OPAQUE_RING(opaque)]; 783 + ts = BNXT_GET_TX_TS_48B_NS(tscmp); 784 + cons = TX_OPAQUE_IDX(opaque); 785 + tx_buf = &txr->tx_buf_ring[RING_TX(bp, cons)]; 786 + if (tx_buf->is_ts_pkt) { 787 + if (BNXT_TX_TS_ERR(tscmp)) { 788 + netdev_err(bp->dev, 789 + "timestamp completion error 0x%x 0x%x\n", 790 + le32_to_cpu(tscmp->tx_ts_cmp_flags_type), 791 + le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); 792 + } else { 793 + spin_lock_bh(&ptp->ptp_lock); 794 + ns = timecounter_cyc2time(&ptp->tc, ts); 795 + spin_unlock_bh(&ptp->ptp_lock); 796 + timestamp.hwtstamp = ns_to_ktime(ns); 797 + skb_tstamp_tx(tx_buf->skb, &timestamp); 798 + } 799 + tx_buf->is_ts_pkt = 0; 800 + } 812 801 } 813 802 814 803 static const struct ptp_clock_info bnxt_ptp_caps = { ··· 989 914 return rc; 990 915 } else { 991 916 rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME, 992 - &ns, 0); 917 + &ns, 0, 0); 993 918 if (rc) 994 919 return rc; 995 920 } ··· 1029 954 1030 955 bnxt_ptp_free(bp); 1031 956 1032 - atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS); 957 + WRITE_ONCE(ptp->tx_avail, BNXT_MAX_TX_TS); 1033 958 spin_lock_init(&ptp->ptp_lock); 959 + spin_lock_init(&ptp->ptp_tx_lock); 1034 960 1035 961 if (BNXT_PTP_USE_RTC(bp)) { 1036 962 bnxt_ptp_timecounter_init(bp, false); ··· 1062 986 ptp->stats.ts_lost = 0; 1063 987 atomic64_set(&ptp->stats.ts_err, 0); 1064 988 1065 - if (BNXT_CHIP_P5(bp)) { 989 + if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { 1066 990 spin_lock_bh(&ptp->ptp_lock); 1067 991 bnxt_refclk_read(bp, NULL, &ptp->current_time); 1068 992 WRITE_ONCE(ptp->old_time, ptp->current_time); ··· 1081 1005 void bnxt_ptp_clear(struct bnxt *bp) 1082 1006 { 1083 1007 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 1008 + int i; 1084 1009 1085 1010 if (!ptp) 1086 1011 return; ··· 1093 1016 kfree(ptp->ptp_info.pin_config); 1094 1017 ptp->ptp_info.pin_config = NULL; 1095 1018 1096 - if (ptp->tx_skb) { 1097 - dev_kfree_skb_any(ptp->tx_skb); 1098 - ptp->tx_skb = NULL; 1019 + for (i = 0; i < BNXT_MAX_TX_TS; i++) { 1020 + if (ptp->txts_req[i].tx_skb) { 1021 + dev_kfree_skb_any(ptp->txts_req[i].tx_skb); 1022 + ptp->txts_req[i].tx_skb = NULL; 1023 + } 1099 1024 } 1100 1025 1101 1026 bnxt_unmap_ptp_regs(bp);
+28 -8
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
··· 85 85 atomic64_t ts_err; 86 86 }; 87 87 88 + #define BNXT_MAX_TX_TS 4 89 + #define NEXT_TXTS(idx) (((idx) + 1) & (BNXT_MAX_TX_TS - 1)) 90 + 91 + struct bnxt_ptp_tx_req { 92 + struct sk_buff *tx_skb; 93 + u16 tx_seqid; 94 + u16 tx_hdr_off; 95 + unsigned long abs_txts_tmo; 96 + }; 97 + 88 98 struct bnxt_ptp_cfg { 89 99 struct ptp_clock_info ptp_info; 90 100 struct ptp_clock *ptp_clock; ··· 103 93 struct bnxt_pps pps_info; 104 94 /* serialize timecounter access */ 105 95 spinlock_t ptp_lock; 106 - struct sk_buff *tx_skb; 96 + /* serialize ts tx request queuing */ 97 + spinlock_t ptp_tx_lock; 107 98 u64 current_time; 108 99 u64 old_time; 109 100 unsigned long next_period; ··· 113 102 /* a 23b shift cyclecounter will overflow in ~36 mins. Check overflow every 18 mins. */ 114 103 #define BNXT_PHC_OVERFLOW_PERIOD (18 * 60 * HZ) 115 104 116 - u16 tx_seqid; 117 - u16 tx_hdr_off; 105 + struct bnxt_ptp_tx_req txts_req[BNXT_MAX_TX_TS]; 106 + 118 107 struct bnxt *bp; 119 - atomic_t tx_avail; 120 - #define BNXT_MAX_TX_TS 1 108 + u32 tx_avail; 121 109 u16 rxctl; 122 110 #define BNXT_PTP_MSG_SYNC (1 << 0) 123 111 #define BNXT_PTP_MSG_DELAY_REQ (1 << 1) ··· 133 123 BNXT_PTP_MSG_PDELAY_REQ | \ 134 124 BNXT_PTP_MSG_PDELAY_RESP) 135 125 u8 tx_tstamp_en:1; 136 - u8 txts_pending:1; 137 126 int rx_filter; 138 127 u32 tstamp_filters; 139 128 140 129 u32 refclk_regs[2]; 141 130 u32 refclk_mapped_regs[2]; 142 131 u32 txts_tmo; 143 - unsigned long abs_txts_tmo; 132 + u16 txts_prod; 133 + u16 txts_cons; 144 134 145 135 struct bnxt_ptp_stats stats; 146 136 }; ··· 157 147 ((dst) = READ_ONCE(src)) 158 148 #endif 159 149 150 + #define BNXT_PTP_INC_TX_AVAIL(ptp) \ 151 + do { \ 152 + spin_lock_bh(&(ptp)->ptp_tx_lock); \ 153 + (ptp)->tx_avail++; \ 154 + spin_unlock_bh(&(ptp)->ptp_tx_lock); \ 155 + } while (0) 156 + 160 157 int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off); 161 158 void bnxt_ptp_update_current_time(struct bnxt *bp); 162 159 void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2); ··· 171 154 void bnxt_ptp_reapply_pps(struct bnxt *bp); 172 155 int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); 173 156 int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); 174 - int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb); 157 + int bnxt_ptp_get_txts_prod(struct bnxt_ptp_cfg *ptp, u16 *prod); 158 + void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod); 175 159 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); 160 + void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, 161 + struct tx_ts_cmp *tscmp); 176 162 void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns); 177 163 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg); 178 164 int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg);