Skip to content

Commit 6968437

Browse files
ahduyckkuba-moo
authored andcommitted
eth: fbnic: Add link detection
Add basic support for detecting the link and reporting it at the netdev layer. For now we will just use the values reporeted by the firmware as the link configuration and assume that is the current configuration of the MAC and PCS. With this we start the stubbing out of the phylink interface that will be used to provide the configuration interface for ethtool in a future patch set. The phylink interface isn't an exact fit. As such we are currently working around several issues in this patch set that we plan to address in the future such as: 1. Support for FEC 2. Support for multiple lanes to handle 50GbaseR2 vs 50GbaseR1 3. Support for BMC CC: Russell King <[email protected]> CC: Andrew Lunn <[email protected]> Signed-off-by: Alexander Duyck <[email protected]> Link: https://patch.msgid.link/172079939835.1778861.5964790909718481811.stgit@ahduyck-xeon-server.home.arpa Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 20d2e88 commit 6968437

File tree

12 files changed

+629
-0
lines changed

12 files changed

+629
-0
lines changed

drivers/net/ethernet/meta/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ config FBNIC
2121
tristate "Meta Platforms Host Network Interface"
2222
depends on X86_64 || COMPILE_TEST
2323
depends on PCI_MSI
24+
select PHYLINK
2425
help
2526
This driver supports Meta Platforms Host Network Interface.
2627

drivers/net/ethernet/meta/fbnic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ fbnic-y := fbnic_devlink.o \
1313
fbnic_mac.o \
1414
fbnic_netdev.o \
1515
fbnic_pci.o \
16+
fbnic_phylink.o \
1617
fbnic_tlv.o \
1718
fbnic_txrx.o

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct fbnic_dev {
2121
u32 __iomem *uc_addr4;
2222
const struct fbnic_mac *mac;
2323
unsigned int fw_msix_vector;
24+
unsigned int pcs_msix_vector;
2425
unsigned short num_irqs;
2526

2627
struct delayed_work service_task;
@@ -49,6 +50,7 @@ struct fbnic_dev {
4950
*/
5051
enum {
5152
FBNIC_FW_MSIX_ENTRY,
53+
FBNIC_PCS_MSIX_ENTRY,
5254
FBNIC_NON_NAPI_VECTORS
5355
};
5456

@@ -95,6 +97,11 @@ void fbnic_fw_wr32(struct fbnic_dev *fbd, u32 reg, u32 val);
9597
#define fw_wr32(_f, _r, _v) fbnic_fw_wr32(_f, _r, _v)
9698
#define fw_wrfl(_f) fbnic_fw_rd32(_f, FBNIC_FW_ZERO_REG)
9799

100+
static inline bool fbnic_bmc_present(struct fbnic_dev *fbd)
101+
{
102+
return fbd->fw_cap.bmc_present;
103+
}
104+
98105
static inline bool fbnic_init_failure(struct fbnic_dev *fbd)
99106
{
100107
return !fbd->netdev;
@@ -110,6 +117,9 @@ void fbnic_devlink_unregister(struct fbnic_dev *fbd);
110117
int fbnic_fw_enable_mbx(struct fbnic_dev *fbd);
111118
void fbnic_fw_disable_mbx(struct fbnic_dev *fbd);
112119

120+
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
121+
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);
122+
113123
int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler,
114124
unsigned long flags, const char *name, void *data);
115125
void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data);

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@
8585
#define FBNIC_INTR_MSIX_CTRL(n) (0x00040 + (n)) /* 0x00100 + 4*n */
8686
#define FBNIC_INTR_MSIX_CTRL_VECTOR_MASK CSR_GENMASK(7, 0)
8787
#define FBNIC_INTR_MSIX_CTRL_ENABLE CSR_BIT(31)
88+
enum {
89+
FBNIC_INTR_MSIX_CTRL_PCS_IDX = 34,
90+
};
8891

8992
#define FBNIC_CSR_END_INTR 0x0005f /* CSR section delimiter */
9093

