xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_mac.c (revision 18a7e218cfcdca6666e1f7356533e4c988780b57)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <linux/bitfield.h>
5 #include <net/tcp.h>
6 
7 #include "fbnic.h"
8 #include "fbnic_mac.h"
9 #include "fbnic_netdev.h"
10 
fbnic_init_readrq(struct fbnic_dev * fbd,unsigned int offset,unsigned int cls,unsigned int readrq)11 static void fbnic_init_readrq(struct fbnic_dev *fbd, unsigned int offset,
12 			      unsigned int cls, unsigned int readrq)
13 {
14 	u32 val = rd32(fbd, offset);
15 
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.
18 	 */
19 	val &= FBNIC_QM_TNI_TDF_CTL_MAX_OT | FBNIC_QM_TNI_TDF_CTL_MAX_OB;
20 
21 	val |= FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_MRRS, readrq) |
22 	       FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_CLS, cls);
23 
24 	wr32(fbd, offset, val);
25 }
26 
fbnic_init_mps(struct fbnic_dev * fbd,unsigned int offset,unsigned int cls,unsigned int mps)27 static void fbnic_init_mps(struct fbnic_dev *fbd, unsigned int offset,
28 			   unsigned int cls, unsigned int mps)
29 {
30 	u32 val = rd32(fbd, offset);
31 
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);
34 
35 	val |= FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_MPS, mps) |
36 	       FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_CLS, cls);
37 
38 	wr32(fbd, offset, val);
39 }
40 
fbnic_mac_init_axi(struct fbnic_dev * fbd)41 static void fbnic_mac_init_axi(struct fbnic_dev *fbd)
42 {
43 	bool override_1k = false;
44 	int readrq, mps, cls;
45 
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
50 	 * registers.
51 	 */
52 	readrq = ilog2(fbd->readrq) - 6;
53 	if (readrq > 3)
54 		override_1k = true;
55 	readrq = clamp(readrq, 0, 3);
56 
57 	mps = ilog2(fbd->mps) - 6;
58 	mps = clamp(mps, 0, 3);
59 
60 	cls = ilog2(L1_CACHE_BYTES) - 6;
61 	cls = clamp(cls, 0, 3);
62 
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);
66 
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
71 	 */
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));
78 
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);
82 }
83 
fbnic_mac_init_qm(struct fbnic_dev * fbd)84 static void fbnic_mac_init_qm(struct fbnic_dev *fbd)
85 {
86 	u64 default_meta = FIELD_PREP(FBNIC_TWD_L2_HLEN_MASK, ETH_HLEN) |
87 			   FBNIC_TWD_FLAG_REQ_COMPLETION;
88 	u32 clock_freq;
89 
90 	/* Configure default TWQ Metadata descriptor */
91 	wr32(fbd, FBNIC_QM_TWQ_DEFAULT_META_L,
92 	     lower_32_bits(default_meta));
93 	wr32(fbd, FBNIC_QM_TWQ_DEFAULT_META_H,
94 	     upper_32_bits(default_meta));
95 
96 	/* Configure TSO behavior */
97 	wr32(fbd, FBNIC_QM_TQS_CTL0,
98 	     FIELD_PREP(FBNIC_QM_TQS_CTL0_LSO_TS_MASK,
99 			FBNIC_QM_TQS_CTL0_LSO_TS_LAST) |
100 	     FIELD_PREP(FBNIC_QM_TQS_CTL0_PREFETCH_THRESH,
101 			FBNIC_QM_TQS_CTL0_PREFETCH_THRESH_MIN));
102 
103 	/* Limit EDT to INT_MAX as this is the limit of the EDT Qdisc */
104 	wr32(fbd, FBNIC_QM_TQS_EDT_TS_RANGE, INT_MAX);
105 
106 	/* Configure MTU
107 	 * Due to known HW issue we cannot set the MTU to within 16 octets
108 	 * of a 64 octet aligned boundary. So we will set the TQS_MTU(s) to
109 	 * MTU + 1.
110 	 */
111 	wr32(fbd, FBNIC_QM_TQS_MTU_CTL0, FBNIC_MAX_JUMBO_FRAME_SIZE + 1);
112 	wr32(fbd, FBNIC_QM_TQS_MTU_CTL1,
113 	     FIELD_PREP(FBNIC_QM_TQS_MTU_CTL1_BULK,
114 			FBNIC_MAX_JUMBO_FRAME_SIZE + 1));
115 
116 	clock_freq = FBNIC_CLOCK_FREQ;
117 
118 	/* Be aggressive on the timings. We will have the interrupt
119 	 * threshold timer tick once every 1 usec and coalesce writes for
120 	 * up to 80 usecs.
121 	 */
122 	wr32(fbd, FBNIC_QM_TCQ_CTL0,
123 	     FIELD_PREP(FBNIC_QM_TCQ_CTL0_TICK_CYCLES,
124 			clock_freq / 1000000) |
125 	     FIELD_PREP(FBNIC_QM_TCQ_CTL0_COAL_WAIT,
126 			clock_freq / 12500));
127 
128 	/* We will have the interrupt threshold timer tick once every
129 	 * 1 usec and coalesce writes for up to 2 usecs.
130 	 */
131 	wr32(fbd, FBNIC_QM_RCQ_CTL0,
132 	     FIELD_PREP(FBNIC_QM_RCQ_CTL0_TICK_CYCLES,
133 			clock_freq / 1000000) |
134 	     FIELD_PREP(FBNIC_QM_RCQ_CTL0_COAL_WAIT,
135 			clock_freq / 500000));
136 
137 	/* Configure spacer control to 64 beats. */
138 	wr32(fbd, FBNIC_FAB_AXI4_AR_SPACER_2_CFG,
139 	     FBNIC_FAB_AXI4_AR_SPACER_MASK |
140 	     FIELD_PREP(FBNIC_FAB_AXI4_AR_SPACER_THREADSHOLD, 2));
141 }
142 
143 #define FBNIC_DROP_EN_MASK	0x7d
144 #define FBNIC_PAUSE_EN_MASK	0x14
145 #define FBNIC_ECN_EN_MASK	0x10
146 
147 struct fbnic_fifo_config {
148 	unsigned int addr;
149 	unsigned int size;
150 };
151 
152 /* Rx FIFO Configuration
153  * The table consists of 8 entries, of which only 4 are currently used
154  * The starting addr is in units of 64B and the size is in 2KB units
155  * Below is the human readable version of the table defined below:
156  * Function		Addr	Size
157  * ----------------------------------
158  * Network to Host/BMC	384K	64K
159  * Unused
160  * Unused
161  * Network to BMC	448K	32K
162  * Network to Host	0	384K
163  * Unused
164  * BMC to Host		480K	32K
165  * Unused
166  */
167 static const struct fbnic_fifo_config fifo_config[] = {
168 	{ .addr = 0x1800, .size = 0x20 },	/* Network to Host/BMC */
169 	{ },					/* Unused */
170 	{ },					/* Unused */
171 	{ .addr = 0x1c00, .size = 0x10 },	/* Network to BMC */
172 	{ .addr = 0x0000, .size = 0xc0 },	/* Network to Host */
173 	{ },					/* Unused */
174 	{ .addr = 0x1e00, .size = 0x10 },	/* BMC to Host */
175 	{ }					/* Unused */
176 };
177 
fbnic_mac_init_rxb(struct fbnic_dev * fbd)178 static void fbnic_mac_init_rxb(struct fbnic_dev *fbd)
179 {
180 	bool rx_enable;
181 	int i;
182 
183 	rx_enable = !!(rd32(fbd, FBNIC_RPC_RMI_CONFIG) &
184 		       FBNIC_RPC_RMI_CONFIG_ENABLE);
185 
186 	for (i = 0; i < 8; i++) {
187 		unsigned int size = fifo_config[i].size;
188 
189 		/* If we are coming up on a system that already has the
190 		 * Rx data path enabled we don't need to reconfigure the
191 		 * FIFOs. Instead we can check to verify the values are
192 		 * large enough to meet our needs, and use the values to
193 		 * populate the flow control, ECN, and drop thresholds.
194 		 */
195 		if (rx_enable) {
196 			size = FIELD_GET(FBNIC_RXB_PBUF_SIZE,
197 					 rd32(fbd, FBNIC_RXB_PBUF_CFG(i)));
198 			if (size < fifo_config[i].size)
199 				dev_warn(fbd->dev,
200 					 "fifo%d size of %d smaller than expected value of %d\n",
201 					 i, size << 11,
202 					 fifo_config[i].size << 11);
203 		} else {
204 			/* Program RXB Cuthrough */
205 			wr32(fbd, FBNIC_RXB_CT_SIZE(i),
206 			     FIELD_PREP(FBNIC_RXB_CT_SIZE_HEADER, 4) |
207 			     FIELD_PREP(FBNIC_RXB_CT_SIZE_PAYLOAD, 2));
208 
209 			/* The granularity for the packet buffer size is 2KB
210 			 * granularity while the packet buffer base address is
211 			 * only 64B granularity
212 			 */
213 			wr32(fbd, FBNIC_RXB_PBUF_CFG(i),
214 			     FIELD_PREP(FBNIC_RXB_PBUF_BASE_ADDR,
215 					fifo_config[i].addr) |
216 			     FIELD_PREP(FBNIC_RXB_PBUF_SIZE, size));
217 
218 			/* The granularity for the credits is 64B. This is
219 			 * based on RXB_PBUF_SIZE * 32 + 4.
220 			 */
221 			wr32(fbd, FBNIC_RXB_PBUF_CREDIT(i),
222 			     FIELD_PREP(FBNIC_RXB_PBUF_CREDIT_MASK,
223 					size ? size * 32 + 4 : 0));
224 		}
225 
226 		if (!size)
227 			continue;
228 
229 		/* Pause is size of FIFO with 56KB skid to start/stop */
230 		wr32(fbd, FBNIC_RXB_PAUSE_THLD(i),
231 		     !(FBNIC_PAUSE_EN_MASK & (1u << i)) ? 0x1fff :
232 		     FIELD_PREP(FBNIC_RXB_PAUSE_THLD_ON,
233 				size * 32 - 0x380) |
234 		     FIELD_PREP(FBNIC_RXB_PAUSE_THLD_OFF, 0x380));
235 
236 		/* Enable Drop when only one packet is left in the FIFO */
237 		wr32(fbd, FBNIC_RXB_DROP_THLD(i),
238 		     !(FBNIC_DROP_EN_MASK & (1u << i)) ? 0x1fff :
239 		     FIELD_PREP(FBNIC_RXB_DROP_THLD_ON,
240 				size * 32 -
241 				FBNIC_MAX_JUMBO_FRAME_SIZE / 64) |
242 		     FIELD_PREP(FBNIC_RXB_DROP_THLD_OFF,
243 				size * 32 -
244 				FBNIC_MAX_JUMBO_FRAME_SIZE / 64));
245 
246 		/* Enable ECN bit when 1/4 of RXB is filled with at least
247 		 * 1 room for one full jumbo frame before setting ECN
248 		 */
249 		wr32(fbd, FBNIC_RXB_ECN_THLD(i),
250 		     !(FBNIC_ECN_EN_MASK & (1u << i)) ? 0x1fff :
251 		     FIELD_PREP(FBNIC_RXB_ECN_THLD_ON,
252 				max_t(unsigned int,
253 				      size * 32 / 4,
254 				      FBNIC_MAX_JUMBO_FRAME_SIZE / 64)) |
255 		     FIELD_PREP(FBNIC_RXB_ECN_THLD_OFF,
256 				max_t(unsigned int,
257 				      size * 32 / 4,
258 				      FBNIC_MAX_JUMBO_FRAME_SIZE / 64)));
259 	}
260 
261 	/* For now only enable drop and ECN. We need to add driver/kernel
262 	 * interfaces for configuring pause.
263 	 */
264 	wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL,
265 	     FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_DROP_ENABLE,
266 			FBNIC_DROP_EN_MASK) |
267 	     FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_ECN_ENABLE,
268 			FBNIC_ECN_EN_MASK));
269 
270 	/* Program INTF credits */
271 	wr32(fbd, FBNIC_RXB_INTF_CREDIT,
272 	     FBNIC_RXB_INTF_CREDIT_MASK0 |
273 	     FBNIC_RXB_INTF_CREDIT_MASK1 |
274 	     FBNIC_RXB_INTF_CREDIT_MASK2 |
275 	     FIELD_PREP(FBNIC_RXB_INTF_CREDIT_MASK3, 8));
276 
277 	/* Configure calendar slots.
278 	 * Rx: 0 - 62	RDE 1st, BMC 2nd
279 	 *     63	BMC 1st, RDE 2nd
280 	 */
281 	for (i = 0; i < 16; i++) {
282 		u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
283 
284 		wr32(fbd, FBNIC_RXB_CLDR_PRIO_CFG(i), calendar_val);
285 	}
286 
287 	/* Split the credits for the DRR up as follows:
288 	 * Quantum0: 8000	Network to Host
289 	 * Quantum1: 0		Not used
290 	 * Quantum2: 80		BMC to Host
291 	 * Quantum3: 0		Not used
292 	 * Quantum4: 8000	Multicast to Host and BMC
293 	 */
294 	wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0,
295 	     FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x40) |
296 	     FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM2, 0x50));
297 	wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0_EXT,
298 	     FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x1f));
299 	wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1,
300 	     FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x40));
301 	wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1_EXT,
302 	     FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x1f));
303 
304 	/* Program RXB FCS Endian register */
305 	wr32(fbd, FBNIC_RXB_ENDIAN_FCS, 0x0aaaaaa0);
306 }
307 
fbnic_mac_init_txb(struct fbnic_dev * fbd)308 static void fbnic_mac_init_txb(struct fbnic_dev *fbd)
309 {
310 	int i;
311 
312 	wr32(fbd, FBNIC_TCE_TXB_CTRL, 0);
313 
314 	/* Configure Tx QM Credits */
315 	wr32(fbd, FBNIC_QM_TQS_CTL1,
316 	     FIELD_PREP(FBNIC_QM_TQS_CTL1_MC_MAX_CREDITS, 0x40) |
317 	     FIELD_PREP(FBNIC_QM_TQS_CTL1_BULK_MAX_CREDITS, 0x20));
318 
319 	/* Initialize internal Tx queues */
320 	wr32(fbd, FBNIC_TCE_TXB_TEI_Q0_CTRL, 0);
321 	wr32(fbd, FBNIC_TCE_TXB_TEI_Q1_CTRL, 0);
322 	wr32(fbd, FBNIC_TCE_TXB_MC_Q_CTRL,
323 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x400) |
324 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x000));
325 	wr32(fbd, FBNIC_TCE_TXB_RX_TEI_Q_CTRL, 0);
326 	wr32(fbd, FBNIC_TCE_TXB_TX_BMC_Q_CTRL,
327 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) |
328 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x400));
329 	wr32(fbd, FBNIC_TCE_TXB_RX_BMC_Q_CTRL,
330 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) |
331 	     FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x600));
332 
333 	wr32(fbd, FBNIC_TCE_LSO_CTRL,
334 	     FBNIC_TCE_LSO_CTRL_IPID_MODE_INC |
335 	     FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_1ST, TCPHDR_PSH |
336 							 TCPHDR_FIN) |
337 	     FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_MID, TCPHDR_PSH |
338 							 TCPHDR_CWR |
339 							 TCPHDR_FIN) |
340 	     FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_END, TCPHDR_CWR));
341 	wr32(fbd, FBNIC_TCE_CSO_CTRL, 0);
342 
343 	wr32(fbd, FBNIC_TCE_BMC_MAX_PKTSZ,
344 	     FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_TX,
345 			FBNIC_MAX_JUMBO_FRAME_SIZE) |
346 	     FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_RX,
347 			FBNIC_MAX_JUMBO_FRAME_SIZE));
348 	wr32(fbd, FBNIC_TCE_MC_MAX_PKTSZ,
349 	     FIELD_PREP(FBNIC_TCE_MC_MAX_PKTSZ_TMI,
350 			FBNIC_MAX_JUMBO_FRAME_SIZE));
351 
352 	/* Configure calendar slots.
353 	 * Tx: 0 - 62	TMI 1st, BMC 2nd
354 	 *     63	BMC 1st, TMI 2nd
355 	 */
356 	for (i = 0; i < 16; i++) {
357 		u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
358 
359 		wr32(fbd, FBNIC_TCE_TXB_CLDR_SLOT_CFG(i), calendar_val);
360 	}
361 
362 	/* Configure DWRR */
363 	wr32(fbd, FBNIC_TCE_TXB_ENQ_WRR_CTRL,
364 	     FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT0, 0x64) |
365 	     FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT2, 0x04));
366 	wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL, 0);
367 	wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL_EXT, 0);
368 	wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL,
369 	     FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM0, 0x50) |
370 	     FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM1, 0x82));
371 	wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL_EXT, 0);
372 	wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL,
373 	     FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM1, 0x50) |
374 	     FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x20));
375 	wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_EXT,
376 	     FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x03));
377 
378 	/* Configure SOP protocol protection */
379 	wr32(fbd, FBNIC_TCE_SOP_PROT_CTRL,
380 	     FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TBI, 0x78) |
381 	     FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_FRM, 0x40) |
382 	     FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_CM, 0x0c));
383 
384 	/* Conservative configuration on MAC interface Start of Packet
385 	 * protection FIFO. This sets the minimum depth of the FIFO before
386 	 * we start sending packets to the MAC measured in 64B units and
387 	 * up to 160 entries deep.
388 	 *
389 	 * For the ASIC the clock is fast enough that we will likely fill
390 	 * the SOP FIFO before the MAC can drain it. So just use a minimum
391 	 * value of 8.
392 	 */
393 	wr32(fbd, FBNIC_TMI_SOP_PROT_CTRL, 8);
394 
395 	wrfl(fbd);
396 	wr32(fbd, FBNIC_TCE_TXB_CTRL, FBNIC_TCE_TXB_CTRL_TCAM_ENABLE |
397 				      FBNIC_TCE_TXB_CTRL_LOAD);
398 }
399 
fbnic_mac_init_regs(struct fbnic_dev * fbd)400 static void fbnic_mac_init_regs(struct fbnic_dev *fbd)
401 {
402 	fbnic_mac_init_axi(fbd);
403 	fbnic_mac_init_qm(fbd);
404 	fbnic_mac_init_rxb(fbd);
405 	fbnic_mac_init_txb(fbd);
406 }
407 
__fbnic_mac_stat_rd64(struct fbnic_dev * fbd,bool reset,u32 reg,struct fbnic_stat_counter * stat)408 static void __fbnic_mac_stat_rd64(struct fbnic_dev *fbd, bool reset, u32 reg,
409 				  struct fbnic_stat_counter *stat)
410 {
411 	u64 new_reg_value;
412 
413 	new_reg_value = fbnic_stat_rd64(fbd, reg, 1);
414 	if (!reset)
415 		stat->value += new_reg_value - stat->u.old_reg_value_64;
416 	stat->u.old_reg_value_64 = new_reg_value;
417 	stat->reported = true;
418 }
419 
420 #define fbnic_mac_stat_rd64(fbd, reset, __stat, __CSR) \
421 	__fbnic_mac_stat_rd64(fbd, reset, FBNIC_##__CSR##_L, &(__stat))
422 
fbnic_mac_tx_pause_config(struct fbnic_dev * fbd,bool tx_pause)423 static void fbnic_mac_tx_pause_config(struct fbnic_dev *fbd, bool tx_pause)
424 {
425 	u32 rxb_pause_ctrl;
426 
427 	/* Enable generation of pause frames if enabled */
428 	rxb_pause_ctrl = rd32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL);
429 	rxb_pause_ctrl &= ~FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE;
430 	if (tx_pause)
431 		rxb_pause_ctrl |=
432 			FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE,
433 				   FBNIC_PAUSE_EN_MASK);
434 	wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL, rxb_pause_ctrl);
435 }
436 
fbnic_pcs_get_link_event_asic(struct fbnic_dev * fbd)437 static int fbnic_pcs_get_link_event_asic(struct fbnic_dev *fbd)
438 {
439 	u32 pcs_intr_mask = rd32(fbd, FBNIC_SIG_PCS_INTR_STS);
440 
441 	if (pcs_intr_mask & FBNIC_SIG_PCS_INTR_LINK_DOWN)
442 		return FBNIC_LINK_EVENT_DOWN;
443 
444 	return (pcs_intr_mask & FBNIC_SIG_PCS_INTR_LINK_UP) ?
445 	       FBNIC_LINK_EVENT_UP : FBNIC_LINK_EVENT_NONE;
446 }
447 
__fbnic_mac_cmd_config_asic(struct fbnic_dev * fbd,bool tx_pause,bool rx_pause)448 static u32 __fbnic_mac_cmd_config_asic(struct fbnic_dev *fbd,
449 				       bool tx_pause, bool rx_pause)
450 {
451 	/* Enable MAC Promiscuous mode and Tx padding */
452 	u32 command_config = FBNIC_MAC_COMMAND_CONFIG_TX_PAD_EN |
453 			     FBNIC_MAC_COMMAND_CONFIG_PROMISC_EN;
454 	struct fbnic_net *fbn = netdev_priv(fbd->netdev);
455 
456 	/* Disable pause frames if not enabled */
457 	if (!tx_pause)
458 		command_config |= FBNIC_MAC_COMMAND_CONFIG_TX_PAUSE_DIS;
459 	if (!rx_pause)
460 		command_config |= FBNIC_MAC_COMMAND_CONFIG_RX_PAUSE_DIS;
461 
462 	/* Disable fault handling if no FEC is requested */
463 	if (fbn->fec == FBNIC_FEC_OFF)
464 		command_config |= FBNIC_MAC_COMMAND_CONFIG_FLT_HDL_DIS;
465 
466 	return command_config;
467 }
468 
fbnic_mac_get_pcs_link_status(struct fbnic_dev * fbd)469 static bool fbnic_mac_get_pcs_link_status(struct fbnic_dev *fbd)
470 {
471 	struct fbnic_net *fbn = netdev_priv(fbd->netdev);
472 	u32 pcs_status, lane_mask = ~0;
473 
474 	pcs_status = rd32(fbd, FBNIC_SIG_PCS_OUT0);
475 	if (!(pcs_status & FBNIC_SIG_PCS_OUT0_LINK))
476 		return false;
477 
478 	/* Define the expected lane mask for the status bits we need to check */
479 	switch (fbn->aui) {
480 	case FBNIC_AUI_100GAUI2:
481 		lane_mask = 0xf;
482 		break;
483 	case FBNIC_AUI_50GAUI1:
484 		lane_mask = 3;
485 		break;
486 	case FBNIC_AUI_LAUI2:
487 		switch (fbn->fec) {
488 		case FBNIC_FEC_OFF:
489 			lane_mask = 0x63;
490 			break;
491 		case FBNIC_FEC_RS:
492 			lane_mask = 5;
493 			break;
494 		case FBNIC_FEC_BASER:
495 			lane_mask = 0xf;
496 			break;
497 		}
498 		break;
499 	case FBNIC_AUI_25GAUI:
500 		lane_mask = 1;
501 		break;
502 	}
503 
504 	/* Use an XOR to remove the bits we expect to see set */
505 	switch (fbn->fec) {
506 	case FBNIC_FEC_OFF:
507 		lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_BLOCK_LOCK,
508 				       pcs_status);
509 		break;
510 	case FBNIC_FEC_RS:
511 		lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_AMPS_LOCK,
512 				       pcs_status);
513 		break;
514 	case FBNIC_FEC_BASER:
515 		lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT1_FCFEC_LOCK,
516 				       rd32(fbd, FBNIC_SIG_PCS_OUT1));
517 		break;
518 	}
519 
520 	/* If all lanes cancelled then we have a lock on all lanes */
521 	return !lane_mask;
522 }
523 
fbnic_pcs_get_link_asic(struct fbnic_dev * fbd)524 static bool fbnic_pcs_get_link_asic(struct fbnic_dev *fbd)
525 {
526 	bool link;
527 
528 	/* Flush status bits to clear possible stale data,
529 	 * bits should reset themselves back to 1 if link is truly up
530 	 */
531 	wr32(fbd, FBNIC_SIG_PCS_OUT0, FBNIC_SIG_PCS_OUT0_LINK |
532 				      FBNIC_SIG_PCS_OUT0_BLOCK_LOCK |
533 				      FBNIC_SIG_PCS_OUT0_AMPS_LOCK);
534 	wr32(fbd, FBNIC_SIG_PCS_OUT1, FBNIC_SIG_PCS_OUT1_FCFEC_LOCK);
535 	wrfl(fbd);
536 
537 	/* Clear interrupt state due to recent changes. */
538 	wr32(fbd, FBNIC_SIG_PCS_INTR_STS,
539 	     FBNIC_SIG_PCS_INTR_LINK_DOWN | FBNIC_SIG_PCS_INTR_LINK_UP);
540 
541 	link = fbnic_mac_get_pcs_link_status(fbd);
542 
543 	/* Enable interrupt to only capture changes in link state */
544 	wr32(fbd, FBNIC_SIG_PCS_INTR_MASK,
545 	     ~FBNIC_SIG_PCS_INTR_LINK_DOWN & ~FBNIC_SIG_PCS_INTR_LINK_UP);
546 	wr32(fbd, FBNIC_INTR_MASK_CLEAR(0), 1u << FBNIC_PCS_MSIX_ENTRY);
547 
548 	return link;
549 }
550 
fbnic_mac_get_fw_settings(struct fbnic_dev * fbd,u8 * aui,u8 * fec)551 void fbnic_mac_get_fw_settings(struct fbnic_dev *fbd, u8 *aui, u8 *fec)
552 {
553 	/* Retrieve default speed from FW */
554 	switch (fbd->fw_cap.link_speed) {
555 	case FBNIC_FW_LINK_MODE_25CR:
556 		*aui = FBNIC_AUI_25GAUI;
557 		break;
558 	case FBNIC_FW_LINK_MODE_50CR2:
559 		*aui = FBNIC_AUI_LAUI2;
560 		break;
561 	case FBNIC_FW_LINK_MODE_50CR:
562 		*aui = FBNIC_AUI_50GAUI1;
563 		*fec = FBNIC_FEC_RS;
564 		return;
565 	case FBNIC_FW_LINK_MODE_100CR2:
566 		*aui = FBNIC_AUI_100GAUI2;
567 		*fec = FBNIC_FEC_RS;
568 		return;
569 	default:
570 		*aui = FBNIC_AUI_UNKNOWN;
571 		return;
572 	}
573 
574 	/* Update FEC first to reflect FW current mode */
575 	switch (fbd->fw_cap.link_fec) {
576 	case FBNIC_FW_LINK_FEC_NONE:
577 		*fec = FBNIC_FEC_OFF;
578 		break;
579 	case FBNIC_FW_LINK_FEC_RS:
580 	default:
581 		*fec = FBNIC_FEC_RS;
582 		break;
583 	case FBNIC_FW_LINK_FEC_BASER:
584 		*fec = FBNIC_FEC_BASER;
585 		break;
586 	}
587 }
588 
fbnic_pcs_enable_asic(struct fbnic_dev * fbd)589 static int fbnic_pcs_enable_asic(struct fbnic_dev *fbd)
590 {
591 	/* Mask and clear the PCS interrupt, will be enabled by link handler */
592 	wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, ~0);
593 	wr32(fbd, FBNIC_SIG_PCS_INTR_STS, ~0);
594 
595 	return 0;
596 }
597 
fbnic_pcs_disable_asic(struct fbnic_dev * fbd)598 static void fbnic_pcs_disable_asic(struct fbnic_dev *fbd)
599 {
600 	/* Mask and clear the PCS interrupt */
601 	wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, ~0);
602 	wr32(fbd, FBNIC_SIG_PCS_INTR_STS, ~0);
603 }
604 
fbnic_mac_link_down_asic(struct fbnic_dev * fbd)605 static void fbnic_mac_link_down_asic(struct fbnic_dev *fbd)
606 {
607 	u32 cmd_cfg, mac_ctrl;
608 
609 	cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, false, false);
610 	mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0);
611 
612 	mac_ctrl |= FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK |
613 		    FBNIC_SIG_MAC_IN0_RESET_TX_CLK |
614 		    FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK |
615 		    FBNIC_SIG_MAC_IN0_RESET_RX_CLK;
616 
617 	wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl);
618 	wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg);
619 }
620 
fbnic_mac_link_up_asic(struct fbnic_dev * fbd,bool tx_pause,bool rx_pause)621 static void fbnic_mac_link_up_asic(struct fbnic_dev *fbd,
622 				   bool tx_pause, bool rx_pause)
623 {
624 	u32 cmd_cfg, mac_ctrl;
625 
626 	fbnic_mac_tx_pause_config(fbd, tx_pause);
627 
628 	cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, tx_pause, rx_pause);
629 	mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0);
630 
631 	mac_ctrl &= ~(FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK |
632 		      FBNIC_SIG_MAC_IN0_RESET_TX_CLK |
633 		      FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK |
634 		      FBNIC_SIG_MAC_IN0_RESET_RX_CLK);
635 	cmd_cfg |= FBNIC_MAC_COMMAND_CONFIG_RX_ENA |
636 		   FBNIC_MAC_COMMAND_CONFIG_TX_ENA;
637 
638 	wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl);
639 	wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg);
640 }
641 
642 static void
fbnic_pcs_rsfec_stat_rd32(struct fbnic_dev * fbd,u32 reg,bool reset,struct fbnic_stat_counter * stat)643 fbnic_pcs_rsfec_stat_rd32(struct fbnic_dev *fbd, u32 reg, bool reset,
644 			  struct fbnic_stat_counter *stat)
645 {
646 	u32 pcs_rsfec_stat;
647 
648 	/* The PCS/RFSEC registers are only 16b wide each. So what we will
649 	 * have after the 64b read is 0x0000xxxx0000xxxx. To make it usable
650 	 * as a full stat we will shift the upper bits into the lower set of
651 	 * 0s and then mask off the math at 32b.
652 	 *
653 	 * Read ordering must be lower reg followed by upper reg.
654 	 */
655 	pcs_rsfec_stat = rd32(fbd, reg) & 0xffff;
656 	pcs_rsfec_stat |= rd32(fbd, reg + 1) << 16;
657 
658 	/* RFSEC registers clear themselves upon being read so there is no
659 	 * need to store the old_reg_value.
660 	 */
661 	if (!reset)
662 		stat->value += pcs_rsfec_stat;
663 }
664 
665 static void
fbnic_mac_get_fec_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_fec_stats * s)666 fbnic_mac_get_fec_stats(struct fbnic_dev *fbd, bool reset,
667 			struct fbnic_fec_stats *s)
668 {
669 	fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_CCW_LO(0), reset,
670 				  &s->corrected_blocks);
671 	fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_NCCW_LO(0), reset,
672 				  &s->uncorrectable_blocks);
673 }
674 
675 static void
fbnic_mac_get_pcs_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_pcs_stats * s)676 fbnic_mac_get_pcs_stats(struct fbnic_dev *fbd, bool reset,
677 			struct fbnic_pcs_stats *s)
678 {
679 	int i;
680 
681 	for (i = 0; i < FBNIC_PCS_MAX_LANES; i++)
682 		fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_PCS_SYMBLERR_LO(i), reset,
683 					  &s->SymbolErrorDuringCarrier.lanes[i]);
684 }
685 
686 static void
fbnic_mac_get_eth_mac_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_eth_mac_stats * mac_stats)687 fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
688 			    struct fbnic_eth_mac_stats *mac_stats)
689 {
690 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->OctetsReceivedOK,
691 			    MAC_STAT_RX_BYTE_COUNT);
692 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->AlignmentErrors,
693 			    MAC_STAT_RX_ALIGN_ERROR);
694 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->FrameTooLongErrors,
695 			    MAC_STAT_RX_TOOLONG);
696 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->FramesReceivedOK,
697 			    MAC_STAT_RX_RECEIVED_OK);
698 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->FrameCheckSequenceErrors,
699 			    MAC_STAT_RX_PACKET_BAD_FCS);
700 	fbnic_mac_stat_rd64(fbd, reset,
701 			    mac_stats->FramesLostDueToIntMACRcvError,
702 			    MAC_STAT_RX_IFINERRORS);
703 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->MulticastFramesReceivedOK,
704 			    MAC_STAT_RX_MULTICAST);
705 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->BroadcastFramesReceivedOK,
706 			    MAC_STAT_RX_BROADCAST);
707 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->OctetsTransmittedOK,
708 			    MAC_STAT_TX_BYTE_COUNT);
709 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->FramesTransmittedOK,
710 			    MAC_STAT_TX_TRANSMITTED_OK);
711 	fbnic_mac_stat_rd64(fbd, reset,
712 			    mac_stats->FramesLostDueToIntMACXmitError,
713 			    MAC_STAT_TX_IFOUTERRORS);
714 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->MulticastFramesXmittedOK,
715 			    MAC_STAT_TX_MULTICAST);
716 	fbnic_mac_stat_rd64(fbd, reset, mac_stats->BroadcastFramesXmittedOK,
717 			    MAC_STAT_TX_BROADCAST);
718 }
719 
720 static void
fbnic_mac_get_pause_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_pause_stats * pause_stats)721 fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset,
722 			  struct fbnic_pause_stats *pause_stats)
723 {
724 	fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames,
725 			    MAC_STAT_TX_XOFF_STB);
726 	fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames,
727 			    MAC_STAT_RX_XOFF_STB);
728 }
729 
730 static void
fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_eth_ctrl_stats * ctrl_stats)731 fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev *fbd, bool reset,
732 			     struct fbnic_eth_ctrl_stats *ctrl_stats)
733 {
734 	fbnic_mac_stat_rd64(fbd, reset, ctrl_stats->MACControlFramesReceived,
735 			    MAC_STAT_RX_CONTROL_FRAMES);
736 	fbnic_mac_stat_rd64(fbd, reset, ctrl_stats->MACControlFramesTransmitted,
737 			    MAC_STAT_TX_CONTROL_FRAMES);
738 }
739 
740 static void
fbnic_mac_get_rmon_stats(struct fbnic_dev * fbd,bool reset,struct fbnic_rmon_stats * rmon_stats)741 fbnic_mac_get_rmon_stats(struct fbnic_dev *fbd, bool reset,
742 			 struct fbnic_rmon_stats *rmon_stats)
743 {
744 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->undersize_pkts,
745 			    MAC_STAT_RX_UNDERSIZE);
746 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->oversize_pkts,
747 			    MAC_STAT_RX_OVERSIZE);
748 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->fragments,
749 			    MAC_STAT_RX_FRAGMENT);
750 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->jabbers,
751 			    MAC_STAT_RX_JABBER);
752 
753 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[0],
754 			    MAC_STAT_RX_PACKET_64_BYTES);
755 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[1],
756 			    MAC_STAT_RX_PACKET_65_127_BYTES);
757 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[2],
758 			    MAC_STAT_RX_PACKET_128_255_BYTES);
759 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[3],
760 			    MAC_STAT_RX_PACKET_256_511_BYTES);
761 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[4],
762 			    MAC_STAT_RX_PACKET_512_1023_BYTES);
763 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[5],
764 			    MAC_STAT_RX_PACKET_1024_1518_BYTES);
765 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[6],
766 			    RPC_STAT_RX_PACKET_1519_2047_BYTES);
767 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[7],
768 			    RPC_STAT_RX_PACKET_2048_4095_BYTES);
769 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[8],
770 			    RPC_STAT_RX_PACKET_4096_8191_BYTES);
771 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[9],
772 			    RPC_STAT_RX_PACKET_8192_9216_BYTES);
773 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[10],
774 			    RPC_STAT_RX_PACKET_9217_MAX_BYTES);
775 
776 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[0],
777 			    MAC_STAT_TX_PACKET_64_BYTES);
778 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[1],
779 			    MAC_STAT_TX_PACKET_65_127_BYTES);
780 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[2],
781 			    MAC_STAT_TX_PACKET_128_255_BYTES);
782 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[3],
783 			    MAC_STAT_TX_PACKET_256_511_BYTES);
784 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[4],
785 			    MAC_STAT_TX_PACKET_512_1023_BYTES);
786 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[5],
787 			    MAC_STAT_TX_PACKET_1024_1518_BYTES);
788 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[6],
789 			    TMI_STAT_TX_PACKET_1519_2047_BYTES);
790 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[7],
791 			    TMI_STAT_TX_PACKET_2048_4095_BYTES);
792 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[8],
793 			    TMI_STAT_TX_PACKET_4096_8191_BYTES);
794 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[9],
795 			    TMI_STAT_TX_PACKET_8192_9216_BYTES);
796 	fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[10],
797 			    TMI_STAT_TX_PACKET_9217_MAX_BYTES);
798 }
799 
fbnic_mac_get_sensor_asic(struct fbnic_dev * fbd,int id,long * val)800 static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id,
801 				     long *val)
802 {
803 	struct fbnic_fw_completion *fw_cmpl;
804 	int err = 0, retries = 5;
805 	s32 *sensor;
806 
807 	fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
808 	if (!fw_cmpl)
809 		return -ENOMEM;
810 
811 	switch (id) {
812 	case FBNIC_SENSOR_TEMP:
813 		sensor = &fw_cmpl->u.tsene.millidegrees;
814 		break;
815 	case FBNIC_SENSOR_VOLTAGE:
816 		sensor = &fw_cmpl->u.tsene.millivolts;
817 		break;
818 	default:
819 		err = -EINVAL;
820 		goto exit_free;
821 	}
822 
823 	err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);
824 	if (err) {
825 		dev_err(fbd->dev,
826 			"Failed to transmit TSENE read msg, err %d\n",
827 			err);
828 		goto exit_free;
829 	}
830 
831 	/* Allow 2 seconds for reply, resend and try up to 5 times */
832 	while (!wait_for_completion_timeout(&fw_cmpl->done, 2 * HZ)) {
833 		retries--;
834 
835 		if (retries == 0) {
836 			dev_err(fbd->dev,
837 				"Timed out waiting for TSENE read\n");
838 			err = -ETIMEDOUT;
839 			goto exit_cleanup;
840 		}
841 
842 		err = fbnic_fw_xmit_tsene_read_msg(fbd, NULL);
843 		if (err) {
844 			dev_err(fbd->dev,
845 				"Failed to transmit TSENE read msg, err %d\n",
846 				err);
847 			goto exit_cleanup;
848 		}
849 	}
850 
851 	/* Handle error returned by firmware */
852 	if (fw_cmpl->result) {
853 		err = fw_cmpl->result;
854 		dev_err(fbd->dev, "%s: Firmware returned error %d\n",
855 			__func__, err);
856 		goto exit_cleanup;
857 	}
858 
859 	*val = *sensor;
860 exit_cleanup:
861 	fbnic_mbx_clear_cmpl(fbd, fw_cmpl);
862 exit_free:
863 	fbnic_fw_put_cmpl(fw_cmpl);
864 
865 	return err;
866 }
867 
868 static const struct fbnic_mac fbnic_mac_asic = {
869 	.init_regs = fbnic_mac_init_regs,
870 	.pcs_enable = fbnic_pcs_enable_asic,
871 	.pcs_disable = fbnic_pcs_disable_asic,
872 	.pcs_get_link = fbnic_pcs_get_link_asic,
873 	.pcs_get_link_event = fbnic_pcs_get_link_event_asic,
874 	.get_fec_stats = fbnic_mac_get_fec_stats,
875 	.get_pcs_stats = fbnic_mac_get_pcs_stats,
876 	.get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
877 	.get_pause_stats = fbnic_mac_get_pause_stats,
878 	.get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats,
879 	.get_rmon_stats = fbnic_mac_get_rmon_stats,
880 	.link_down = fbnic_mac_link_down_asic,
881 	.link_up = fbnic_mac_link_up_asic,
882 	.get_sensor = fbnic_mac_get_sensor_asic,
883 };
884 
885 /**
886  * fbnic_mac_init - Assign a MAC type and initialize the fbnic device
887  * @fbd: Device pointer to device to initialize
888  *
889  * Return: zero on success, negative on failure
890  *
891  * Initialize the MAC function pointers and initializes the MAC of
892  * the device.
893  **/
fbnic_mac_init(struct fbnic_dev * fbd)894 int fbnic_mac_init(struct fbnic_dev *fbd)
895 {
896 	fbd->mac = &fbnic_mac_asic;
897 
898 	fbd->mac->init_regs(fbd);
899 
900 	return 0;
901 }
902