Skip to content

Commit da3cde0

Browse files
ahduyckkuba-moo
authored andcommitted
eth: fbnic: Add FW communication mechanism
Add a mechanism for sending messages to and receiving messages from the FW. The FW has fairly limited functionality, so the mechanism doesn't have to support high message rate. Use device mailbox registers to form two rings, one "to" and one "from" the device. The rings are just a convention between driver and FW, not a HW construct. We don't expect messages larger than 4k so use page-sized buffers. Signed-off-by: Alexander Duyck <alexanderduyck@fb.com> Link: https://patch.msgid.link/172079937113.1778861.10669864213768701947.stgit@ahduyck-xeon-server.home.arpa Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c6203e6 commit da3cde0

File tree

7 files changed

+641
-0
lines changed

7 files changed

+641
-0
lines changed

drivers/net/ethernet/meta/fbnic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
obj-$(CONFIG_FBNIC) += fbnic.o
99

1010
fbnic-y := fbnic_devlink.o \
11+
fbnic_fw.o \
1112
fbnic_irq.o \
1213
fbnic_mac.o \
1314
fbnic_pci.o \

drivers/net/ethernet/meta/fbnic/fbnic.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/io.h>
88

99
#include "fbnic_csr.h"
10+
#include "fbnic_fw.h"
1011
#include "fbnic_mac.h"
1112

