Skip to content

Commit 8aa2a79

Browse files
Pavan Chebbidavem330
authored andcommitted
bnxt_en: Increase the max total outstanding PTP TX packets to 4
Start accepting up to 4 TX TS requests on BCM5750X (P5) chips. These PTP TX packets will be queued in the ptp->txts_req[] array waiting for the TX timestamp to complete. The entries in the array will be managed by a producer and consumer index. The producer index is updated under spinlock since multiple TX rings can try to send PTP packets at the same time. Signed-off-by: Pavan Chebbi <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9bf688d commit 8aa2a79

File tree

4 files changed

+68
-30
lines changed

4 files changed

+68
-30
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
457457
unsigned int length, pad = 0;
458458
u32 len, free_size, vlan_tag_flags, cfa_action, flags;
459459
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
460-
u16 prod, last_frag;
461460
struct pci_dev *pdev = bp->pdev;
461+
u16 prod, last_frag, txts_prod;
462462
struct bnxt_tx_ring_info *txr;
463463
struct bnxt_sw_tx_bd *tx_buf;
464464
__le32 lflags = 0;
@@ -527,11 +527,19 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
527527
if (!bnxt_ptp_parse(skb, &seq_id, &hdr_off)) {
528528
if (vlan_tag_flags)
529529
hdr_off += VLAN_HLEN;
530-
ptp->txts_req.tx_seqid = seq_id;
531-
ptp->txts_req.tx_hdr_off = hdr_off;
532530
lflags |= cpu_to_le32(TX_BD_FLAGS_STAMP);
533531
tx_buf->is_ts_pkt = 1;
534532
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
533+
534+
spin_lock_bh(&ptp->ptp_tx_lock);
535+
txts_prod = ptp->txts_prod;
536+
ptp->txts_prod = NEXT_TXTS(txts_prod);
537+
spin_unlock_bh(&ptp->ptp_tx_lock);
538+
539+
ptp->txts_req[txts_prod].tx_seqid = seq_id;
540+
ptp->txts_req[txts_prod].tx_hdr_off = hdr_off;
541+
tx_buf->txts_prod = txts_prod;
542+
535543
} else {
536544
atomic_inc(&bp->ptp_cfg->tx_avail);
537545
}
@@ -769,7 +777,9 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
769777
if (BNXT_TX_PTP_IS_SET(lflags)) {
770778
txr->tx_buf_ring[txr->tx_prod].is_ts_pkt = 0;
771779
atomic64_inc(&bp->ptp_cfg->stats.ts_err);
772-
atomic_inc(&bp->ptp_cfg->tx_avail);
780+
if (!(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
781+
/* set SKB to err so PTP worker will clean up */
782+
ptp->txts_req[txts_prod].tx_skb = ERR_PTR(-EIO);
773783
}
774784
if (txr->kick_pending)
775785
bnxt_txr_db_kick(bp, txr, txr->tx_prod);
@@ -837,7 +847,7 @@ static bool __bnxt_tx_int(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
837847
if (unlikely(is_ts_pkt)) {
838848
if (BNXT_CHIP_P5(bp)) {
839849
/* PTP worker takes ownership of the skb */
840-
bnxt_get_tx_ts_p5(bp, skb);
850+
bnxt_get_tx_ts_p5(bp, skb, tx_buf->txts_prod);
841851
skb = NULL;
842852
}
843853
}

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,10 @@ struct bnxt_sw_tx_bd {
878878
u8 is_push;
879879
u8 action;
880880
unsigned short nr_frags;
881-
u16 rx_prod;
881+
union {
882+
u16 rx_prod;
883+
u16 txts_prod;
884+
};
882885
};
883886

884887
struct bnxt_sw_rx_bd {

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static void bnxt_ptp_get_current_time(struct bnxt *bp)
110110
}
111111

112112
static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
113-
u32 txts_tmo)
113+
u32 txts_tmo, int slot)
114114
{
115115
struct hwrm_port_ts_query_output *resp;
116116
struct hwrm_port_ts_query_input *req;
@@ -123,7 +123,7 @@ static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
123123
req->flags = cpu_to_le32(flags);
124124
if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) ==
125125
PORT_TS_QUERY_REQ_FLAGS_PATH_TX) {
126-
struct bnxt_ptp_tx_req *txts_req = &bp->ptp_cfg->txts_req;
126+
struct bnxt_ptp_tx_req *txts_req = &bp->ptp_cfg->txts_req[slot];
127127
u32 tmo_us = txts_tmo * 1000;
128128

129129
req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES);
@@ -683,7 +683,7 @@ static u64 bnxt_cc_read(const struct cyclecounter *cc)
683683
return ns;
684684
}
685685

