Skip to content

Commit c6132f6

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Fix 64-bit doorbell operation on 32-bit kernels
The driver requires 64-bit doorbell writes to be atomic on 32-bit architectures. So we redefined writeq as a new macro with spinlock protection on 32-bit architectures. This created a new warning when we added a new file in a recent patchset. writeq is defined on many 32-bit architectures to do the memory write non-atomically and it generated a new macro redefined warning. This warning was fixed incorrectly in the recent patch. Fix this properly by adding a new bnxt_writeq() function that will do the non-atomic write under spinlock on 32-bit systems. All callers in the driver will now call bnxt_writeq() instead. v2: Need to pass in bp to bnxt_writeq() Use lo_hi_writeq() [suggested by Florian] Reported-by: kernel test robot <[email protected]> Fixes: f9ff578 ("bnxt_en: introduce new firmware message API based on DMA pools") Reviewed-by: Edwin Peer <[email protected]> Signed-off-by: Michael Chan <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9e9fb76 commit c6132f6

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,15 @@ static bool bnxt_vf_pciid(enum board_idx idx)
305305
writel(DB_CP_FLAGS | RING_CMP(idx), (db)->doorbell)
306306

307307
#define BNXT_DB_NQ_P5(db, idx) \
308-
writeq((db)->db_key64 | DBR_TYPE_NQ | RING_CMP(idx), (db)->doorbell)
308+
bnxt_writeq(bp, (db)->db_key64 | DBR_TYPE_NQ | RING_CMP(idx), \
309+
(db)->doorbell)
309310

310311
#define BNXT_DB_CQ_ARM(db, idx) \
311312
writel(DB_CP_REARM_FLAGS | RING_CMP(idx), (db)->doorbell)
312313

313314
#define BNXT_DB_NQ_ARM_P5(db, idx) \
314-
writeq((db)->db_key64 | DBR_TYPE_NQ_ARM | RING_CMP(idx), (db)->doorbell)
315+
bnxt_writeq(bp, (db)->db_key64 | DBR_TYPE_NQ_ARM | RING_CMP(idx),\
316+
(db)->doorbell)
315317

316318
static void bnxt_db_nq(struct bnxt *bp, struct bnxt_db_info *db, u32 idx)
317319
{
@@ -332,8 +334,8 @@ static void bnxt_db_nq_arm(struct bnxt *bp, struct bnxt_db_info *db, u32 idx)
332334
static void bnxt_db_cq(struct bnxt *bp, struct bnxt_db_info *db, u32 idx)
333335
{
334336
if (bp->flags & BNXT_FLAG_CHIP_P5)
335-
writeq(db->db_key64 | DBR_TYPE_CQ_ARMALL | RING_CMP(idx),
336-
db->doorbell);
337+
bnxt_writeq(bp, db->db_key64 | DBR_TYPE_CQ_ARMALL |
338+
RING_CMP(idx), db->doorbell);
337339
else
338340
BNXT_DB_CQ(db, idx);
339341
}
@@ -2638,8 +2640,8 @@ static void __bnxt_poll_cqs_done(struct bnxt *bp, struct bnxt_napi *bnapi,
26382640

26392641
if (cpr2 && cpr2->had_work_done) {
26402642
db = &cpr2->cp_db;
2641-
writeq(db->db_key64 | dbr_type |
2642-
RING_CMP(cpr2->cp_raw_cons), db->doorbell);
2643+
bnxt_writeq(bp, db->db_key64 | dbr_type |
2644+
RING_CMP(cpr2->cp_raw_cons), db->doorbell);
26432645
cpr2->had_work_done = 0;
26442646
}
26452647
}

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <net/dst_metadata.h>
2929
#include <net/xdp.h>
3030
#include <linux/dim.h>
31+
#include <linux/io-64-nonatomic-lo-hi.h>
3132
#ifdef CONFIG_TEE_BNXT_FW
3233
#include <linux/firmware/broadcom/tee_bnxt_fw.h>
3334
#endif
@@ -1981,7 +1982,7 @@ struct bnxt {
19811982
struct mutex sriov_lock;
19821983
#endif
19831984

1984-
#ifndef writeq
1985+
#if BITS_PER_LONG == 32
19851986
/* ensure atomic 64-bit doorbell writes on 32-bit systems. */
19861987
spinlock_t db_lock;
19871988
#endif
@@ -2110,24 +2111,36 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
21102111
((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
21112112
}
21122113

2113-
#ifndef writeq
2114-
#define writeq(val64, db) \
2115-
do { \
2116-
spin_lock(&bp->db_lock); \
2117-
writel((val64) & 0xffffffff, db); \
2118-
writel((val64) >> 32, (db) + 4); \
2119-
spin_unlock(&bp->db_lock); \
2120-
} while (0)
2114+
static inline void bnxt_writeq(struct bnxt *bp, u64 val,
2115+
volatile void __iomem *addr)
2116+
{
2117+
#if BITS_PER_LONG == 32
2118+
spin_lock(&bp->db_lock);
2119+
lo_hi_writeq(val, addr);
2120+
spin_unlock(&bp->db_lock);
2121+
#else
2122+
writeq(val, addr);
2123+
#endif
2124+
}
21212125

2122-
#define writeq_relaxed writeq
2126+
static inline void bnxt_writeq_relaxed(struct bnxt *bp, u64 val,
2127+
volatile void __iomem *addr)
2128+
{
2129+
#if BITS_PER_LONG == 32
2130+
spin_lock(&bp->db_lock);
2131+
lo_hi_writeq_relaxed(val, addr);
2132+
spin_unlock(&bp->db_lock);
2133+
#else
2134+
writeq_relaxed(val, addr);
21232135
#endif
2136+
}
21242137

21252138
/* For TX and RX ring doorbells with no ordering guarantee*/
21262139
static inline void bnxt_db_write_relaxed(struct bnxt *bp,
21272140
struct bnxt_db_info *db, u32 idx)
21282141
{
21292142
if (bp->flags & BNXT_FLAG_CHIP_P5) {
2130-
writeq_relaxed(db->db_key64 | idx, db->doorbell);
2143+
bnxt_writeq_relaxed(bp, db->db_key64 | idx, db->doorbell);
21312144
} else {
21322145
u32 db_val = db->db_key32 | idx;
21332146

@@ -2142,7 +2155,7 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db,
21422155
u32 idx)
21432156
{
21442157
if (bp->flags & BNXT_FLAG_CHIP_P5) {
2145-
writeq(db->db_key64 | idx, db->doorbell);
2158+
bnxt_writeq(bp, db->db_key64 | idx, db->doorbell);
21462159
} else {
21472160
u32 db_val = db->db_key32 | idx;
21482161

0 commit comments

Comments
 (0)