1213
struct fbnic_dev {
@@ -15,8 +16,13 @@ struct fbnic_dev {
1516
u32 __iomem *uc_addr0;
1617
u32 __iomem *uc_addr4;
1718
const struct fbnic_mac *mac;
19+
unsigned int fw_msix_vector;
1820
unsigned short num_irqs;
1921

22+
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
23+
/* Lock protecting Tx Mailbox queue to prevent possible races */
24+
spinlock_t fw_tx_lock;
25+
2026
u64 dsn;
2127
u32 mps;
2228
u32 readrq;
@@ -28,6 +34,7 @@ struct fbnic_dev {
2834
* causes later.
2935
*/
3036
enum {
37+
FBNIC_FW_MSIX_ENTRY,
3138
FBNIC_NON_NAPI_VECTORS
3239
};
3340

@@ -66,13 +73,24 @@ fbnic_rmw32(struct fbnic_dev *fbd, u32 reg, u32 mask, u32 val)
6673
#define rd32(_f, _r) fbnic_rd32(_f, _r)
6774
#define wrfl(_f) fbnic_wrfl(_f)
6875

76+
bool fbnic_fw_present(struct fbnic_dev *fbd);
77+
u32 fbnic_fw_rd32(struct fbnic_dev *fbd, u32 reg);
78+
void fbnic_fw_wr32(struct fbnic_dev *fbd, u32 reg, u32 val);
79+
80+
#define fw_rd32(_f, _r) fbnic_fw_rd32(_f, _r)
81+
#define fw_wr32(_f, _r, _v) fbnic_fw_wr32(_f, _r, _v)
82+
#define fw_wrfl(_f) fbnic_fw_rd32(_f, FBNIC_FW_ZERO_REG)
83+
6984
extern char fbnic_driver_name[];
7085

7186
void fbnic_devlink_free(struct fbnic_dev *fbd);
7287
struct fbnic_dev *fbnic_devlink_alloc(struct pci_dev *pdev);
7388
void fbnic_devlink_register(struct fbnic_dev *fbd);
7489
void fbnic_devlink_unregister(struct fbnic_dev *fbd);
7590

91+
int fbnic_fw_enable_mbx(struct fbnic_dev *fbd);
92+
void fbnic_fw_disable_mbx(struct fbnic_dev *fbd);
93+
7694
void fbnic_free_irqs(struct fbnic_dev *fbd);
7795
int fbnic_alloc_irqs(struct fbnic_dev *fbd);
7896

drivers/net/ethernet/meta/fbnic/fbnic_csr.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,60 @@
99
#define CSR_BIT(nr) (1u << (nr))
1010
#define CSR_GENMASK(h, l) GENMASK(h, l)
1111

12+
#define DESC_BIT(nr) BIT_ULL(nr)
13+
#define DESC_GENMASK(h, l) GENMASK_ULL(h, l)
14+
1215
#define PCI_DEVICE_ID_META_FBNIC_ASIC 0x0013
1316

1417
#define FBNIC_CLOCK_FREQ (600 * (1000 * 1000))
1518

19+
/* Register Definitions
20+
*
21+
* The registers are laid as indexes into an le32 array. As such the actual
22+
* address is 4 times the index value. Below each register is defined as 3
23+
* fields, name, index, and Address.
24+
*
25+
* Name Index Address
26+
*************************************************************************/
27+
/* Interrupt Registers */
28+
#define FBNIC_CSR_START_INTR 0x00000 /* CSR section delimiter */
29+
#define FBNIC_INTR_STATUS(n) (0x00000 + (n)) /* 0x00000 + 4*n */
30+
#define FBNIC_INTR_STATUS_CNT 8
31+
#define FBNIC_INTR_MASK(n) (0x00008 + (n)) /* 0x00020 + 4*n */
32+
#define FBNIC_INTR_MASK_CNT 8
33+
#define FBNIC_INTR_SET(n) (0x00010 + (n)) /* 0x00040 + 4*n */
34+
#define FBNIC_INTR_SET_CNT 8
35+
#define FBNIC_INTR_CLEAR(n) (0x00018 + (n)) /* 0x00060 + 4*n */
36+
#define FBNIC_INTR_CLEAR_CNT 8
37+
#define FBNIC_INTR_SW_STATUS(n) (0x00020 + (n)) /* 0x00080 + 4*n */
38+
#define FBNIC_INTR_SW_STATUS_CNT 8
39+
#define FBNIC_INTR_SW_AC_MODE(n) (0x00028 + (n)) /* 0x000a0 + 4*n */
40+
#define FBNIC_INTR_SW_AC_MODE_CNT 8
41+
#define FBNIC_INTR_MASK_SET(n) (0x00030 + (n)) /* 0x000c0 + 4*n */
42+
#define FBNIC_INTR_MASK_SET_CNT 8
43+
#define FBNIC_INTR_MASK_CLEAR(n) (0x00038 + (n)) /* 0x000e0 + 4*n */
44+
#define FBNIC_INTR_MASK_CLEAR_CNT 8
45+
#define FBNIC_MAX_MSIX_VECS 256U
46+
#define FBNIC_INTR_MSIX_CTRL(n) (0x00040 + (n)) /* 0x00100 + 4*n */
47+
#define FBNIC_INTR_MSIX_CTRL_VECTOR_MASK CSR_GENMASK(7, 0)
48+
#define FBNIC_INTR_MSIX_CTRL_ENABLE CSR_BIT(31)
49+
50+
#define FBNIC_CSR_END_INTR 0x0005f /* CSR section delimiter */
51+
52+
/* Interrupt MSIX Registers */
53+
#define FBNIC_CSR_START_INTR_CQ 0x00400 /* CSR section delimiter */
54+
#define FBNIC_INTR_CQ_REARM(n) \
55+
(0x00400 + 4 * (n)) /* 0x01000 + 16*n */
56+
#define FBNIC_INTR_CQ_REARM_CNT 256
57+
#define FBNIC_INTR_CQ_REARM_RCQ_TIMEOUT CSR_GENMASK(13, 0)
58+
#define FBNIC_INTR_CQ_REARM_RCQ_TIMEOUT_UPD_EN CSR_BIT(14)
59+
#define FBNIC_INTR_CQ_REARM_TCQ_TIMEOUT CSR_GENMASK(28, 15)
60+
#define FBNIC_INTR_CQ_REARM_TCQ_TIMEOUT_UPD_EN CSR_BIT(29)
61+
#define FBNIC_INTR_CQ_REARM_INTR_RELOAD CSR_BIT(30)
62+
#define FBNIC_INTR_CQ_REARM_INTR_UNMASK CSR_BIT(31)
63+
64+
#define FBNIC_CSR_END_INTR_CQ 0x007fe /* CSR section delimiter */
65+
1666
/* Global QM Tx registers */
1767
#define FBNIC_CSR_START_QM_TX 0x00800 /* CSR section delimiter */
1868
#define FBNIC_QM_TWQ_DEFAULT_META_L 0x00818 /* 0x02060 */
@@ -318,4 +368,33 @@ enum {
318368

319369
#define FBNIC_MAX_QUEUES 128
320370

371+
/* BAR 4 CSRs */
372+
373+
/* The IPC mailbox consists of 32 mailboxes, with each mailbox consisting
374+
* of 32 4 byte registers. We will use 2 registers per descriptor so the
375+
* length of the mailbox is reduced to 16.
376+
*
377+
* Currently we use an offset of 0x6000 on BAR4 for the mailbox so we just
378+
* have to do the math and determine the offset based on the mailbox
379+
* direction and index inside that mailbox.
380+
*/
381+
#define FBNIC_IPC_MBX_DESC_LEN 16
382+
#define FBNIC_IPC_MBX(mbx_idx, desc_idx) \
383+
((((mbx_idx) * FBNIC_IPC_MBX_DESC_LEN + (desc_idx)) * 2) + 0x6000)
384+
385+
/* Use first register in mailbox to flush writes */
386+
#define FBNIC_FW_ZERO_REG FBNIC_IPC_MBX(0, 0)
387+
388+
enum {
389+
FBNIC_IPC_MBX_RX_IDX,
390+
FBNIC_IPC_MBX_TX_IDX,
391+
FBNIC_IPC_MBX_INDICES,
392+
};
393+
394+
#define FBNIC_IPC_MBX_DESC_LEN_MASK DESC_GENMASK(63, 48)
395+
#define FBNIC_IPC_MBX_DESC_EOM DESC_BIT(46)
396+
#define FBNIC_IPC_MBX_DESC_ADDR_MASK DESC_GENMASK(45, 3)
397+
#define FBNIC_IPC_MBX_DESC_FW_CMPL DESC_BIT(1)
398+
#define FBNIC_IPC_MBX_DESC_HOST_CMPL DESC_BIT(0)
399+
321400
#endif /* _FBNIC_CSR_H_ */

0 commit comments

Comments
 (0)