686-
static int bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
686+
static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot)
687687
{
688688
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
689689
struct skb_shared_hwtstamps timestamp;
@@ -693,13 +693,13 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
693693
u32 tmo = 0;
694694
int rc;
695695

696-
txts_req = &ptp->txts_req;
697-
if (!txts_req->txts_pending)
698-
txts_req->abs_txts_tmo = now + msecs_to_jiffies(ptp->txts_tmo);
696+
txts_req = &ptp->txts_req[slot];
697+
/* make sure bnxt_get_tx_ts_p5() has updated abs_txts_tmo */
698+
smp_rmb();
699699
if (!time_after_eq(now, txts_req->abs_txts_tmo))
700700
tmo = jiffies_to_msecs(txts_req->abs_txts_tmo - now);
701701
rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts,
702-
tmo);
702+
tmo, slot);
703703
if (!rc) {
704704
memset(&timestamp, 0, sizeof(timestamp));
705705
spin_lock_bh(&ptp->ptp_lock);
@@ -709,19 +709,16 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
709709
skb_tstamp_tx(txts_req->tx_skb, &timestamp);
710710
ptp->stats.ts_pkts++;
711711
} else {
712-
if (!time_after_eq(jiffies, txts_req->abs_txts_tmo)) {
713-
txts_req->txts_pending = true;
712+
if (!time_after_eq(jiffies, txts_req->abs_txts_tmo))
714713
return -EAGAIN;
715-
}
714+
716715
ptp->stats.ts_lost++;
717716
netdev_warn_once(bp->dev,
718717
"TS query for TX timer failed rc = %x\n", rc);
719718
}
720719

721720
dev_kfree_skb_any(txts_req->tx_skb);
722721
txts_req->tx_skb = NULL;
723-
atomic_inc(&ptp->tx_avail);
724-
txts_req->txts_pending = false;
725722

726723
return 0;
727724
}
@@ -732,10 +729,24 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
732729
ptp_info);
733730
unsigned long now = jiffies;
734731
struct bnxt *bp = ptp->bp;
732+
u16 cons = ptp->txts_cons;
733+
u8 num_requests;
735734
int rc = 0;
736735

737-
if (ptp->txts_req.tx_skb)
738-
rc = bnxt_stamp_tx_skb(bp, ptp->txts_req.tx_skb);
736+
num_requests = BNXT_MAX_TX_TS - atomic_read(&ptp->tx_avail);
737+
while (num_requests--) {
738+
if (IS_ERR(ptp->txts_req[cons].tx_skb))
739+
goto next_slot;
740+
if (!ptp->txts_req[cons].tx_skb)
741+
break;
742+
rc = bnxt_stamp_tx_skb(bp, cons);
743+
if (rc == -EAGAIN)
744+
break;
745+
next_slot:
746+
atomic_inc(&ptp->tx_avail);
747+
cons = NEXT_TXTS(cons);
748+
}
749+
ptp->txts_cons = cons;
739750

740751
if (!time_after_eq(now, ptp->next_period)) {
741752
if (rc == -EAGAIN)
@@ -756,11 +767,16 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
756767
return HZ;
757768
}
758769

759-
void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb)
770+
void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod)
760771
{
761772
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
773+
struct bnxt_ptp_tx_req *txts_req;
762774

763-
ptp->txts_req.tx_skb = skb;
775+
txts_req = &ptp->txts_req[prod];
776+
txts_req->abs_txts_tmo = jiffies + msecs_to_jiffies(ptp->txts_tmo);
777+
/* make sure abs_txts_tmo is written first */
778+
smp_wmb();
779+
txts_req->tx_skb = skb;
764780
ptp_schedule_worker(ptp->ptp_clock, 0);
765781
}
766782