@@ -419,6 +422,42 @@ enum {
419422
#define FBNIC_MASTER_SPARE_0 0x0C41B /* 0x3106c */
420423
#define FBNIC_CSR_END_MASTER 0x0C452 /* CSR section delimiter */
421424

425+
/* MAC MAC registers (ASIC only) */
426+
#define FBNIC_CSR_START_MAC_MAC 0x11000 /* CSR section delimiter */
427+
#define FBNIC_MAC_COMMAND_CONFIG 0x11002 /* 0x44008 */
428+
#define FBNIC_MAC_COMMAND_CONFIG_RX_PAUSE_DIS CSR_BIT(29)
429+
#define FBNIC_MAC_COMMAND_CONFIG_TX_PAUSE_DIS CSR_BIT(28)
430+
#define FBNIC_MAC_COMMAND_CONFIG_FLT_HDL_DIS CSR_BIT(27)
431+
#define FBNIC_MAC_COMMAND_CONFIG_TX_PAD_EN CSR_BIT(11)
432+
#define FBNIC_MAC_COMMAND_CONFIG_LOOPBACK_EN CSR_BIT(10)
433+
#define FBNIC_MAC_COMMAND_CONFIG_PROMISC_EN CSR_BIT(4)
434+
#define FBNIC_MAC_COMMAND_CONFIG_RX_ENA CSR_BIT(1)
435+
#define FBNIC_MAC_COMMAND_CONFIG_TX_ENA CSR_BIT(0)
436+
#define FBNIC_MAC_CL01_PAUSE_QUANTA 0x11015 /* 0x44054 */
437+
#define FBNIC_MAC_CL01_QUANTA_THRESH 0x11019 /* 0x44064 */
438+
#define FBNIC_CSR_END_MAC_MAC 0x11028 /* CSR section delimiter */
439+
440+
/* Signals from MAC, AN, PCS, and LED CSR registers (ASIC only) */
441+
#define FBNIC_CSR_START_SIG 0x11800 /* CSR section delimiter */
442+
#define FBNIC_SIG_MAC_IN0 0x11800 /* 0x46000 */
443+
#define FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK CSR_BIT(14)
444+
#define FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK CSR_BIT(13)
445+
#define FBNIC_SIG_MAC_IN0_RESET_TX_CLK CSR_BIT(12)
446+
#define FBNIC_SIG_MAC_IN0_RESET_RX_CLK CSR_BIT(11)
447+
#define FBNIC_SIG_MAC_IN0_TX_CRC CSR_BIT(8)
448+
#define FBNIC_SIG_MAC_IN0_CFG_MODE128 CSR_BIT(10)
449+
#define FBNIC_SIG_PCS_OUT0 0x11808 /* 0x46020 */
450+
#define FBNIC_SIG_PCS_OUT0_LINK CSR_BIT(27)
451+
#define FBNIC_SIG_PCS_OUT0_BLOCK_LOCK CSR_GENMASK(24, 5)
452+
#define FBNIC_SIG_PCS_OUT0_AMPS_LOCK CSR_GENMASK(4, 1)
453+
#define FBNIC_SIG_PCS_OUT1 0x11809 /* 0x46024 */
454+
#define FBNIC_SIG_PCS_OUT1_FCFEC_LOCK CSR_GENMASK(11, 8)
455+
#define FBNIC_SIG_PCS_INTR_STS 0x11814 /* 0x46050 */
456+
#define FBNIC_SIG_PCS_INTR_LINK_DOWN CSR_BIT(1)
457+
#define FBNIC_SIG_PCS_INTR_LINK_UP CSR_BIT(0)
458+
#define FBNIC_SIG_PCS_INTR_MASK 0x11816 /* 0x46058 */
459+
#define FBNIC_CSR_END_SIG 0x1184e /* CSR section delimiter */
460+
422461
/* PUL User Registers */
423462
#define FBNIC_CSR_START_PUL_USER 0x31000 /* CSR section delimiter */
424463
#define FBNIC_PUL_OB_TLP_HDR_AW_CFG 0x3103d /* 0xc40f4 */

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,19 @@ enum {
104104
FBNIC_FW_CAP_RESP_MSG_MAX
105105
};
106106

107+
enum {
108+
FBNIC_FW_LINK_SPEED_25R1 = 1,
109+
FBNIC_FW_LINK_SPEED_50R2 = 2,
110+
FBNIC_FW_LINK_SPEED_50R1 = 3,
111+
FBNIC_FW_LINK_SPEED_100R2 = 4,
112+
};
113+
114+
enum {
115+
FBNIC_FW_LINK_FEC_NONE = 1,
116+
FBNIC_FW_LINK_FEC_RS = 2,
117+
FBNIC_FW_LINK_FEC_BASER = 3,
118+
};
119+
107120
enum {
108121
FBNIC_FW_OWNERSHIP_FLAG = 0x0,
109122
FBNIC_FW_OWNERSHIP_MSG_MAX

drivers/net/ethernet/meta/fbnic/fbnic_irq.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/types.h>
66

77
#include "fbnic.h"
8+
#include "fbnic_netdev.h"
89
#include "fbnic_txrx.h"
910

1011
static irqreturn_t fbnic_fw_msix_intr(int __always_unused irq, void *data)
@@ -81,6 +82,70 @@ void fbnic_fw_disable_mbx(struct fbnic_dev *fbd)
8182
fbnic_mbx_clean(fbd);
8283
}
8384

85+
static irqreturn_t fbnic_pcs_msix_intr(int __always_unused irq, void *data)
86+
{
87+
struct fbnic_dev *fbd = data;
88+
struct fbnic_net *fbn;
89+
90+
if (fbd->mac->pcs_get_link_event(fbd) == FBNIC_LINK_EVENT_NONE) {
91+
fbnic_wr32(fbd, FBNIC_INTR_MASK_CLEAR(0),
92+
1u << FBNIC_PCS_MSIX_ENTRY);
93+
return IRQ_HANDLED;
94+
}
95+
96+
fbn = netdev_priv(fbd->netdev);
97+
98+
phylink_pcs_change(&fbn->phylink_pcs, false);
99+
100+
return IRQ_HANDLED;
101+
}
102+
103+
/**
104+
* fbnic_pcs_irq_enable - Configure the MAC to enable it to advertise link
105+
* @fbd: Pointer to device to initialize
106+
*
107+
* This function provides basic bringup for the MAC/PCS IRQ. For now the IRQ
108+
* will remain disabled until we start the MAC/PCS/PHY logic via phylink.
109+
*
110+
* Return: non-zero on failure.
111+
**/
112+
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd)
113+
{
114+
u32 vector = fbd->pcs_msix_vector;
115+
int err;
116+
117+
/* Request the IRQ for MAC link vector.
118+
* Map MAC cause to it, and unmask it
119+
*/
120+
err = request_irq(vector, &fbnic_pcs_msix_intr, 0,
121+
fbd->netdev->name, fbd);
122+
if (err)
123+
return err;
124+
125+
fbnic_wr32(fbd, FBNIC_INTR_MSIX_CTRL(FBNIC_INTR_MSIX_CTRL_PCS_IDX),
126+
FBNIC_PCS_MSIX_ENTRY | FBNIC_INTR_MSIX_CTRL_ENABLE);
127+
128+
return 0;
129+
}
130+
131+
/**
132+
* fbnic_pcs_irq_disable - Teardown the MAC IRQ to prepare for stopping
133+
* @fbd: Pointer to device that is stopping
134+
*
135+
* This function undoes the work done in fbnic_pcs_irq_enable and prepares
136+
* the device to no longer receive traffic on the host interface.
137+
**/
138+
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd)
139+
{
140+
/* Disable interrupt */
141+
fbnic_wr32(fbd, FBNIC_INTR_MSIX_CTRL(FBNIC_INTR_MSIX_CTRL_PCS_IDX),
142+
FBNIC_PCS_MSIX_ENTRY);
143+
fbnic_wr32(fbd, FBNIC_INTR_MASK_SET(0), 1u << FBNIC_PCS_MSIX_ENTRY);
144+
145+
/* Free the vector */
146+
free_irq(fbd->pcs_msix_vector, fbd);
147+
}
148+
84149
int fbnic_request_irq(struct fbnic_dev *fbd, int nr, irq_handler_t handler,
85150
unsigned long flags, const char *name, void *data)
86151
{
@@ -108,6 +173,7 @@ void fbnic_free_irqs(struct fbnic_dev *fbd)
108173
{
109174
struct pci_dev *pdev = to_pci_dev(fbd->dev);
110175

176+
fbd->pcs_msix_vector = 0;
111177
fbd->fw_msix_vector = 0;
112178

113179
fbd->num_irqs = 0;
@@ -135,6 +201,7 @@ int fbnic_alloc_irqs(struct fbnic_dev *fbd)
135201

136202
fbd->num_irqs = num_irqs;
137203

204+
fbd->pcs_msix_vector = pci_irq_vector(pdev, FBNIC_PCS_MSIX_ENTRY);
138205
fbd->fw_msix_vector = pci_irq_vector(pdev, FBNIC_FW_MSIX_ENTRY);
139206

140207
return 0;

0 commit comments

Comments
 (0)