xref: /openbmc/u-boot/drivers/net/pch_gbe.c (revision 4d93617d)
1 /*
2  * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
3  *
4  * Intel Platform Controller Hub EG20T (codename Topcliff) GMAC Driver
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <errno.h>
11 #include <asm/io.h>
12 #include <pci.h>
13 #include <malloc.h>
14 #include <miiphy.h>
15 #include "pch_gbe.h"
16 
17 #if !defined(CONFIG_PHYLIB)
18 # error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
19 #endif
20 
21 static struct pci_device_id supported[] = {
22 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_GBE },
23 	{ }
24 };
25 
26 static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
27 {
28 	u32 macid_hi, macid_lo;
29 
30 	macid_hi = readl(&mac_regs->mac_adr[0].high);
31 	macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
32 	debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);
33 
34 	addr[0] = (u8)(macid_hi & 0xff);
35 	addr[1] = (u8)((macid_hi >> 8) & 0xff);
36 	addr[2] = (u8)((macid_hi >> 16) & 0xff);
37 	addr[3] = (u8)((macid_hi >> 24) & 0xff);
38 	addr[4] = (u8)(macid_lo & 0xff);
39 	addr[5] = (u8)((macid_lo >> 8) & 0xff);
40 }
41 
42 static int pch_gbe_mac_write(struct pch_gbe_regs *mac_regs, u8 *addr)
43 {
44 	u32 macid_hi, macid_lo;
45 	ulong start;
46 
47 	macid_hi = addr[0] + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24);
48 	macid_lo = addr[4] + (addr[5] << 8);
49 
50 	writel(macid_hi, &mac_regs->mac_adr[0].high);
51 	writel(macid_lo, &mac_regs->mac_adr[0].low);
52 	writel(0xfffe, &mac_regs->addr_mask);
53 
54 	start = get_timer(0);
55 	while (get_timer(start) < PCH_GBE_TIMEOUT) {
56 		if (!(readl(&mac_regs->addr_mask) & PCH_GBE_BUSY))
57 			return 0;
58 
59 		udelay(10);
60 	}
61 
62 	return -ETIME;
63 }
64 
65 static int pch_gbe_reset(struct eth_device *dev)
66 {
67 	struct pch_gbe_priv *priv = dev->priv;
68 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
69 	ulong start;
70 
71 	priv->rx_idx = 0;
72 	priv->tx_idx = 0;
73 
74 	writel(PCH_GBE_ALL_RST, &mac_regs->reset);
75 
76 	/*
77 	 * Configure the MAC to RGMII mode after reset
78 	 *
79 	 * For some unknown reason, we must do the configuration here right
80 	 * after resetting the whole MAC, otherwise the reset bit in the RESET
81 	 * register will never be cleared by the hardware. And there is another
82 	 * way of having the same magic, that is to configure the MODE register
83 	 * to have the MAC work in MII/GMII mode, which is how current Linux
84 	 * pch_gbe driver does. Since anyway we need program the MAC to RGMII
85 	 * mode in the driver, we just do it here.
86 	 *
87 	 * Note: this behavior is not documented in the hardware manual.
88 	 */
89 	writel(PCH_GBE_RGMII_MODE_RGMII | PCH_GBE_CHIP_TYPE_INTERNAL,
90 	       &mac_regs->rgmii_ctrl);
91 
92 	start = get_timer(0);
93 	while (get_timer(start) < PCH_GBE_TIMEOUT) {
94 		if (!(readl(&mac_regs->reset) & PCH_GBE_ALL_RST)) {
95 			/*
96 			 * Soft reset clears hardware MAC address registers,
97 			 * so we have to reload MAC address here in order to
98 			 * make linux pch_gbe driver happy.
99 			 */
100 			return pch_gbe_mac_write(mac_regs, dev->enetaddr);
101 		}
102 
103 		udelay(10);
104 	}
105 
106 	debug("pch_gbe: reset timeout\n");
107 	return -ETIME;
108 }
109 
110 static void pch_gbe_rx_descs_init(struct eth_device *dev)
111 {
112 	struct pch_gbe_priv *priv = dev->priv;
113 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
114 	struct pch_gbe_rx_desc *rx_desc = &priv->rx_desc[0];
115 	int i;
116 
117 	memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM);
118 	for (i = 0; i < PCH_GBE_DESC_NUM; i++)
119 		rx_desc->buffer_addr = pci_phys_to_mem(priv->bdf,
120 			(u32)(priv->rx_buff[i]));
121 
122 	writel(pci_phys_to_mem(priv->bdf, (u32)rx_desc),
123 	       &mac_regs->rx_dsc_base);
124 	writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1),
125 	       &mac_regs->rx_dsc_size);
126 
127 	writel(pci_phys_to_mem(priv->bdf, (u32)(rx_desc + 1)),
128 	       &mac_regs->rx_dsc_sw_p);
129 }
130 
131 static void pch_gbe_tx_descs_init(struct eth_device *dev)
132 {
133 	struct pch_gbe_priv *priv = dev->priv;
134 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
135 	struct pch_gbe_tx_desc *tx_desc = &priv->tx_desc[0];
136 
137 	memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM);
138 
139 	writel(pci_phys_to_mem(priv->bdf, (u32)tx_desc),
140 	       &mac_regs->tx_dsc_base);
141 	writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1),
142 	       &mac_regs->tx_dsc_size);
143 	writel(pci_phys_to_mem(priv->bdf, (u32)(tx_desc + 1)),
144 	       &mac_regs->tx_dsc_sw_p);
145 }
146 
147 static void pch_gbe_adjust_link(struct pch_gbe_regs *mac_regs,
148 				struct phy_device *phydev)
149 {
150 	if (!phydev->link) {
151 		printf("%s: No link.\n", phydev->dev->name);
152 		return;
153 	}
154 
155 	clrbits_le32(&mac_regs->rgmii_ctrl,
156 		     PCH_GBE_RGMII_RATE_2_5M | PCH_GBE_CRS_SEL);
157 	clrbits_le32(&mac_regs->mode,
158 		     PCH_GBE_MODE_GMII_ETHER | PCH_GBE_MODE_FULL_DUPLEX);
159 
160 	switch (phydev->speed) {
161 	case 1000:
162 		setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_125M);
163 		setbits_le32(&mac_regs->mode, PCH_GBE_MODE_GMII_ETHER);
164 		break;
165 	case 100:
166 		setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_25M);
167 		setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER);
168 		break;
169 	case 10:
170 		setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_2_5M);
171 		setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER);
172 		break;
173 	}
174 
175 	if (phydev->duplex) {
176 		setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_CRS_SEL);
177 		setbits_le32(&mac_regs->mode, PCH_GBE_MODE_FULL_DUPLEX);
178 	}
179 
180 	printf("Speed: %d, %s duplex\n", phydev->speed,
181 	       (phydev->duplex) ? "full" : "half");
182 
183 	return;
184 }
185 
186 static int pch_gbe_init(struct eth_device *dev, bd_t *bis)
187 {
188 	struct pch_gbe_priv *priv = dev->priv;
189 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
190 
191 	if (pch_gbe_reset(dev))
192 		return -1;
193 
194 	pch_gbe_rx_descs_init(dev);
195 	pch_gbe_tx_descs_init(dev);
196 
197 	/* Enable frame bursting */
198 	writel(PCH_GBE_MODE_FR_BST, &mac_regs->mode);
199 	/* Disable TCP/IP accelerator */
200 	writel(PCH_GBE_RX_TCPIPACC_OFF, &mac_regs->tcpip_acc);
201 	/* Disable RX flow control */
202 	writel(0, &mac_regs->rx_fctrl);
203 	/* Configure RX/TX mode */
204 	writel(PCH_GBE_RH_ALM_EMP_16 | PCH_GBE_RH_ALM_FULL_16 |
205 	       PCH_GBE_RH_RD_TRG_32, &mac_regs->rx_mode);
206 	writel(PCH_GBE_TM_TH_TX_STRT_32 | PCH_GBE_TM_TH_ALM_EMP_16 |
207 	       PCH_GBE_TM_TH_ALM_FULL_32 | PCH_GBE_TM_ST_AND_FD |
208 	       PCH_GBE_TM_SHORT_PKT, &mac_regs->tx_mode);
209 
210 	/* Start up the PHY */
211 	if (phy_startup(priv->phydev)) {
212 		printf("Could not initialize PHY %s\n",
213 		       priv->phydev->dev->name);
214 		return -1;
215 	}
216 
217 	pch_gbe_adjust_link(mac_regs, priv->phydev);
218 
219 	if (!priv->phydev->link)
220 		return -1;
221 
222 	/* Enable TX & RX */
223 	writel(PCH_GBE_RX_DMA_EN | PCH_GBE_TX_DMA_EN, &mac_regs->dma_ctrl);
224 	writel(PCH_GBE_MRE_MAC_RX_EN, &mac_regs->mac_rx_en);
225 
226 	return 0;
227 }
228 
229 static void pch_gbe_halt(struct eth_device *dev)
230 {
231 	struct pch_gbe_priv *priv = dev->priv;
232 
233 	pch_gbe_reset(dev);
234 
235 	phy_shutdown(priv->phydev);
236 }
237 
238 static int pch_gbe_send(struct eth_device *dev, void *packet, int length)
239 {
240 	struct pch_gbe_priv *priv = dev->priv;
241 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
242 	struct pch_gbe_tx_desc *tx_head, *tx_desc;
243 	u16 frame_ctrl = 0;
244 	u32 int_st;
245 	ulong start;
246 
247 	tx_head = &priv->tx_desc[0];
248 	tx_desc = &priv->tx_desc[priv->tx_idx];
249 
250 	if (length < 64)
251 		frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
252 
253 	tx_desc->buffer_addr = pci_phys_to_mem(priv->bdf, (u32)packet);
254 	tx_desc->length = length;
255 	tx_desc->tx_words_eob = length + 3;
256 	tx_desc->tx_frame_ctrl = frame_ctrl;
257 	tx_desc->dma_status = 0;
258 	tx_desc->gbec_status = 0;
259 
260 	/* Test the wrap-around condition */
261 	if (++priv->tx_idx >= PCH_GBE_DESC_NUM)
262 		priv->tx_idx = 0;
263 
264 	writel(pci_phys_to_mem(priv->bdf, (u32)(tx_head + priv->tx_idx)),
265 	       &mac_regs->tx_dsc_sw_p);
266 
267 	start = get_timer(0);
268 	while (get_timer(start) < PCH_GBE_TIMEOUT) {
269 		int_st = readl(&mac_regs->int_st);
270 		if (int_st & PCH_GBE_INT_TX_CMPLT)
271 			return 0;
272 
273 		udelay(10);
274 	}
275 
276 	debug("pch_gbe: sent failed\n");
277 	return -ETIME;
278 }
279 
280 static int pch_gbe_recv(struct eth_device *dev)
281 {
282 	struct pch_gbe_priv *priv = dev->priv;
283 	struct pch_gbe_regs *mac_regs = priv->mac_regs;
284 	struct pch_gbe_rx_desc *rx_head, *rx_desc;
285 	u32 hw_desc, buffer_addr, length;
286 	int rx_swp;
287 
288 	rx_head = &priv->rx_desc[0];
289 	rx_desc = &priv->rx_desc[priv->rx_idx];
290 
291 	readl(&mac_regs->int_st);
292 	hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld);
293 
294 	/* Just return if not receiving any packet */
295 	if ((u32)rx_desc == hw_desc)
296 		return 0;
297 
298 	buffer_addr = pci_mem_to_phys(priv->bdf, rx_desc->buffer_addr);
299 	length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN;
300 	NetReceive((uchar *)buffer_addr, length);
301 
302 	/* Test the wrap-around condition */
303 	if (++priv->rx_idx >= PCH_GBE_DESC_NUM)
304 		priv->rx_idx = 0;
305 	rx_swp = priv->rx_idx;
306 	if (++rx_swp >= PCH_GBE_DESC_NUM)
307 		rx_swp = 0;
308 
309 	writel(pci_phys_to_mem(priv->bdf, (u32)(rx_head + rx_swp)),
310 	       &mac_regs->rx_dsc_sw_p);
311 
312 	return length;
313 }
314 
315 static int pch_gbe_mdio_ready(struct pch_gbe_regs *mac_regs)
316 {
317 	ulong start = get_timer(0);
318 
319 	while (get_timer(start) < PCH_GBE_TIMEOUT) {
320 		if (readl(&mac_regs->miim) & PCH_GBE_MIIM_OPER_READY)
321 			return 0;
322 
323 		udelay(10);
324 	}
325 
326 	return -ETIME;
327 }
328 
329 static int pch_gbe_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
330 {
331 	struct pch_gbe_regs *mac_regs = bus->priv;
332 	u32 miim;
333 
334 	if (pch_gbe_mdio_ready(mac_regs))
335 		return -ETIME;
336 
337 	miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) |
338 	       (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) |
339 	       PCH_GBE_MIIM_OPER_READ;
340 	writel(miim, &mac_regs->miim);
341 
342 	if (pch_gbe_mdio_ready(mac_regs))
343 		return -ETIME;
344 
345 	return readl(&mac_regs->miim) & 0xffff;
346 }
347 
348 static int pch_gbe_mdio_write(struct mii_dev *bus, int addr, int devad,
349 			      int reg, u16 val)
350 {
351 	struct pch_gbe_regs *mac_regs = bus->priv;
352 	u32 miim;
353 
354 	if (pch_gbe_mdio_ready(mac_regs))
355 		return -ETIME;
356 
357 	miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) |
358 	       (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) |
359 	       PCH_GBE_MIIM_OPER_WRITE | val;
360 	writel(miim, &mac_regs->miim);
361 
362 	if (pch_gbe_mdio_ready(mac_regs))
363 		return -ETIME;
364 	else
365 		return 0;
366 }
367 
368 static int pch_gbe_mdio_init(char *name, struct pch_gbe_regs *mac_regs)
369 {
370 	struct mii_dev *bus;
371 
372 	bus = mdio_alloc();
373 	if (!bus) {
374 		debug("pch_gbe: failed to allocate MDIO bus\n");
375 		return -ENOMEM;
376 	}
377 
378 	bus->read = pch_gbe_mdio_read;
379 	bus->write = pch_gbe_mdio_write;
380 	sprintf(bus->name, name);
381 
382 	bus->priv = (void *)mac_regs;
383 
384 	return mdio_register(bus);
385 }
386 
387 static int pch_gbe_phy_init(struct eth_device *dev)
388 {
389 	struct pch_gbe_priv *priv = dev->priv;
390 	struct phy_device *phydev;
391 	int mask = 0xffffffff;
392 
393 	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
394 	if (!phydev) {
395 		printf("pch_gbe: cannot find the phy\n");
396 		return -1;
397 	}
398 
399 	phy_connect_dev(phydev, dev);
400 
401 	phydev->supported &= PHY_GBIT_FEATURES;
402 	phydev->advertising = phydev->supported;
403 
404 	priv->phydev = phydev;
405 	phy_config(phydev);
406 
407 	return 1;
408 }
409 
410 int pch_gbe_register(bd_t *bis)
411 {
412 	struct eth_device *dev;
413 	struct pch_gbe_priv *priv;
414 	pci_dev_t devno;
415 	u32 iobase;
416 
417 	devno = pci_find_devices(supported, 0);
418 	if (devno == -1)
419 		return -ENODEV;
420 
421 	dev = (struct eth_device *)malloc(sizeof(*dev));
422 	if (!dev)
423 		return -ENOMEM;
424 	memset(dev, 0, sizeof(*dev));
425 
426 	/*
427 	 * The priv structure contains the descriptors and frame buffers which
428 	 * need a strict buswidth alignment (64 bytes)
429 	 */
430 	priv = (struct pch_gbe_priv *)memalign(PCH_GBE_ALIGN_SIZE,
431 					       sizeof(*priv));
432 	if (!priv) {
433 		free(dev);
434 		return -ENOMEM;
435 	}
436 	memset(priv, 0, sizeof(*priv));
437 
438 	dev->priv = priv;
439 	priv->dev = dev;
440 	priv->bdf = devno;
441 
442 	pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
443 	iobase &= PCI_BASE_ADDRESS_MEM_MASK;
444 	iobase = pci_mem_to_phys(devno, iobase);
445 
446 	dev->iobase = iobase;
447 	priv->mac_regs = (struct pch_gbe_regs *)iobase;
448 
449 	sprintf(dev->name, "pch_gbe.%x", iobase);
450 
451 	/* Read MAC address from SROM and initialize dev->enetaddr with it */
452 	pch_gbe_mac_read(priv->mac_regs, dev->enetaddr);
453 
454 	dev->init = pch_gbe_init;
455 	dev->halt = pch_gbe_halt;
456 	dev->send = pch_gbe_send;
457 	dev->recv = pch_gbe_recv;
458 
459 	eth_register(dev);
460 
461 	priv->interface = PHY_INTERFACE_MODE_RGMII;
462 	pch_gbe_mdio_init(dev->name, priv->mac_regs);
463 	priv->bus = miiphy_get_dev_by_name(dev->name);
464 
465 	return pch_gbe_phy_init(dev);
466 }
467