@@ -958,7 +974,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
958974
return rc;
959975
} else {
960976
rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME,
961-
&ns, 0);
977+
&ns, 0, 0);
962978
if (rc)
963979
return rc;
964980
}
@@ -1000,6 +1016,7 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
10001016

10011017
atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
10021018
spin_lock_init(&ptp->ptp_lock);
1019+
spin_lock_init(&ptp->ptp_tx_lock);
10031020

10041021
if (BNXT_PTP_USE_RTC(bp)) {
10051022
bnxt_ptp_timecounter_init(bp, false);
@@ -1049,6 +1066,7 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
10491066
void bnxt_ptp_clear(struct bnxt *bp)
10501067
{
10511068
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
1069+
int i;
10521070

10531071
if (!ptp)
10541072
return;
@@ -1060,9 +1078,11 @@ void bnxt_ptp_clear(struct bnxt *bp)
10601078
kfree(ptp->ptp_info.pin_config);
10611079
ptp->ptp_info.pin_config = NULL;
10621080

1063-
if (ptp->txts_req.tx_skb) {
1064-
dev_kfree_skb_any(ptp->txts_req.tx_skb);
1065-
ptp->txts_req.tx_skb = NULL;
1081+
for (i = 0; i < BNXT_MAX_TX_TS; i++) {
1082+
if (ptp->txts_req[i].tx_skb) {
1083+
dev_kfree_skb_any(ptp->txts_req[i].tx_skb);
1084+
ptp->txts_req[i].tx_skb = NULL;
1085+
}
10661086
}
10671087

10681088
bnxt_unmap_ptp_regs(bp);

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ struct bnxt_ptp_stats {
8585
atomic64_t ts_err;
8686
};
8787

88+
#define BNXT_MAX_TX_TS 4
89+
#define NEXT_TXTS(idx) (((idx) + 1) & (BNXT_MAX_TX_TS - 1))
90+
8891
struct bnxt_ptp_tx_req {
8992
struct sk_buff *tx_skb;
9093
u16 tx_seqid;
9194
u16 tx_hdr_off;
92-
u8 txts_pending:1;
9395
unsigned long abs_txts_tmo;
9496
};
9597

@@ -101,6 +103,8 @@ struct bnxt_ptp_cfg {
101103
struct bnxt_pps pps_info;
102104
/* serialize timecounter access */
103105
spinlock_t ptp_lock;
106+
/* serialize ts tx request queuing */
107+
spinlock_t ptp_tx_lock;
104108
u64 current_time;
105109
u64 old_time;
106110
unsigned long next_period;
@@ -109,11 +113,10 @@ struct bnxt_ptp_cfg {
109113
/* a 23b shift cyclecounter will overflow in ~36 mins. Check overflow every 18 mins. */
110114
#define BNXT_PHC_OVERFLOW_PERIOD (18 * 60 * HZ)
111115

112-
struct bnxt_ptp_tx_req txts_req;
116+
struct bnxt_ptp_tx_req txts_req[BNXT_MAX_TX_TS];
113117

114118
struct bnxt *bp;
115119
atomic_t tx_avail;
116-
#define BNXT_MAX_TX_TS 1
117120
u16 rxctl;
118121
#define BNXT_PTP_MSG_SYNC (1 << 0)
119122
#define BNXT_PTP_MSG_DELAY_REQ (1 << 1)
@@ -136,6 +139,8 @@ struct bnxt_ptp_cfg {
136139
u32 refclk_regs[2];
137140
u32 refclk_mapped_regs[2];
138141
u32 txts_tmo;
142+
u16 txts_prod;
143+
u16 txts_cons;
139144

140145
struct bnxt_ptp_stats stats;
141146
};
@@ -159,7 +164,7 @@ int bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp);
159164
void bnxt_ptp_reapply_pps(struct bnxt *bp);
160165
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
161166
int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
162-
void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb);
167+
void bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb, u16 prod);
163168
int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
164169
void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi,
165170
struct tx_ts_cmp *tscmp);

0 commit comments

Comments
 (0)