1 // SPDX-License-Identifier:    GPL-2.0
2 /*
3  * Copyright (C) 2018-2022 Marvell International Ltd.
4  */
5 
6 #include <dm.h>
7 #include <dm/device_compat.h>
8 #include <env.h>
9 #include <net.h>
10 #include <netdev.h>
11 #include <malloc.h>
12 #include <miiphy.h>
13 #include <misc.h>
14 #include <asm/io.h>
15 #include <linux/delay.h>
16 
17 #include <mach/cvmx-regs.h>
18 #include <mach/cvmx-csr.h>
19 #include <mach/cvmx-bootmem.h>
20 #include <mach/octeon-model.h>
21 #include <mach/cvmx-fuse.h>
22 #include <mach/octeon-feature.h>
23 #include <mach/octeon_fdt.h>
24 #include <mach/cvmx-qlm.h>
25 #include <mach/octeon_eth.h>
26 #include <mach/octeon_qlm.h>
27 #include <mach/cvmx-pcie.h>
28 #include <mach/cvmx-coremask.h>
29 
30 #include <mach/cvmx-agl-defs.h>
31 #include <mach/cvmx-asxx-defs.h>
32 #include <mach/cvmx-bgxx-defs.h>
33 #include <mach/cvmx-dbg-defs.h>
34 #include <mach/cvmx-gmxx-defs.h>
35 #include <mach/cvmx-gserx-defs.h>
36 #include <mach/cvmx-ipd-defs.h>
37 #include <mach/cvmx-l2c-defs.h>
38 #include <mach/cvmx-npi-defs.h>
39 #include <mach/cvmx-pcsx-defs.h>
40 #include <mach/cvmx-pexp-defs.h>
41 #include <mach/cvmx-pki-defs.h>
42 #include <mach/cvmx-pko-defs.h>
43 #include <mach/cvmx-smix-defs.h>
44 #include <mach/cvmx-sriox-defs.h>
45 #include <mach/cvmx-xcv-defs.h>
46 #include <mach/cvmx-pcsxx-defs.h>
47 
48 #include <mach/cvmx-helper.h>
49 #include <mach/cvmx-helper-board.h>
50 #include <mach/cvmx-helper-fdt.h>
51 #include <mach/cvmx-helper-bgx.h>
52 #include <mach/cvmx-helper-cfg.h>
53 
54 #include <mach/cvmx-hwpko.h>
55 #include <mach/cvmx-pko.h>
56 #include <mach/cvmx-pki.h>
57 #include <mach/cvmx-config.h>
58 #include <mach/cvmx-mdio.h>
59 
60 /** Maximum receive packet size (hardware default is 1536) */
61 #define CFG_OCTEON_NETWORK_MRU 1536
62 
63 #define OCTEON_BOOTLOADER_NAMED_BLOCK_TMP_PREFIX "__tmp"
64 
65 /**
66  * Enables RX packet debugging if octeon_debug_rx_packets is set in the
67  * environment.
68  */
69 #define DEBUG_RX_PACKET
70 
71 /**
72  * Enables TX packet debugging if octeon_debug_tx_packets is set in the
73  * environment.
74  */
75 #define DEBUG_TX_PACKET
76 
77 /* Global flag indicating common hw has been set up */
78 static int octeon_global_hw_inited;
79 
80 #if defined(DEBUG_RX_PACKET) || defined(DEBUG_TX_PACKET)
81 static int packet_rx_debug;
82 static int packet_tx_debug;
83 #endif
84 
85 /* Make sure that we have enough buffers to keep prefetching blocks happy.
86  * Absolute minimum is probably about 200.
87  */
88 #define NUM_PACKET_BUFFERS 1000
89 
90 #define PKO_SHUTDOWN_TIMEOUT_VAL 100
91 
92 /* Define the offsets from the base CSR */
93 #define GMX_PRT_CFG 0x10
94 
95 #define GMX_RX_FRM_MAX 0x30
96 #define GMX_RX_JABBER  0x38
97 
98 #define GMX_RX_ADR_CTL	  0x100
99 #define GMX_RX_ADR_CAM_EN 0x108
100 #define GMX_RX_ADR_CAM0	  0x180
101 #define GMX_RX_ADR_CAM1	  0x188
102 #define GMX_RX_ADR_CAM2	  0x190
103 #define GMX_RX_ADR_CAM3	  0x198
104 #define GMX_RX_ADR_CAM4	  0x1a0
105 #define GMX_RX_ADR_CAM5	  0x1a8
106 #define GMX_TX_OVR_BP	  0x4c8
107 
108 /**
109  * Set the hardware MAC address for a device
110  *
111  * @param interface    interface of port to set
112  * @param index    index of port to set MAC address for
113  * @param addr   Address structure to change it too.
114  * @return Zero on success
115  */
cvm_oct_set_mac_address(struct udevice * dev)116 static int cvm_oct_set_mac_address(struct udevice *dev)
117 {
118 	struct octeon_eth_info *priv = dev_get_priv(dev);
119 	struct eth_pdata *pdata = dev_get_plat(dev);
120 	cvmx_gmxx_prtx_cfg_t gmx_cfg;
121 	cvmx_helper_interface_mode_t mode;
122 	cvmx_gmxx_rxx_adr_ctl_t control;
123 	u8 *ptr = (uint8_t *)pdata->enetaddr;
124 	int interface = priv->interface;
125 	int index = priv->index;
126 	u64 mac = 0;
127 	u64 gmx_reg;
128 	int xipd_port;
129 	int i;
130 
131 	for (i = 0; i < 6; i++)
132 		mac = (mac << 8) | (u64)(ptr[i]);
133 
134 	debug("%s(%s (%pM))\n", __func__, dev->name, ptr);
135 	mode = cvmx_helper_interface_get_mode(interface);
136 
137 	/* It's rather expensive to change the MAC address for BGX so we only
138 	 * do this if it has changed or not been set previously.
139 	 */
140 	if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
141 		xipd_port = cvmx_helper_get_ipd_port(interface, index);
142 		if (priv->last_bgx_mac != mac || !priv->bgx_mac_set) {
143 			cvmx_helper_bgx_set_mac(xipd_port, 1, 2, mac);
144 			priv->last_bgx_mac = mac;
145 			priv->bgx_mac_set = 1;
146 		}
147 		return 0;
148 	}
149 
150 	if (mode == CVMX_HELPER_INTERFACE_MODE_AGL) {
151 		gmx_reg = CVMX_AGL_GMX_RXX_INT_REG(0);
152 	} else {
153 		gmx_reg = CVMX_GMXX_RXX_INT_REG(index, interface);
154 		csr_wr(CVMX_GMXX_SMACX(index, interface), mac);
155 	}
156 
157 	/* Disable interface */
158 	gmx_cfg.u64 = csr_rd(gmx_reg + GMX_PRT_CFG);
159 	csr_wr(gmx_reg + GMX_PRT_CFG, gmx_cfg.u64 & ~1ull);
160 	debug("%s: gmx reg: 0x%llx\n", __func__, gmx_reg);
161 
162 	csr_wr(gmx_reg + GMX_RX_ADR_CAM0, ptr[0]);
163 	csr_wr(gmx_reg + GMX_RX_ADR_CAM1, ptr[1]);
164 	csr_wr(gmx_reg + GMX_RX_ADR_CAM2, ptr[2]);
165 	csr_wr(gmx_reg + GMX_RX_ADR_CAM3, ptr[3]);
166 	csr_wr(gmx_reg + GMX_RX_ADR_CAM4, ptr[4]);
167 	csr_wr(gmx_reg + GMX_RX_ADR_CAM5, ptr[5]);
168 
169 	control.u64 = 0;
170 	control.s.bcst = 1;	/* Allow broadcast MAC addresses */
171 	control.s.mcst = 1;	/* Force reject multicast packets */
172 	control.s.cam_mode = 1; /* Filter packets based on the CAM */
173 
174 	csr_wr(gmx_reg + GMX_RX_ADR_CTL, control.u64);
175 
176 	csr_wr(gmx_reg + GMX_RX_ADR_CAM_EN, 1);
177 
178 	/* Return interface to previous enable state */
179 	csr_wr(gmx_reg + GMX_PRT_CFG, gmx_cfg.u64);
180 
181 	return 0;
182 }
183 
cvm_oct_fill_hw_memory(u64 pool,u64 size,u64 elements)184 static void cvm_oct_fill_hw_memory(u64 pool, u64 size, u64 elements)
185 {
186 	static int alloc_count;
187 	char tmp_name[64];
188 	int ret;
189 
190 	debug("%s: pool: 0x%llx, size: 0xx%llx, count: 0x%llx\n",
191 	      __func__, pool, size, elements);
192 	sprintf(tmp_name, "%s_fpa_alloc_%d",
193 		OCTEON_BOOTLOADER_NAMED_BLOCK_TMP_PREFIX, alloc_count++);
194 	ret = cvmx_fpa_setup_pool(pool, tmp_name, NULL, size, elements);
195 }
196 
197 /**
198  * Configure common hardware for all interfaces
199  */
cvm_oct_configure_common_hw(void)200 static void cvm_oct_configure_common_hw(void)
201 {
202 	int mru = env_get_ulong("octeon_mru", 0, CFG_OCTEON_NETWORK_MRU);
203 	int packet_pool_size = CVMX_FPA_PACKET_POOL_SIZE;
204 
205 	if (mru > packet_pool_size)
206 		packet_pool_size = (mru + CVMX_CACHE_LINE_SIZE - 1) &
207 				   ~(CVMX_CACHE_LINE_SIZE - 1);
208 
209 	/* Setup the FPA */
210 	cvmx_fpa_enable();
211 
212 	cvm_oct_fill_hw_memory(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
213 			       NUM_PACKET_BUFFERS);
214 #if CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL
215 	if (!octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
216 		cvm_oct_fill_hw_memory(CVMX_FPA_OUTPUT_BUFFER_POOL,
217 				       CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
218 	}
219 #endif
220 	cvm_oct_fill_hw_memory(CVMX_FPA_PACKET_POOL, packet_pool_size,
221 			       NUM_PACKET_BUFFERS);
222 
223 	cvmx_helper_initialize_packet_io_global();
224 	cvmx_helper_initialize_packet_io_local();
225 
226 	/* The MRU defaults to 1536 bytes by the hardware.  Setting
227 	 * CFG_OCTEON_NETWORK_MRU allows this to be overridden.
228 	 */
229 	if (octeon_has_feature(OCTEON_FEATURE_PKI)) {
230 		struct cvmx_pki_global_config gbl_cfg;
231 		int i;
232 
233 		cvmx_pki_read_global_config(0, &gbl_cfg);
234 		for (i = 0; i < CVMX_PKI_NUM_FRAME_CHECK; i++)
235 			gbl_cfg.frm_len[i].maxlen = mru;
236 		cvmx_pki_write_global_config(0, &gbl_cfg);
237 	}
238 
239 	/* Set POW get work timeout to maximum value */
240 	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE) ||
241 	    octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))
242 		csr_wr(CVMX_SSO_NW_TIM, 0x3ff);
243 	else
244 		csr_wr(CVMX_POW_NW_TIM, 0x3ff);
245 }
246 
247 /**
248  * Enables Ethernet devices to allow packets to be transmitted and received.
249  * For example, this is activated when the DHCP command is issued.
250  *
251  * @param	dev	Ethernet device to initialize
252  * @param	bis	board data structure, not used.
253  *
254  * @return	1 for success
255  */
octeon_eth_init(struct udevice * dev)256 int octeon_eth_init(struct udevice *dev)
257 {
258 	struct octeon_eth_info *priv = dev_get_priv(dev);
259 
260 	debug("%s(), dev_ptr: %p, dev: %s, port: %d\n", __func__, dev,
261 	      dev->name, priv->port);
262 
263 	if (priv->initted_flag) {
264 		debug("%s already initialized\n", dev->name);
265 		return 1;
266 	}
267 
268 	if (!octeon_global_hw_inited) {
269 		debug("Initializing common hardware\n");
270 		cvm_oct_configure_common_hw();
271 	}
272 
273 	/* Ignore backpressure on RGMII ports */
274 	if (!octeon_has_feature(OCTEON_FEATURE_BGX))
275 		csr_wr(priv->gmx_base + GMX_TX_OVR_BP, 0xf << 8 | 0xf);
276 
277 	debug("%s: Setting MAC address\n", __func__);
278 	cvm_oct_set_mac_address(dev);
279 
280 	if (!octeon_global_hw_inited) {
281 		debug("Enabling packet input\n");
282 		cvmx_helper_ipd_and_packet_input_enable();
283 		octeon_global_hw_inited = 1;
284 
285 		/* Connect, configure and start the PHY, if the device is
286 		 * connected to one. If not, then it's most likely an SPF
287 		 * enabled port, which does not have such PHY setup here.
288 		 */
289 		if (priv->mdio_dev) {
290 			priv->phy_dev = dm_eth_phy_connect(dev);
291 			phy_config(priv->phy_dev);
292 			phy_startup(priv->phy_dev);
293 		}
294 	}
295 	priv->enabled = 0;
296 	priv->initted_flag = 1;
297 
298 	debug("%s exiting successfully\n", __func__);
299 	return 1;
300 }
301 
302 /**
303  * Initializes the specified interface and port
304  *
305  * @param	interface	interface to initialize
306  * @param	index		port index on interface
307  * @param	port		ipd port number
308  * @param	if_mode		interface mode
309  *
310  * @return	0 for success, -1 if out of memory, 1 if port is invalid
311  */
octeon_eth_initialize(struct udevice * dev,int interface,int index,int port,cvmx_helper_interface_mode_t if_mode)312 static int octeon_eth_initialize(struct udevice *dev, int interface,
313 				 int index, int port,
314 				 cvmx_helper_interface_mode_t if_mode)
315 {
316 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
317 	int eth;
318 
319 	eth = cvmx_helper_get_port_fdt_node_offset(interface, index);
320 	if (eth <= 0) {
321 		debug("ERROR: No fdt node for interface %d, index %d\n",
322 		      interface, index);
323 		return 1;
324 	}
325 
326 	oct_eth_info->is_c45 = (if_mode == CVMX_HELPER_INTERFACE_MODE_XAUI) ||
327 			       (if_mode == CVMX_HELPER_INTERFACE_MODE_RXAUI) ||
328 			       (if_mode == CVMX_HELPER_INTERFACE_MODE_XFI) ||
329 			       (if_mode == CVMX_HELPER_INTERFACE_MODE_XLAUI) ||
330 			       (if_mode == CVMX_HELPER_INTERFACE_MODE_10G_KR) ||
331 			       (if_mode == CVMX_HELPER_INTERFACE_MODE_10G_KR);
332 	oct_eth_info->port = port;
333 	oct_eth_info->index = index;
334 	oct_eth_info->interface = interface;
335 	oct_eth_info->initted_flag = 0;
336 	/* This is guaranteed to force the link state to be printed out */
337 	oct_eth_info->link_state = 0xffffffffffffffffULL;
338 	debug("Setting up port: %d, int: %d, index: %d, device: octeth%d\n",
339 	      oct_eth_info->port, oct_eth_info->interface, oct_eth_info->index,
340 	      dev_seq(dev));
341 	if (if_mode == CVMX_HELPER_INTERFACE_MODE_AGL) {
342 		oct_eth_info->gmx_base = CVMX_AGL_GMX_RXX_INT_REG(0);
343 	} else {
344 		if (!octeon_has_feature(OCTEON_FEATURE_BGX))
345 			oct_eth_info->gmx_base =
346 				CVMX_GMXX_RXX_INT_REG(index, interface);
347 	}
348 
349 	return 0;
350 }
351 
352 /**
353  * @INTERNAL
354  * Converts a BGX address to the node, interface and port number
355  *
356  * @param bgx_addr	Address of CSR register
357  *
358  * @return node, interface and port number, will be -1 for invalid address.
359  */
__cvmx_bgx_reg_addr_to_xiface(u64 bgx_addr)360 static struct cvmx_xiface __cvmx_bgx_reg_addr_to_xiface(u64 bgx_addr)
361 {
362 	struct cvmx_xiface xi = { -1, -1 };
363 
364 	xi.node = cvmx_csr_addr_to_node(bgx_addr);
365 	bgx_addr = cvmx_csr_addr_strip_node(bgx_addr);
366 	if ((bgx_addr & 0xFFFFFFFFF0000000) != 0x00011800E0000000) {
367 		debug("%s: Invalid BGX address 0x%llx\n", __func__,
368 		      (unsigned long long)bgx_addr);
369 		xi.node = -1;
370 		return xi;
371 	}
372 	xi.interface = (bgx_addr >> 24) & 0x0F;
373 
374 	return xi;
375 }
376 
octeon_nic_probe(struct udevice * dev)377 static int octeon_nic_probe(struct udevice *dev)
378 {
379 	struct octeon_eth_info *info = dev_get_priv(dev);
380 	struct ofnode_phandle_args phandle;
381 	struct cvmx_xiface xi;
382 	ofnode node, mdio_node;
383 	int ipd_port;
384 	int intf;
385 	int ret;
386 
387 	/* The empty stub is to keep cvmx_user_app_init() happy. */
388 	cvmx_npi_max_pknds = 1;
389 	__cvmx_helper_init_port_valid();
390 
391 	xi = __cvmx_bgx_reg_addr_to_xiface(dev_read_addr(dev));
392 	intf = xi.interface;
393 	debug("%s: Found BGX node %d, interface %d\n", __func__, xi.node, intf);
394 
395 	ipd_port = cvmx_helper_get_ipd_port(intf, xi.node);
396 	ret = octeon_eth_initialize(dev, intf, xi.node, ipd_port,
397 				    cvmx_helper_interface_get_mode(intf));
398 
399 	/* Move to subnode, as this includes the "phy-handle" */
400 	node = dev_read_first_subnode(dev);
401 
402 	/* Check if an SPF module is conneted, then no MDIO is probed */
403 	ret = ofnode_parse_phandle_with_args(node, "sfp-slot", NULL, 0, 0,
404 					     &phandle);
405 	if (!ret) {
406 		dev_dbg(dev, "sfp-slot found, not probing for MDIO\n");
407 		return 0;
408 	}
409 
410 	/* Continue with MDIO probing */
411 	ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
412 					     &phandle);
413 	if (ret) {
414 		dev_err(dev, "phy-handle not found in subnode\n");
415 		return -ENODEV;
416 	}
417 
418 	/* Get MDIO node */
419 	mdio_node = ofnode_get_parent(phandle.node);
420 	ret = uclass_get_device_by_ofnode(UCLASS_MDIO, mdio_node,
421 					  &info->mdio_dev);
422 	if (ret) {
423 		dev_err(dev, "mdio_dev not found\n");
424 		return -ENODEV;
425 	}
426 
427 	return 0;
428 }
429 
430 /**
431  * Sets the hardware MAC address of the Ethernet device
432  *
433  * @param dev - Ethernet device
434  *
435  * @return 0 for success
436  */
octeon_eth_write_hwaddr(struct udevice * dev)437 int octeon_eth_write_hwaddr(struct udevice *dev)
438 {
439 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
440 	struct eth_pdata *pdata = dev_get_plat(dev);
441 
442 	/* Skip if the interface isn't yet enabled */
443 	if (!oct_eth_info->enabled) {
444 		debug("%s: Interface not enabled, not setting MAC address\n",
445 		      __func__);
446 		return 0;
447 	}
448 	debug("%s: Setting %s address to %02x:%02x:%02x:%02x:%02x:%02x\n",
449 	      __func__, dev->name, pdata->enetaddr[0], pdata->enetaddr[1],
450 	      pdata->enetaddr[2], pdata->enetaddr[3], pdata->enetaddr[4],
451 	      pdata->enetaddr[5]);
452 	return cvm_oct_set_mac_address(dev);
453 }
454 
455 /**
456  * Enables and disables the XCV RGMII interface
457  *
458  * @param	interface	Interface number
459  * @param	index		Port index (should be 0 for RGMII)
460  * @param	enable		True to enable it, false to disable it
461  */
octeon_bgx_xcv_rgmii_enable(int interface,int index,bool enable)462 static void octeon_bgx_xcv_rgmii_enable(int interface, int index, bool enable)
463 {
464 	union cvmx_xcv_reset xcv_reset;
465 
466 	debug("%s(%d, %d, %sable)\n", __func__, interface, index,
467 	      enable ? "en" : "dis");
468 	xcv_reset.u64 = csr_rd(CVMX_XCV_RESET);
469 	xcv_reset.s.rx_pkt_rst_n = enable ? 1 : 0;
470 	csr_wr(CVMX_XCV_RESET, xcv_reset.u64);
471 }
472 
473 /**
474  * Enables a SGMII interface
475  *
476  * @param dev - Ethernet device to initialize
477  */
octeon_eth_sgmii_enable(struct udevice * dev)478 void octeon_eth_sgmii_enable(struct udevice *dev)
479 {
480 	struct octeon_eth_info *oct_eth_info;
481 	cvmx_gmxx_prtx_cfg_t gmx_cfg;
482 	int index, interface;
483 	cvmx_helper_interface_mode_t if_mode;
484 
485 	oct_eth_info = dev_get_priv(dev);
486 	interface = oct_eth_info->interface;
487 	index = oct_eth_info->index;
488 
489 	debug("%s(%s) (%d.%d)\n", __func__, dev->name, interface, index);
490 	if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
491 		cvmx_bgxx_cmrx_config_t cmr_config;
492 
493 		cmr_config.u64 =
494 			csr_rd(CVMX_BGXX_CMRX_CONFIG(index, interface));
495 		cmr_config.s.enable = 1;
496 		cmr_config.s.data_pkt_tx_en = 1;
497 		cmr_config.s.data_pkt_rx_en = 1;
498 		csr_wr(CVMX_BGXX_CMRX_CONFIG(index, interface), cmr_config.u64);
499 		mdelay(100);
500 		if (cvmx_helper_bgx_is_rgmii(interface, index))
501 			octeon_bgx_xcv_rgmii_enable(interface, index, true);
502 	} else {
503 		if_mode = cvmx_helper_interface_get_mode(interface);
504 		/* Normal operating mode. */
505 
506 		if (if_mode == CVMX_HELPER_INTERFACE_MODE_SGMII ||
507 		    if_mode == CVMX_HELPER_INTERFACE_MODE_QSGMII) {
508 			cvmx_pcsx_miscx_ctl_reg_t pcsx_miscx_ctl_reg;
509 
510 			debug("  if mode: (Q)SGMII\n");
511 			pcsx_miscx_ctl_reg.u64 = csr_rd(CVMX_PCSX_MISCX_CTL_REG(index, interface));
512 			pcsx_miscx_ctl_reg.s.gmxeno = 0;
513 			csr_wr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
514 			       pcsx_miscx_ctl_reg.u64);
515 		} else if (if_mode != CVMX_HELPER_INTERFACE_MODE_AGL) {
516 			cvmx_pcsxx_misc_ctl_reg_t pcsxx_misc_ctl_reg;
517 
518 			debug("  if mode: AGM\n");
519 			pcsxx_misc_ctl_reg.u64 =
520 				csr_rd(CVMX_PCSXX_MISC_CTL_REG(interface));
521 			pcsxx_misc_ctl_reg.s.gmxeno = 0;
522 			csr_wr(CVMX_PCSXX_MISC_CTL_REG(interface),
523 			       pcsxx_misc_ctl_reg.u64);
524 		}
525 
526 		gmx_cfg.u64 = csr_rd(oct_eth_info->gmx_base + GMX_PRT_CFG);
527 		gmx_cfg.s.en = 1;
528 		csr_wr(oct_eth_info->gmx_base + GMX_PRT_CFG, gmx_cfg.u64);
529 		gmx_cfg.u64 = csr_rd(oct_eth_info->gmx_base + GMX_PRT_CFG);
530 	}
531 }
532 
533 /**
534  * Enables an Ethernet interface
535  *
536  * @param dev - Ethernet device to enable
537  */
octeon_eth_enable(struct udevice * dev)538 void octeon_eth_enable(struct udevice *dev)
539 {
540 	struct octeon_eth_info *oct_eth_info;
541 	u64 tmp;
542 	int interface;
543 	cvmx_helper_interface_mode_t if_mode;
544 
545 	oct_eth_info = dev_get_priv(dev);
546 	interface = oct_eth_info->interface;
547 	if_mode = cvmx_helper_interface_get_mode(interface);
548 
549 	switch (if_mode) {
550 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
551 	case CVMX_HELPER_INTERFACE_MODE_GMII:
552 		debug("  rgmii/gmii mode\n");
553 		tmp = csr_rd(CVMX_ASXX_RX_PRT_EN(interface));
554 		tmp |= (1ull << (oct_eth_info->port & 0x3));
555 		csr_wr(CVMX_ASXX_RX_PRT_EN(interface), tmp);
556 		tmp = csr_rd(CVMX_ASXX_TX_PRT_EN(interface));
557 		tmp |= (1ull << (oct_eth_info->port & 0x3));
558 		csr_wr(CVMX_ASXX_TX_PRT_EN(interface), tmp);
559 		octeon_eth_write_hwaddr(dev);
560 		break;
561 
562 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
563 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
564 	case CVMX_HELPER_INTERFACE_MODE_RXAUI:
565 	case CVMX_HELPER_INTERFACE_MODE_XLAUI:
566 	case CVMX_HELPER_INTERFACE_MODE_XFI:
567 	case CVMX_HELPER_INTERFACE_MODE_10G_KR:
568 	case CVMX_HELPER_INTERFACE_MODE_40G_KR4:
569 	case CVMX_HELPER_INTERFACE_MODE_MIXED:
570 	case CVMX_HELPER_INTERFACE_MODE_AGL:
571 		debug("  SGMII/XAUI/etc.\n");
572 		octeon_eth_sgmii_enable(dev);
573 		octeon_eth_write_hwaddr(dev);
574 		break;
575 
576 	default:
577 		break;
578 	}
579 }
580 
octeon_phy_port_check(struct udevice * dev)581 void octeon_phy_port_check(struct udevice *dev)
582 {
583 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
584 	struct phy_device *phydev = oct_eth_info->phydev;
585 
586 	if (oct_eth_info->phy_port_check)
587 		oct_eth_info->phy_port_check(phydev);
588 }
589 
590 /**
591  * Configure the RGMII port for the negotiated speed
592  *
593  * @param dev    Linux device for the RGMII port
594  */
cvm_oct_configure_rgmii_speed(struct udevice * dev)595 static void cvm_oct_configure_rgmii_speed(struct udevice *dev)
596 {
597 	struct octeon_eth_info *priv = dev_get_priv(dev);
598 	int port = priv->port;
599 	cvmx_helper_link_info_t link_state = cvmx_helper_link_get(port);
600 
601 	/* If the port is down some PHYs we need to check modules, etc. */
602 	if (!link_state.s.link_up)
603 		octeon_phy_port_check(dev);
604 
605 	if (link_state.u64 != priv->link_state) {
606 		cvmx_helper_interface_mode_t mode;
607 
608 		octeon_phy_port_check(dev);
609 
610 		debug("%s(%s): Link state changed\n", __func__, dev->name);
611 		printf("%s: ", dev->name);
612 		if (!link_state.s.link_up) {
613 			puts("Down ");
614 		} else {
615 			printf("Up %d Mbps ", link_state.s.speed);
616 			if (link_state.s.full_duplex)
617 				puts("Full duplex ");
618 			else
619 				puts("Half duplex ");
620 		}
621 		mode = cvmx_helper_interface_get_mode(priv->interface);
622 		printf("(port %2d) (%s)\n", port,
623 		       cvmx_helper_interface_mode_to_string(mode));
624 		debug("%s: Setting link state\n", __func__);
625 		cvmx_helper_link_set(priv->port, link_state);
626 		priv->link_state = link_state.u64;
627 	}
628 }
629 
630 #if defined(DEBUG_TX_PACKET) || defined(DEBUG_RX_PACKET)
print_mac(const char * label,const uint8_t * mac_addr)631 static void print_mac(const char *label, const uint8_t *mac_addr)
632 {
633 	printf("%s: %02x:%02x:%02x:%02x:%02x:%02x", label, mac_addr[0],
634 	       mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
635 }
636 
print_ip(const void * packet)637 static void print_ip(const void *packet)
638 {
639 	u8 *p = (uint8_t *)packet;
640 	u16 length;
641 	u8 hdr_len;
642 
643 	puts("IP Header:\n");
644 	if ((p[0] & 0xF0) != 0x40) {
645 		printf("Invalid IP version %d\n", *p >> 4);
646 		return;
647 	}
648 	hdr_len = *p & 0x0F;
649 	if (hdr_len < 5)
650 		printf("Invalid IP header length %d\n", hdr_len);
651 	printf("  Version: 4, Header length: %d\n", hdr_len);
652 	length = (p[2] << 8) | p[3];
653 	printf("  TOS: 0x%02x, length: %d\n", p[1], length);
654 	printf("  ID: %d, %s%s%s fragment offset: %d\n", (p[4] << 8) | p[5],
655 	       p[6] & 0x80 ? "congested, " : "", p[6] & 0x40 ? "DF, " : "",
656 	       p[6] & 0x20 ? "MF, " : "", ((p[6] & 0x1F) << 8) | p[7]);
657 	printf("  TTL: %d, Protocol: %d, Header Checksum: 0x%x\n", p[8], p[9],
658 	       (p[10] << 8) | p[11]);
659 	printf("  Source IP: %d.%d.%d.%d\n  Destination IP: %d.%d.%d.%d\n",
660 	       p[12], p[13], p[14], p[15], p[16], p[17], p[18], p[19]);
661 	if (p[9] == 17 || p[9] == 6)
662 		printf("  Source port: %u, Destination port: %u\n",
663 		       (p[20] << 8) | p[21], (p[22] << 8) | p[23]);
664 	puts("\n");
665 }
666 
667 /**
668  * Prints out a packet for debugging purposes
669  *
670  * @param[in]	packet - pointer to packet data
671  * @param	length - length of packet in bytes
672  */
print_packet(const void * packet,int length)673 static void print_packet(const void *packet, int length)
674 {
675 	int i, j;
676 	const unsigned char *up = packet;
677 	u16 type = (up[12] << 8 | up[13]);
678 	int start = 14;
679 
680 	print_mac("DMAC", &up[0]);
681 	puts("    ");
682 	print_mac("SMAC", &up[6]);
683 	printf("    TYPE: %04x\n", type);
684 
685 	if (type == 0x0800)
686 		print_ip(&up[start]);
687 
688 	for (i = start; (i + 16) < length; i += 16) {
689 		printf("%04x ", i);
690 		for (j = 0; j < 16; ++j)
691 			printf("%02x ", up[i + j]);
692 
693 		printf("    ");
694 		for (j = 0; j < 16; ++j)
695 			printf("%c",
696 			       ((up[i + j] >= ' ') && (up[i + j] <= '~')) ?
697 				       up[i + j] :
698 					     '.');
699 		printf("\n");
700 	}
701 	printf("%04x ", i);
702 	for (j = 0; i + j < length; ++j)
703 		printf("%02x ", up[i + j]);
704 
705 	for (; j < 16; ++j)
706 		printf("   ");
707 
708 	printf("    ");
709 	for (j = 0; i + j < length; ++j)
710 		printf("%c", ((up[i + j] >= ' ') && (up[i + j] <= '~')) ?
711 				     up[i + j] :
712 					   '.');
713 
714 	printf("\n");
715 }
716 #endif
717 
718 /**
719  * String representation of error codes.
720  */
721 static const char * const rx_error_codes[] = {
722 	"OK",
723 	"partial",
724 	"jabber",
725 	"overrun",
726 	"oversize",
727 	"alignment",
728 	"fragment",
729 	"fcs",
730 	"undersize",
731 	"extend",
732 	"length mismatch",
733 	"rgmii rx",
734 	"skip error",
735 	"nibble error (studder)",
736 	"(undefined)",
737 	"(undefined)",
738 	"SPI 4.2 FCS",
739 	"skip",
740 	"L2 malformed",
741 };
742 
743 /**
744  * Called to receive a packet
745  *
746  * @param dev - device to receive on
747  *
748  * @return - length of packet
749  *
750  * This function is used to poll packets.  In turn it calls NetReceive
751  * to process the packets.
752  */
nic_recv(struct udevice * dev,int flags,uchar ** packetp)753 static int nic_recv(struct udevice *dev, int flags, uchar **packetp)
754 {
755 	cvmx_wqe_t *work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
756 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
757 	cvmx_buf_ptr_t buf_ptr;
758 	void *packet_data;
759 	int length;
760 	int error_code;
761 
762 	if (!oct_eth_info->enabled) {
763 		oct_eth_info->enabled = 1;
764 		debug("%s: Enabling interface %s\n", __func__, dev->name);
765 		octeon_eth_enable(dev);
766 	}
767 
768 	if (!work) {
769 		/*
770 		 * Somtimes the link is not up yet. Return here in this
771 		 * case, this function will be called again later.
772 		 */
773 		return 0;
774 	}
775 
776 	error_code = cvmx_wqe_get_rcv_err(work);
777 	if (error_code) {
778 		/* Work has error, so drop */
779 		cvmx_helper_free_packet_data(work);
780 		cvmx_wqe_free(work);
781 		if (error_code < ARRAY_SIZE(rx_error_codes) &&
782 		    !octeon_has_feature(OCTEON_FEATURE_BGX))
783 			printf("Receive error (code %d: %s), dropping\n",
784 			       error_code, rx_error_codes[error_code]);
785 		else
786 			printf("Receive error (code %d (unknown), dropping\n",
787 			       error_code);
788 		return 0;
789 	}
790 	if (cvmx_wqe_get_bufs(work) != 1) {
791 		/* can only support single-buffer packets */
792 		printf("Abnormal packet received in %u bufs, dropping\n",
793 		       cvmx_wqe_get_bufs(work));
794 		length = cvmx_wqe_get_len(work);
795 		buf_ptr = cvmx_wqe_get_packet_ptr(work);
796 		packet_data = cvmx_phys_to_ptr(buf_ptr.s.addr);
797 		print_packet(packet_data, length);
798 		cvmx_helper_free_packet_data(work);
799 		cvmx_wqe_free(work);
800 		return 0;
801 	}
802 
803 	buf_ptr = cvmx_wqe_get_packet_ptr(work);
804 	packet_data = cvmx_phys_to_ptr(buf_ptr.s.addr);
805 	length = cvmx_wqe_get_len(work);
806 
807 	oct_eth_info->packets_received++;
808 	debug("############# got work: %p, len: %d, packet_ptr: %p\n", work,
809 	      length, packet_data);
810 #if defined(DEBUG_RX_PACKET)
811 	if (packet_rx_debug) {
812 		printf("\nRX packet: interface: %d, index: %d\n",
813 		       oct_eth_info->interface, oct_eth_info->index);
814 		print_packet(packet_data, length);
815 	}
816 #endif
817 	*packetp = (uchar *)packet_data;
818 
819 	/* Save work for free_pkt() */
820 	oct_eth_info->work = work;
821 
822 	/* Free WQE and packet data */
823 	return length;
824 }
825 
nic_free_pkt(struct udevice * dev,uchar * pkt,int pkt_len)826 static int nic_free_pkt(struct udevice *dev, uchar *pkt, int pkt_len)
827 {
828 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
829 	cvmx_wqe_t *work = oct_eth_info->work;
830 
831 	if (!work)
832 		return 0;
833 
834 	cvmx_helper_free_packet_data(work);
835 	cvmx_wqe_free(work);
836 	oct_eth_info->work = NULL;
837 
838 	return 0;
839 }
840 
841 /**
842  * Packet transmit
843  *
844  * @param skb    Packet to send
845  * @param dev    Device info structure
846  * @return Always returns zero
847  */
cvm_oct_xmit(struct udevice * dev,void * packet,int len)848 static int cvm_oct_xmit(struct udevice *dev, void *packet, int len)
849 {
850 	struct octeon_eth_info *priv = dev_get_priv(dev);
851 	int queue = cvmx_pko_get_base_queue(priv->port);
852 	cvmx_pko_command_word0_t pko_command;
853 	cvmx_buf_ptr_t hw_buffer;
854 	int rv;
855 
856 	debug("%s: addr: %p, len: %d\n", __func__, packet, len);
857 
858 	hw_buffer.u64 = 0;
859 	hw_buffer.s.addr = cvmx_ptr_to_phys(packet);
860 	hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
861 	hw_buffer.s.size = len;
862 	hw_buffer.s.back = 0;
863 
864 	/* Build the PKO command */
865 	pko_command.u64 = 0;
866 	pko_command.s.subone0 = 1;
867 	pko_command.s.dontfree = 0;
868 	pko_command.s.segs = 1;
869 	pko_command.s.total_bytes = len;
870 	/* Send the packet to the output queue */
871 
872 	debug("%s: port: %d, queue: %d\n", __func__, priv->port, queue);
873 	cvmx_pko_send_packet_prepare(priv->port, queue, 0);
874 	rv = cvmx_pko_send_packet_finish(priv->port, queue, pko_command,
875 					 hw_buffer, 0);
876 	if (rv)
877 		printf("Failed to send the packet rv=%d\n", rv);
878 
879 	return 0;
880 }
881 
nic_xmit(struct udevice * dev,void * pkt,int pkt_len)882 static int nic_xmit(struct udevice *dev, void *pkt, int pkt_len)
883 {
884 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
885 	void *fpa_buf = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
886 
887 	if (!oct_eth_info->enabled) {
888 		oct_eth_info->enabled = 1;
889 		octeon_eth_enable(dev);
890 	}
891 
892 	/* We need to copy this to a FPA buffer, then give that to TX */
893 
894 	if (oct_eth_info->packets_sent == 0 &&
895 	    !octeon_has_feature(OCTEON_FEATURE_BGX))
896 		cvm_oct_configure_rgmii_speed(dev);
897 
898 	if (!fpa_buf) {
899 		printf("ERROR allocating buffer for packet!\n");
900 		return -1;
901 	}
902 
903 	memcpy(fpa_buf, pkt, pkt_len);
904 #ifdef DEBUG_TX_PACKET
905 	if (packet_tx_debug) {
906 		printf("\nTX packet: interface: %d, index: %d\n",
907 		       oct_eth_info->interface, oct_eth_info->index);
908 		print_packet(pkt, pkt_len);
909 	}
910 #endif
911 	cvm_oct_xmit(dev, fpa_buf, pkt_len);
912 	oct_eth_info->packets_sent++;
913 
914 	return 0;
915 }
916 
nic_open(struct udevice * dev)917 int nic_open(struct udevice *dev)
918 {
919 	octeon_eth_init(dev);
920 
921 	return 0;
922 }
923 
octeon_eth_halt_bgx(struct udevice * dev,cvmx_helper_interface_mode_t mode)924 static void octeon_eth_halt_bgx(struct udevice *dev,
925 				cvmx_helper_interface_mode_t mode)
926 {
927 	union cvmx_bgxx_cmrx_config cmr_config;
928 	union cvmx_bgxx_cmr_rx_adrx_cam cmr_cam;
929 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
930 	int index = oct_eth_info->index;
931 	int xiface = oct_eth_info->interface;
932 	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
933 
934 	debug("%s(%s(%d.%d), %d)\n", __func__, dev->name, xiface, index, mode);
935 
936 	/* For RGMII we need to properly shut down the XCV interface */
937 	if (cvmx_helper_bgx_is_rgmii(xiface, index)) {
938 		debug("  Shut down XCV RGMII\n");
939 		octeon_bgx_xcv_rgmii_enable(xi.interface, index, false);
940 	} else {
941 		cmr_config.u64 = csr_rd_node(xi.node,
942 					     CVMX_BGXX_CMRX_CONFIG(index, xi.interface));
943 		cmr_config.s.data_pkt_tx_en = 0;
944 		cmr_config.s.data_pkt_rx_en = 0;
945 		csr_wr_node(xi.node, CVMX_BGXX_CMRX_CONFIG(index, xi.interface),
946 			    cmr_config.u64);
947 
948 		cmr_cam.u64 = csr_rd_node(xi.node,
949 					  CVMX_BGXX_CMR_RX_ADRX_CAM(index * 8, xi.interface));
950 		cmr_cam.s.en = 0;
951 		csr_wr_node(xi.node,
952 			    CVMX_BGXX_CMR_RX_ADRX_CAM(index * 8, xi.interface),
953 			    cmr_cam.u64);
954 		oct_eth_info->last_bgx_mac = 0;
955 		oct_eth_info->bgx_mac_set = 0;
956 	}
957 }
958 
959 /**
960  * Halts the specified Ethernet interface preventing it from receiving any more
961  * packets.
962  *
963  * @param dev - Ethernet device to shut down.
964  */
octeon_eth_halt(struct udevice * dev)965 void octeon_eth_halt(struct udevice *dev)
966 {
967 	struct octeon_eth_info *oct_eth_info = dev_get_priv(dev);
968 	int index = oct_eth_info->index;
969 	int interface = oct_eth_info->interface;
970 	cvmx_helper_interface_mode_t mode;
971 	union cvmx_gmxx_rxx_adr_ctl adr_ctl;
972 	cvmx_gmxx_prtx_cfg_t gmx_cfg;
973 	u64 tmp;
974 
975 	debug("%s(%s): Halting\n", __func__, dev->name);
976 
977 	oct_eth_info->enabled = 0;
978 
979 	mode = cvmx_helper_interface_get_mode(oct_eth_info->interface);
980 	if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
981 		octeon_eth_halt_bgx(dev, mode);
982 		return;
983 	}
984 
985 	/* Stop SCC */
986 	/* Disable reception on this port at the GMX block */
987 	switch (mode) {
988 	case CVMX_HELPER_INTERFACE_MODE_RGMII:
989 	case CVMX_HELPER_INTERFACE_MODE_GMII:
990 		debug("  RGMII/GMII\n");
991 		tmp = csr_rd(CVMX_ASXX_RX_PRT_EN(oct_eth_info->interface));
992 		tmp &= ~(1ull << index);
993 		/* Disable the RGMII RX ports */
994 		csr_wr(CVMX_ASXX_RX_PRT_EN(oct_eth_info->interface), tmp);
995 		tmp = csr_rd(CVMX_ASXX_TX_PRT_EN(oct_eth_info->interface));
996 		tmp &= ~(1ull << index);
997 		/* Disable the RGMII TX ports */
998 		csr_wr(CVMX_ASXX_TX_PRT_EN(oct_eth_info->interface), tmp);
999 		/* No break! */
1000 	case CVMX_HELPER_INTERFACE_MODE_SGMII:
1001 	case CVMX_HELPER_INTERFACE_MODE_QSGMII:
1002 	case CVMX_HELPER_INTERFACE_MODE_XAUI:
1003 	case CVMX_HELPER_INTERFACE_MODE_RXAUI:
1004 	case CVMX_HELPER_INTERFACE_MODE_XLAUI:
1005 	case CVMX_HELPER_INTERFACE_MODE_XFI:
1006 	case CVMX_HELPER_INTERFACE_MODE_10G_KR:
1007 	case CVMX_HELPER_INTERFACE_MODE_40G_KR4:
1008 	case CVMX_HELPER_INTERFACE_MODE_MIXED:
1009 	case CVMX_HELPER_INTERFACE_MODE_AGL:
1010 		/* Disable MAC filtering */
1011 		gmx_cfg.u64 = csr_rd(oct_eth_info->gmx_base + GMX_PRT_CFG);
1012 		csr_wr(oct_eth_info->gmx_base + GMX_PRT_CFG,
1013 		       gmx_cfg.u64 & ~1ull);
1014 		adr_ctl.u64 = 0;
1015 		adr_ctl.s.bcst = 1; /* Reject broadcast */
1016 		csr_wr(oct_eth_info->gmx_base + GMX_RX_ADR_CTL, adr_ctl.u64);
1017 		csr_wr(oct_eth_info->gmx_base + GMX_RX_ADR_CAM_EN, 0);
1018 		csr_wr(oct_eth_info->gmx_base + GMX_PRT_CFG, gmx_cfg.u64);
1019 		break;
1020 	default:
1021 		printf("%s: Unknown mode %d for interface 0x%x:%d\n", __func__,
1022 		       mode, interface, index);
1023 		break;
1024 	}
1025 }
1026 
nic_stop(struct udevice * dev)1027 void nic_stop(struct udevice *dev)
1028 {
1029 	octeon_eth_halt(dev);
1030 }
1031 
nic_write_hwaddr(struct udevice * dev)1032 int nic_write_hwaddr(struct udevice *dev)
1033 {
1034 	cvm_oct_set_mac_address(dev);
1035 
1036 	return 0;
1037 }
1038 
1039 static const struct eth_ops octeon_nic_ops = {
1040 	.start = nic_open,
1041 	.stop = nic_stop,
1042 	.send = nic_xmit,
1043 	.recv = nic_recv,
1044 	.free_pkt = nic_free_pkt,
1045 	.write_hwaddr = nic_write_hwaddr,
1046 };
1047 
1048 static const struct udevice_id octeon_nic_ids[] = {
1049 	{ .compatible = "cavium,octeon-7890-bgx" },
1050 	{}
1051 };
1052 
1053 U_BOOT_DRIVER(octeon_nic) = {
1054 	.name = "octeon_nic",
1055 	.id = UCLASS_ETH,
1056 	.probe = octeon_nic_probe,
1057 	.of_match = octeon_nic_ids,
1058 	.ops = &octeon_nic_ops,
1059 	.priv_auto = sizeof(struct octeon_eth_info),
1060 };
1061