1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
4 #include <linux/bitfield.h>
9 #include "fbnic_netdev.h"
11 static void fbnic_init_readrq(struct fbnic_dev
*fbd
, unsigned int offset
,
12 unsigned int cls
, unsigned int readrq
)
14 u32 val
= rd32(fbd
, offset
);
16 /* The TDF_CTL masks are a superset of the RNI_RBP ones. So we can
17 * use them when setting either the TDE_CTF or RNI_RBP registers.
19 val
&= FBNIC_QM_TNI_TDF_CTL_MAX_OT
| FBNIC_QM_TNI_TDF_CTL_MAX_OB
;
21 val
|= FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_MRRS
, readrq
) |
22 FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_CLS
, cls
);
24 wr32(fbd
, offset
, val
);
27 static void fbnic_init_mps(struct fbnic_dev
*fbd
, unsigned int offset
,
28 unsigned int cls
, unsigned int mps
)
30 u32 val
= rd32(fbd
, offset
);
32 /* Currently all MPS masks are identical so just use the first one */
33 val
&= ~(FBNIC_QM_TNI_TCM_CTL_MPS
| FBNIC_QM_TNI_TCM_CTL_CLS
);
35 val
|= FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_MPS
, mps
) |
36 FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_CLS
, cls
);
38 wr32(fbd
, offset
, val
);
41 static void fbnic_mac_init_axi(struct fbnic_dev
*fbd
)
43 bool override_1k
= false;
46 /* All of the values are based on being a power of 2 starting
47 * with 64 == 0. Therefore we can either divide by 64 in the
48 * case of constants, or just subtract 6 from the log2 of the value
49 * in order to get the value we will be programming into the
52 readrq
= ilog2(fbd
->readrq
) - 6;
55 readrq
= clamp(readrq
, 0, 3);
57 mps
= ilog2(fbd
->mps
) - 6;
58 mps
= clamp(mps
, 0, 3);
60 cls
= ilog2(L1_CACHE_BYTES
) - 6;
61 cls
= clamp(cls
, 0, 3);
63 /* Configure Tx/Rx AXI Paths w/ Read Request and Max Payload sizes */
64 fbnic_init_readrq(fbd
, FBNIC_QM_TNI_TDF_CTL
, cls
, readrq
);
65 fbnic_init_mps(fbd
, FBNIC_QM_TNI_TCM_CTL
, cls
, mps
);
67 /* Configure QM TNI TDE:
68 * - Max outstanding AXI beats to 704(768 - 64) - guaranetees 8% of
69 * buffer capacity to descriptors.
70 * - Max outstanding transactions to 128
72 wr32(fbd
, FBNIC_QM_TNI_TDE_CTL
,
73 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS_1K
, override_1k
? 1 : 0) |
74 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OB
, 704) |
75 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OT
, 128) |
76 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS
, readrq
) |
77 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_CLS
, cls
));
79 fbnic_init_readrq(fbd
, FBNIC_QM_RNI_RBP_CTL
, cls
, readrq
);
80 fbnic_init_mps(fbd
, FBNIC_QM_RNI_RDE_CTL
, cls
, mps
);
81 fbnic_init_mps(fbd
, FBNIC_QM_RNI_RCM_CTL
, cls
, mps
);
83 /* Enable XALI AR/AW outbound */
84 wr32(fbd
, FBNIC_PUL_OB_TLP_HDR_AW_CFG
,
85 FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME
);
86 wr32(fbd
, FBNIC_PUL_OB_TLP_HDR_AR_CFG
,
87 FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME
);
90 static void fbnic_mac_init_qm(struct fbnic_dev
*fbd
)
94 /* Configure TSO behavior */
95 wr32(fbd
, FBNIC_QM_TQS_CTL0
,
96 FIELD_PREP(FBNIC_QM_TQS_CTL0_LSO_TS_MASK
,
97 FBNIC_QM_TQS_CTL0_LSO_TS_LAST
) |
98 FIELD_PREP(FBNIC_QM_TQS_CTL0_PREFETCH_THRESH
,
99 FBNIC_QM_TQS_CTL0_PREFETCH_THRESH_MIN
));
101 /* Limit EDT to INT_MAX as this is the limit of the EDT Qdisc */
102 wr32(fbd
, FBNIC_QM_TQS_EDT_TS_RANGE
, INT_MAX
);
105 * Due to known HW issue we cannot set the MTU to within 16 octets
106 * of a 64 octet aligned boundary. So we will set the TQS_MTU(s) to
109 wr32(fbd
, FBNIC_QM_TQS_MTU_CTL0
, FBNIC_MAX_JUMBO_FRAME_SIZE
+ 1);
110 wr32(fbd
, FBNIC_QM_TQS_MTU_CTL1
,
111 FIELD_PREP(FBNIC_QM_TQS_MTU_CTL1_BULK
,
112 FBNIC_MAX_JUMBO_FRAME_SIZE
+ 1));
114 clock_freq
= FBNIC_CLOCK_FREQ
;
116 /* Be aggressive on the timings. We will have the interrupt
117 * threshold timer tick once every 1 usec and coalesce writes for
120 wr32(fbd
, FBNIC_QM_TCQ_CTL0
,
121 FIELD_PREP(FBNIC_QM_TCQ_CTL0_TICK_CYCLES
,
122 clock_freq
/ 1000000) |
123 FIELD_PREP(FBNIC_QM_TCQ_CTL0_COAL_WAIT
,
124 clock_freq
/ 12500));
126 /* We will have the interrupt threshold timer tick once every
127 * 1 usec and coalesce writes for up to 2 usecs.
129 wr32(fbd
, FBNIC_QM_RCQ_CTL0
,
130 FIELD_PREP(FBNIC_QM_RCQ_CTL0_TICK_CYCLES
,
131 clock_freq
/ 1000000) |
132 FIELD_PREP(FBNIC_QM_RCQ_CTL0_COAL_WAIT
,
133 clock_freq
/ 500000));
135 /* Configure spacer control to 64 beats. */
136 wr32(fbd
, FBNIC_FAB_AXI4_AR_SPACER_2_CFG
,
137 FBNIC_FAB_AXI4_AR_SPACER_MASK
|
138 FIELD_PREP(FBNIC_FAB_AXI4_AR_SPACER_THREADSHOLD
, 2));
141 #define FBNIC_DROP_EN_MASK 0x7d
142 #define FBNIC_PAUSE_EN_MASK 0x14
143 #define FBNIC_ECN_EN_MASK 0x10
145 struct fbnic_fifo_config
{
150 /* Rx FIFO Configuration
151 * The table consists of 8 entries, of which only 4 are currently used
152 * The starting addr is in units of 64B and the size is in 2KB units
153 * Below is the human readable version of the table defined below:
155 * ----------------------------------
156 * Network to Host/BMC 384K 64K
159 * Network to BMC 448K 32K
160 * Network to Host 0 384K
162 * BMC to Host 480K 32K
165 static const struct fbnic_fifo_config fifo_config
[] = {
166 { .addr
= 0x1800, .size
= 0x20 }, /* Network to Host/BMC */
169 { .addr
= 0x1c00, .size
= 0x10 }, /* Network to BMC */
170 { .addr
= 0x0000, .size
= 0xc0 }, /* Network to Host */
172 { .addr
= 0x1e00, .size
= 0x10 }, /* BMC to Host */
176 static void fbnic_mac_init_rxb(struct fbnic_dev
*fbd
)
181 rx_enable
= !!(rd32(fbd
, FBNIC_RPC_RMI_CONFIG
) &
182 FBNIC_RPC_RMI_CONFIG_ENABLE
);
184 for (i
= 0; i
< 8; i
++) {
185 unsigned int size
= fifo_config
[i
].size
;
187 /* If we are coming up on a system that already has the
188 * Rx data path enabled we don't need to reconfigure the
189 * FIFOs. Instead we can check to verify the values are
190 * large enough to meet our needs, and use the values to
191 * populate the flow control, ECN, and drop thresholds.
194 size
= FIELD_GET(FBNIC_RXB_PBUF_SIZE
,
195 rd32(fbd
, FBNIC_RXB_PBUF_CFG(i
)));
196 if (size
< fifo_config
[i
].size
)
198 "fifo%d size of %d smaller than expected value of %d\n",
200 fifo_config
[i
].size
<< 11);
202 /* Program RXB Cuthrough */
203 wr32(fbd
, FBNIC_RXB_CT_SIZE(i
),
204 FIELD_PREP(FBNIC_RXB_CT_SIZE_HEADER
, 4) |
205 FIELD_PREP(FBNIC_RXB_CT_SIZE_PAYLOAD
, 2));
207 /* The granularity for the packet buffer size is 2KB
208 * granularity while the packet buffer base address is
209 * only 64B granularity
211 wr32(fbd
, FBNIC_RXB_PBUF_CFG(i
),
212 FIELD_PREP(FBNIC_RXB_PBUF_BASE_ADDR
,
213 fifo_config
[i
].addr
) |
214 FIELD_PREP(FBNIC_RXB_PBUF_SIZE
, size
));
216 /* The granularity for the credits is 64B. This is
217 * based on RXB_PBUF_SIZE * 32 + 4.
219 wr32(fbd
, FBNIC_RXB_PBUF_CREDIT(i
),
220 FIELD_PREP(FBNIC_RXB_PBUF_CREDIT_MASK
,
221 size
? size
* 32 + 4 : 0));
227 /* Pause is size of FIFO with 56KB skid to start/stop */
228 wr32(fbd
, FBNIC_RXB_PAUSE_THLD(i
),
229 !(FBNIC_PAUSE_EN_MASK
& (1u << i
)) ? 0x1fff :
230 FIELD_PREP(FBNIC_RXB_PAUSE_THLD_ON
,
232 FIELD_PREP(FBNIC_RXB_PAUSE_THLD_OFF
, 0x380));
234 /* Enable Drop when only one packet is left in the FIFO */
235 wr32(fbd
, FBNIC_RXB_DROP_THLD(i
),
236 !(FBNIC_DROP_EN_MASK
& (1u << i
)) ? 0x1fff :
237 FIELD_PREP(FBNIC_RXB_DROP_THLD_ON
,
239 FBNIC_MAX_JUMBO_FRAME_SIZE
/ 64) |
240 FIELD_PREP(FBNIC_RXB_DROP_THLD_OFF
,
242 FBNIC_MAX_JUMBO_FRAME_SIZE
/ 64));
244 /* Enable ECN bit when 1/4 of RXB is filled with at least
245 * 1 room for one full jumbo frame before setting ECN
247 wr32(fbd
, FBNIC_RXB_ECN_THLD(i
),
248 !(FBNIC_ECN_EN_MASK
& (1u << i
)) ? 0x1fff :
249 FIELD_PREP(FBNIC_RXB_ECN_THLD_ON
,
252 FBNIC_MAX_JUMBO_FRAME_SIZE
/ 64)) |
253 FIELD_PREP(FBNIC_RXB_ECN_THLD_OFF
,
256 FBNIC_MAX_JUMBO_FRAME_SIZE
/ 64)));
259 /* For now only enable drop and ECN. We need to add driver/kernel
260 * interfaces for configuring pause.
262 wr32(fbd
, FBNIC_RXB_PAUSE_DROP_CTRL
,
263 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_DROP_ENABLE
,
264 FBNIC_DROP_EN_MASK
) |
265 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_ECN_ENABLE
,
268 /* Program INTF credits */
269 wr32(fbd
, FBNIC_RXB_INTF_CREDIT
,
270 FBNIC_RXB_INTF_CREDIT_MASK0
|
271 FBNIC_RXB_INTF_CREDIT_MASK1
|
272 FBNIC_RXB_INTF_CREDIT_MASK2
|
273 FIELD_PREP(FBNIC_RXB_INTF_CREDIT_MASK3
, 8));
275 /* Configure calendar slots.
276 * Rx: 0 - 62 RDE 1st, BMC 2nd
277 * 63 BMC 1st, RDE 2nd
279 for (i
= 0; i
< 16; i
++) {
280 u32 calendar_val
= (i
== 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
282 wr32(fbd
, FBNIC_RXB_CLDR_PRIO_CFG(i
), calendar_val
);
285 /* Split the credits for the DRR up as follows:
286 * Quantum0: 8000 Network to Host
287 * Quantum1: 0 Not used
288 * Quantum2: 80 BMC to Host
289 * Quantum3: 0 Not used
290 * Quantum4: 8000 Multicast to Host and BMC
292 wr32(fbd
, FBNIC_RXB_DWRR_RDE_WEIGHT0
,
293 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0
, 0x40) |
294 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM2
, 0x50));
295 wr32(fbd
, FBNIC_RXB_DWRR_RDE_WEIGHT0_EXT
,
296 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0
, 0x1f));
297 wr32(fbd
, FBNIC_RXB_DWRR_RDE_WEIGHT1
,
298 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4
, 0x40));
299 wr32(fbd
, FBNIC_RXB_DWRR_RDE_WEIGHT1_EXT
,
300 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4
, 0x1f));
302 /* Program RXB FCS Endian register */
303 wr32(fbd
, FBNIC_RXB_ENDIAN_FCS
, 0x0aaaaaa0);
306 static void fbnic_mac_init_txb(struct fbnic_dev
*fbd
)
310 wr32(fbd
, FBNIC_TCE_TXB_CTRL
, 0);
312 /* Configure Tx QM Credits */
313 wr32(fbd
, FBNIC_QM_TQS_CTL1
,
314 FIELD_PREP(FBNIC_QM_TQS_CTL1_MC_MAX_CREDITS
, 0x40) |
315 FIELD_PREP(FBNIC_QM_TQS_CTL1_BULK_MAX_CREDITS
, 0x20));
317 /* Initialize internal Tx queues */
318 wr32(fbd
, FBNIC_TCE_TXB_TEI_Q0_CTRL
, 0);
319 wr32(fbd
, FBNIC_TCE_TXB_TEI_Q1_CTRL
, 0);
320 wr32(fbd
, FBNIC_TCE_TXB_MC_Q_CTRL
,
321 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE
, 0x400) |
322 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START
, 0x000));
323 wr32(fbd
, FBNIC_TCE_TXB_RX_TEI_Q_CTRL
, 0);
324 wr32(fbd
, FBNIC_TCE_TXB_TX_BMC_Q_CTRL
,
325 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE
, 0x200) |
326 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START
, 0x400));
327 wr32(fbd
, FBNIC_TCE_TXB_RX_BMC_Q_CTRL
,
328 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE
, 0x200) |
329 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START
, 0x600));
331 wr32(fbd
, FBNIC_TCE_LSO_CTRL
,
332 FBNIC_TCE_LSO_CTRL_IPID_MODE_INC
|
333 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_1ST
, TCPHDR_PSH
|
335 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_MID
, TCPHDR_PSH
|
338 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_END
, TCPHDR_CWR
));
339 wr32(fbd
, FBNIC_TCE_CSO_CTRL
, 0);
341 wr32(fbd
, FBNIC_TCE_BMC_MAX_PKTSZ
,
342 FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_TX
,
343 FBNIC_MAX_JUMBO_FRAME_SIZE
) |
344 FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_RX
,
345 FBNIC_MAX_JUMBO_FRAME_SIZE
));
346 wr32(fbd
, FBNIC_TCE_MC_MAX_PKTSZ
,
347 FIELD_PREP(FBNIC_TCE_MC_MAX_PKTSZ_TMI
,
348 FBNIC_MAX_JUMBO_FRAME_SIZE
));
350 /* Configure calendar slots.
351 * Tx: 0 - 62 TMI 1st, BMC 2nd
352 * 63 BMC 1st, TMI 2nd
354 for (i
= 0; i
< 16; i
++) {
355 u32 calendar_val
= (i
== 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
357 wr32(fbd
, FBNIC_TCE_TXB_CLDR_SLOT_CFG(i
), calendar_val
);
361 wr32(fbd
, FBNIC_TCE_TXB_ENQ_WRR_CTRL
,
362 FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT0
, 0x64) |
363 FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT2
, 0x04));
364 wr32(fbd
, FBNIC_TCE_TXB_TEI_DWRR_CTRL
, 0);
365 wr32(fbd
, FBNIC_TCE_TXB_TEI_DWRR_CTRL_EXT
, 0);
366 wr32(fbd
, FBNIC_TCE_TXB_BMC_DWRR_CTRL
,
367 FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM0
, 0x50) |
368 FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM1
, 0x82));
369 wr32(fbd
, FBNIC_TCE_TXB_BMC_DWRR_CTRL_EXT
, 0);
370 wr32(fbd
, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL
,
371 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM1
, 0x50) |
372 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2
, 0x20));
373 wr32(fbd
, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_EXT
,
374 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2
, 0x03));
376 /* Configure SOP protocol protection */
377 wr32(fbd
, FBNIC_TCE_SOP_PROT_CTRL
,
378 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TBI
, 0x78) |
379 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_FRM
, 0x40) |
380 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_CM
, 0x0c));
382 /* Conservative configuration on MAC interface Start of Packet
383 * protection FIFO. This sets the minimum depth of the FIFO before
384 * we start sending packets to the MAC measured in 64B units and
385 * up to 160 entries deep.
387 * For the ASIC the clock is fast enough that we will likely fill
388 * the SOP FIFO before the MAC can drain it. So just use a minimum
391 wr32(fbd
, FBNIC_TMI_SOP_PROT_CTRL
, 8);
394 wr32(fbd
, FBNIC_TCE_TXB_CTRL
, FBNIC_TCE_TXB_CTRL_TCAM_ENABLE
|
395 FBNIC_TCE_TXB_CTRL_LOAD
);
398 static void fbnic_mac_init_regs(struct fbnic_dev
*fbd
)
400 fbnic_mac_init_axi(fbd
);
401 fbnic_mac_init_qm(fbd
);
402 fbnic_mac_init_rxb(fbd
);
403 fbnic_mac_init_txb(fbd
);
406 static void __fbnic_mac_stat_rd64(struct fbnic_dev
*fbd
, bool reset
, u32 reg
,
407 struct fbnic_stat_counter
*stat
)
411 new_reg_value
= fbnic_stat_rd64(fbd
, reg
, 1);
413 stat
->value
+= new_reg_value
- stat
->u
.old_reg_value_64
;
414 stat
->u
.old_reg_value_64
= new_reg_value
;
415 stat
->reported
= true;
418 #define fbnic_mac_stat_rd64(fbd, reset, __stat, __CSR) \
419 __fbnic_mac_stat_rd64(fbd, reset, FBNIC_##__CSR##_L, &(__stat))
421 static void fbnic_mac_tx_pause_config(struct fbnic_dev
*fbd
, bool tx_pause
)
425 /* Enable generation of pause frames if enabled */
426 rxb_pause_ctrl
= rd32(fbd
, FBNIC_RXB_PAUSE_DROP_CTRL
);
427 rxb_pause_ctrl
&= ~FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE
;
430 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE
,
431 FBNIC_PAUSE_EN_MASK
);
432 wr32(fbd
, FBNIC_RXB_PAUSE_DROP_CTRL
, rxb_pause_ctrl
);
435 static int fbnic_pcs_get_link_event_asic(struct fbnic_dev
*fbd
)
437 u32 pcs_intr_mask
= rd32(fbd
, FBNIC_SIG_PCS_INTR_STS
);
439 if (pcs_intr_mask
& FBNIC_SIG_PCS_INTR_LINK_DOWN
)
440 return FBNIC_LINK_EVENT_DOWN
;
442 return (pcs_intr_mask
& FBNIC_SIG_PCS_INTR_LINK_UP
) ?
443 FBNIC_LINK_EVENT_UP
: FBNIC_LINK_EVENT_NONE
;
446 static u32
__fbnic_mac_cmd_config_asic(struct fbnic_dev
*fbd
,
447 bool tx_pause
, bool rx_pause
)
449 /* Enable MAC Promiscuous mode and Tx padding */
450 u32 command_config
= FBNIC_MAC_COMMAND_CONFIG_TX_PAD_EN
|
451 FBNIC_MAC_COMMAND_CONFIG_PROMISC_EN
;
452 struct fbnic_net
*fbn
= netdev_priv(fbd
->netdev
);
454 /* Disable pause frames if not enabled */
456 command_config
|= FBNIC_MAC_COMMAND_CONFIG_TX_PAUSE_DIS
;
458 command_config
|= FBNIC_MAC_COMMAND_CONFIG_RX_PAUSE_DIS
;
460 /* Disable fault handling if no FEC is requested */
461 if ((fbn
->fec
& FBNIC_FEC_MODE_MASK
) == FBNIC_FEC_OFF
)
462 command_config
|= FBNIC_MAC_COMMAND_CONFIG_FLT_HDL_DIS
;
464 return command_config
;
467 static bool fbnic_mac_get_pcs_link_status(struct fbnic_dev
*fbd
)
469 struct fbnic_net
*fbn
= netdev_priv(fbd
->netdev
);
470 u32 pcs_status
, lane_mask
= ~0;
472 pcs_status
= rd32(fbd
, FBNIC_SIG_PCS_OUT0
);
473 if (!(pcs_status
& FBNIC_SIG_PCS_OUT0_LINK
))
476 /* Define the expected lane mask for the status bits we need to check */
477 switch (fbn
->link_mode
& FBNIC_LINK_MODE_MASK
) {
478 case FBNIC_LINK_100R2
:
481 case FBNIC_LINK_50R1
:
484 case FBNIC_LINK_50R2
:
485 switch (fbn
->fec
& FBNIC_FEC_MODE_MASK
) {
492 case FBNIC_FEC_BASER
:
497 case FBNIC_LINK_25R1
:
502 /* Use an XOR to remove the bits we expect to see set */
503 switch (fbn
->fec
& FBNIC_FEC_MODE_MASK
) {
505 lane_mask
^= FIELD_GET(FBNIC_SIG_PCS_OUT0_BLOCK_LOCK
,
509 lane_mask
^= FIELD_GET(FBNIC_SIG_PCS_OUT0_AMPS_LOCK
,
512 case FBNIC_FEC_BASER
:
513 lane_mask
^= FIELD_GET(FBNIC_SIG_PCS_OUT1_FCFEC_LOCK
,
514 rd32(fbd
, FBNIC_SIG_PCS_OUT1
));
518 /* If all lanes cancelled then we have a lock on all lanes */
522 static bool fbnic_pcs_get_link_asic(struct fbnic_dev
*fbd
)
526 /* Flush status bits to clear possible stale data,
527 * bits should reset themselves back to 1 if link is truly up
529 wr32(fbd
, FBNIC_SIG_PCS_OUT0
, FBNIC_SIG_PCS_OUT0_LINK
|
530 FBNIC_SIG_PCS_OUT0_BLOCK_LOCK
|
531 FBNIC_SIG_PCS_OUT0_AMPS_LOCK
);
532 wr32(fbd
, FBNIC_SIG_PCS_OUT1
, FBNIC_SIG_PCS_OUT1_FCFEC_LOCK
);
535 /* Clear interrupt state due to recent changes. */
536 wr32(fbd
, FBNIC_SIG_PCS_INTR_STS
,
537 FBNIC_SIG_PCS_INTR_LINK_DOWN
| FBNIC_SIG_PCS_INTR_LINK_UP
);
539 link
= fbnic_mac_get_pcs_link_status(fbd
);
541 /* Enable interrupt to only capture changes in link state */
542 wr32(fbd
, FBNIC_SIG_PCS_INTR_MASK
,
543 ~FBNIC_SIG_PCS_INTR_LINK_DOWN
& ~FBNIC_SIG_PCS_INTR_LINK_UP
);
544 wr32(fbd
, FBNIC_INTR_MASK_CLEAR(0), 1u << FBNIC_PCS_MSIX_ENTRY
);
549 static void fbnic_pcs_get_fw_settings(struct fbnic_dev
*fbd
)
551 struct fbnic_net
*fbn
= netdev_priv(fbd
->netdev
);
552 u8 link_mode
= fbn
->link_mode
;
555 /* Update FEC first to reflect FW current mode */
556 if (fbn
->fec
& FBNIC_FEC_AUTO
) {
557 switch (fbd
->fw_cap
.link_fec
) {
558 case FBNIC_FW_LINK_FEC_NONE
:
561 case FBNIC_FW_LINK_FEC_RS
:
564 case FBNIC_FW_LINK_FEC_BASER
:
565 fec
= FBNIC_FEC_BASER
;
574 /* Do nothing if AUTO mode is not engaged */
575 if (fbn
->link_mode
& FBNIC_LINK_AUTO
) {
576 switch (fbd
->fw_cap
.link_speed
) {
577 case FBNIC_FW_LINK_SPEED_25R1
:
578 link_mode
= FBNIC_LINK_25R1
;
580 case FBNIC_FW_LINK_SPEED_50R2
:
581 link_mode
= FBNIC_LINK_50R2
;
583 case FBNIC_FW_LINK_SPEED_50R1
:
584 link_mode
= FBNIC_LINK_50R1
;
587 case FBNIC_FW_LINK_SPEED_100R2
:
588 link_mode
= FBNIC_LINK_100R2
;
595 fbn
->link_mode
= link_mode
;
599 static int fbnic_pcs_enable_asic(struct fbnic_dev
*fbd
)
601 /* Mask and clear the PCS interrupt, will be enabled by link handler */
602 wr32(fbd
, FBNIC_SIG_PCS_INTR_MASK
, ~0);
603 wr32(fbd
, FBNIC_SIG_PCS_INTR_STS
, ~0);
605 /* Pull in settings from FW */
606 fbnic_pcs_get_fw_settings(fbd
);
611 static void fbnic_pcs_disable_asic(struct fbnic_dev
*fbd
)
613 /* Mask and clear the PCS interrupt */
614 wr32(fbd
, FBNIC_SIG_PCS_INTR_MASK
, ~0);
615 wr32(fbd
, FBNIC_SIG_PCS_INTR_STS
, ~0);
618 static void fbnic_mac_link_down_asic(struct fbnic_dev
*fbd
)
620 u32 cmd_cfg
, mac_ctrl
;
622 cmd_cfg
= __fbnic_mac_cmd_config_asic(fbd
, false, false);
623 mac_ctrl
= rd32(fbd
, FBNIC_SIG_MAC_IN0
);
625 mac_ctrl
|= FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK
|
626 FBNIC_SIG_MAC_IN0_RESET_TX_CLK
|
627 FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK
|
628 FBNIC_SIG_MAC_IN0_RESET_RX_CLK
;
630 wr32(fbd
, FBNIC_SIG_MAC_IN0
, mac_ctrl
);
631 wr32(fbd
, FBNIC_MAC_COMMAND_CONFIG
, cmd_cfg
);
634 static void fbnic_mac_link_up_asic(struct fbnic_dev
*fbd
,
635 bool tx_pause
, bool rx_pause
)
637 u32 cmd_cfg
, mac_ctrl
;
639 fbnic_mac_tx_pause_config(fbd
, tx_pause
);
641 cmd_cfg
= __fbnic_mac_cmd_config_asic(fbd
, tx_pause
, rx_pause
);
642 mac_ctrl
= rd32(fbd
, FBNIC_SIG_MAC_IN0
);
644 mac_ctrl
&= ~(FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK
|
645 FBNIC_SIG_MAC_IN0_RESET_TX_CLK
|
646 FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK
|
647 FBNIC_SIG_MAC_IN0_RESET_RX_CLK
);
648 cmd_cfg
|= FBNIC_MAC_COMMAND_CONFIG_RX_ENA
|
649 FBNIC_MAC_COMMAND_CONFIG_TX_ENA
;
651 wr32(fbd
, FBNIC_SIG_MAC_IN0
, mac_ctrl
);
652 wr32(fbd
, FBNIC_MAC_COMMAND_CONFIG
, cmd_cfg
);
656 fbnic_mac_get_eth_mac_stats(struct fbnic_dev
*fbd
, bool reset
,
657 struct fbnic_eth_mac_stats
*mac_stats
)
659 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->OctetsReceivedOK
,
660 MAC_STAT_RX_BYTE_COUNT
);
661 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->AlignmentErrors
,
662 MAC_STAT_RX_ALIGN_ERROR
);
663 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->FrameTooLongErrors
,
664 MAC_STAT_RX_TOOLONG
);
665 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->FramesReceivedOK
,
666 MAC_STAT_RX_RECEIVED_OK
);
667 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->FrameCheckSequenceErrors
,
668 MAC_STAT_RX_PACKET_BAD_FCS
);
669 fbnic_mac_stat_rd64(fbd
, reset
,
670 mac_stats
->FramesLostDueToIntMACRcvError
,
671 MAC_STAT_RX_IFINERRORS
);
672 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->MulticastFramesReceivedOK
,
673 MAC_STAT_RX_MULTICAST
);
674 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->BroadcastFramesReceivedOK
,
675 MAC_STAT_RX_BROADCAST
);
676 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->OctetsTransmittedOK
,
677 MAC_STAT_TX_BYTE_COUNT
);
678 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->FramesTransmittedOK
,
679 MAC_STAT_TX_TRANSMITTED_OK
);
680 fbnic_mac_stat_rd64(fbd
, reset
,
681 mac_stats
->FramesLostDueToIntMACXmitError
,
682 MAC_STAT_TX_IFOUTERRORS
);
683 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->MulticastFramesXmittedOK
,
684 MAC_STAT_TX_MULTICAST
);
685 fbnic_mac_stat_rd64(fbd
, reset
, mac_stats
->BroadcastFramesXmittedOK
,
686 MAC_STAT_TX_BROADCAST
);
689 static int fbnic_mac_get_sensor_asic(struct fbnic_dev
*fbd
, int id
, long *val
)
691 struct fbnic_fw_completion fw_cmpl
;
695 case FBNIC_SENSOR_TEMP
:
696 sensor
= &fw_cmpl
.tsene
.millidegrees
;
698 case FBNIC_SENSOR_VOLTAGE
:
699 sensor
= &fw_cmpl
.tsene
.millivolts
;
710 static const struct fbnic_mac fbnic_mac_asic
= {
711 .init_regs
= fbnic_mac_init_regs
,
712 .pcs_enable
= fbnic_pcs_enable_asic
,
713 .pcs_disable
= fbnic_pcs_disable_asic
,
714 .pcs_get_link
= fbnic_pcs_get_link_asic
,
715 .pcs_get_link_event
= fbnic_pcs_get_link_event_asic
,
716 .get_eth_mac_stats
= fbnic_mac_get_eth_mac_stats
,
717 .link_down
= fbnic_mac_link_down_asic
,
718 .link_up
= fbnic_mac_link_up_asic
,
719 .get_sensor
= fbnic_mac_get_sensor_asic
,
723 * fbnic_mac_init - Assign a MAC type and initialize the fbnic device
724 * @fbd: Device pointer to device to initialize
726 * Return: zero on success, negative on failure
728 * Initialize the MAC function pointers and initializes the MAC of
731 int fbnic_mac_init(struct fbnic_dev
*fbd
)
733 fbd
->mac
= &fbnic_mac_asic
;
735 fbd
->mac
->init_regs(fbd
);