Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  Support for ColdFire CPU based boards using a NS8390 Ethernet device.
  4 *
  5 *  Derived from the many other 8390 drivers.
  6 *
  7 *  (C) Copyright 2012,  Greg Ungerer <gerg@uclinux.org>
  8 *
  9 */
 10
 11#include <linux/module.h>
 12#include <linux/kernel.h>
 13#include <linux/errno.h>
 14#include <linux/platform_device.h>
 15#include <linux/netdevice.h>
 16#include <linux/etherdevice.h>
 17#include <linux/jiffies.h>
 18#include <linux/io.h>
 19#include <asm/mcf8390.h>
 20
 21static const char version[] =
 22	"mcf8390.c: (15-06-2012) Greg Ungerer <gerg@uclinux.org>";
 23
 24#define NE_CMD		0x00
 25#define NE_DATAPORT	0x10	/* NatSemi-defined port window offset */
 26#define NE_RESET	0x1f	/* Issue a read to reset ,a write to clear */
 27#define NE_EN0_ISR	0x07
 28#define NE_EN0_DCFG	0x0e
 29#define NE_EN0_RSARLO	0x08
 30#define NE_EN0_RSARHI	0x09
 31#define NE_EN0_RCNTLO	0x0a
 32#define NE_EN0_RXCR	0x0c
 33#define NE_EN0_TXCR	0x0d
 34#define NE_EN0_RCNTHI	0x0b
 35#define NE_EN0_IMR	0x0f
 36
 37#define NESM_START_PG	0x40	/* First page of TX buffer */
 38#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
 39
 40#ifdef NE2000_ODDOFFSET
 41/*
 42 * A lot of the ColdFire boards use a separate address region for odd offset
 43 * register addresses. The following functions convert and map as required.
 44 * Note that the data port accesses are treated a little differently, and
 45 * always accessed via the insX/outsX functions.
 46 */
 47static inline u32 NE_PTR(u32 addr)
 48{
 49	if (addr & 1)
 50		return addr - 1 + NE2000_ODDOFFSET;
 51	return addr;
 52}
 53
 54static inline u32 NE_DATA_PTR(u32 addr)
 55{
 56	return addr;
 57}
 58
 59void ei_outb(u32 val, u32 addr)
 60{
 61	NE2000_BYTE *rp;
 62
 63	rp = (NE2000_BYTE *) NE_PTR(addr);
 64	*rp = RSWAP(val);
 65}
 66
 67#define	ei_inb	ei_inb
 68u8 ei_inb(u32 addr)
 69{
 70	NE2000_BYTE *rp, val;
 71
 72	rp = (NE2000_BYTE *) NE_PTR(addr);
 73	val = *rp;
 74	return (u8) (RSWAP(val) & 0xff);
 75}
 76
 77void ei_insb(u32 addr, void *vbuf, int len)
 78{
 79	NE2000_BYTE *rp, val;
 80	u8 *buf;
 81
 82	buf = (u8 *) vbuf;
 83	rp = (NE2000_BYTE *) NE_DATA_PTR(addr);
 84	for (; (len > 0); len--) {
 85		val = *rp;
 86		*buf++ = RSWAP(val);
 87	}
 88}
 89
 90void ei_insw(u32 addr, void *vbuf, int len)
 91{
 92	volatile u16 *rp;
 93	u16 w, *buf;
 94
 95	buf = (u16 *) vbuf;
 96	rp = (volatile u16 *) NE_DATA_PTR(addr);
 97	for (; (len > 0); len--) {
 98		w = *rp;
 99		*buf++ = BSWAP(w);
100	}
101}
102
103void ei_outsb(u32 addr, const void *vbuf, int len)
104{
105	NE2000_BYTE *rp, val;
106	u8 *buf;
107
108	buf = (u8 *) vbuf;
109	rp = (NE2000_BYTE *) NE_DATA_PTR(addr);
110	for (; (len > 0); len--) {
111		val = *buf++;
112		*rp = RSWAP(val);
113	}
114}
115
116void ei_outsw(u32 addr, const void *vbuf, int len)
117{
118	volatile u16 *rp;
119	u16 w, *buf;
120
121	buf = (u16 *) vbuf;
122	rp = (volatile u16 *) NE_DATA_PTR(addr);
123	for (; (len > 0); len--) {
124		w = *buf++;
125		*rp = BSWAP(w);
126	}
127}
128
129#else /* !NE2000_ODDOFFSET */
130
131#define	ei_inb		inb
132#define	ei_outb		outb
133#define	ei_insb		insb
134#define	ei_insw		insw
135#define	ei_outsb	outsb
136#define	ei_outsw	outsw
137
138#endif /* !NE2000_ODDOFFSET */
139
140#define	ei_inb_p	ei_inb
141#define	ei_outb_p	ei_outb
142
143#include "lib8390.c"
144
145/*
146 * Hard reset the card. This used to pause for the same period that a
147 * 8390 reset command required, but that shouldn't be necessary.
148 */
149static void mcf8390_reset_8390(struct net_device *dev)
150{
151	unsigned long reset_start_time = jiffies;
152	u32 addr = dev->base_addr;
153	struct ei_device *ei_local = netdev_priv(dev);
154
155	netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
156
157	ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
158
159	ei_status.txing = 0;
160	ei_status.dmaing = 0;
161
162	/* This check _should_not_ be necessary, omit eventually. */
163	while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RESET) == 0) {
164		if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
165			netdev_warn(dev, "%s: did not complete\n", __func__);
166			break;
167		}
168	}
169
170	ei_outb(ENISR_RESET, addr + NE_EN0_ISR);
171}
172
173/*
174 * This *shouldn't* happen.
175 * If it does, it's the last thing you'll see
176 */
177static void mcf8390_dmaing_err(const char *func, struct net_device *dev,
178			       struct ei_device *ei_local)
179{
180	netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
181		func, ei_local->dmaing, ei_local->irqlock);
182}
183
184/*
185 * Grab the 8390 specific header. Similar to the block_input routine, but
186 * we don't need to be concerned with ring wrap as the header will be at
187 * the start of a page, so we optimize accordingly.
188 */
189static void mcf8390_get_8390_hdr(struct net_device *dev,
190				 struct e8390_pkt_hdr *hdr, int ring_page)
191{
192	struct ei_device *ei_local = netdev_priv(dev);
193	u32 addr = dev->base_addr;
194
195	if (ei_local->dmaing) {
196		mcf8390_dmaing_err(__func__, dev, ei_local);
197		return;
198	}
199
200	ei_local->dmaing |= 0x01;
201	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD);
202	ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
203	ei_outb(sizeof(struct e8390_pkt_hdr), addr + NE_EN0_RCNTLO);
204	ei_outb(0, addr + NE_EN0_RCNTHI);
205	ei_outb(0, addr + NE_EN0_RSARLO);		/* On page boundary */
206	ei_outb(ring_page, addr + NE_EN0_RSARHI);
207	ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD);
208
209	ei_insw(addr + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr) >> 1);
210
211	outb(ENISR_RDC, addr + NE_EN0_ISR);	/* Ack intr */
212	ei_local->dmaing &= ~0x01;
213
214	hdr->count = cpu_to_le16(hdr->count);
215}
216
217/*
218 * Block input and output, similar to the Crynwr packet driver.
219 * If you are porting to a new ethercard, look at the packet driver source
220 * for hints. The NEx000 doesn't share the on-board packet memory --
221 * you have to put the packet out through the "remote DMA" dataport
222 * using z_writeb.
223 */
224static void mcf8390_block_input(struct net_device *dev, int count,
225				struct sk_buff *skb, int ring_offset)
226{
227	struct ei_device *ei_local = netdev_priv(dev);
228	u32 addr = dev->base_addr;
229	char *buf = skb->data;
230
231	if (ei_local->dmaing) {
232		mcf8390_dmaing_err(__func__, dev, ei_local);
233		return;
234	}
235
236	ei_local->dmaing |= 0x01;
237	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD);
238	ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
239	ei_outb(count & 0xff, addr + NE_EN0_RCNTLO);
240	ei_outb(count >> 8, addr + NE_EN0_RCNTHI);
241	ei_outb(ring_offset & 0xff, addr + NE_EN0_RSARLO);
242	ei_outb(ring_offset >> 8, addr + NE_EN0_RSARHI);
243	ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD);
244
245	ei_insw(addr + NE_DATAPORT, buf, count >> 1);
246	if (count & 1)
247		buf[count - 1] = ei_inb(addr + NE_DATAPORT);
248
249	ei_outb(ENISR_RDC, addr + NE_EN0_ISR);	/* Ack intr */
250	ei_local->dmaing &= ~0x01;
251}
252
253static void mcf8390_block_output(struct net_device *dev, int count,
254				 const unsigned char *buf,
255				 const int start_page)
256{
257	struct ei_device *ei_local = netdev_priv(dev);
258	u32 addr = dev->base_addr;
259	unsigned long dma_start;
260
261	/* Make sure we transfer all bytes if 16bit IO writes */
262	if (count & 0x1)
263		count++;
264
265	if (ei_local->dmaing) {
266		mcf8390_dmaing_err(__func__, dev, ei_local);
267		return;
268	}
269
270	ei_local->dmaing |= 0x01;
271	/* We should already be in page 0, but to be safe... */
272	ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, addr + NE_CMD);
273
274	ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
275
276	/* Now the normal output. */
277	ei_outb(count & 0xff, addr + NE_EN0_RCNTLO);
278	ei_outb(count >> 8, addr + NE_EN0_RCNTHI);
279	ei_outb(0x00, addr + NE_EN0_RSARLO);
280	ei_outb(start_page, addr + NE_EN0_RSARHI);
281	ei_outb(E8390_RWRITE + E8390_START, addr + NE_CMD);
282
283	ei_outsw(addr + NE_DATAPORT, buf, count >> 1);
284
285	dma_start = jiffies;
286	while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RDC) == 0) {
287		if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */
288			netdev_warn(dev, "timeout waiting for Tx RDC\n");
289			mcf8390_reset_8390(dev);
290			__NS8390_init(dev, 1);
291			break;
292		}
293	}
294
295	ei_outb(ENISR_RDC, addr + NE_EN0_ISR);	/* Ack intr */
296	ei_local->dmaing &= ~0x01;
297}
298
299static const struct net_device_ops mcf8390_netdev_ops = {
300	.ndo_open		= __ei_open,
301	.ndo_stop		= __ei_close,
302	.ndo_start_xmit		= __ei_start_xmit,
303	.ndo_tx_timeout		= __ei_tx_timeout,
304	.ndo_get_stats		= __ei_get_stats,
305	.ndo_set_rx_mode	= __ei_set_multicast_list,
306	.ndo_validate_addr	= eth_validate_addr,
307	.ndo_set_mac_address	= eth_mac_addr,
308#ifdef CONFIG_NET_POLL_CONTROLLER
309	.ndo_poll_controller	= __ei_poll,
310#endif
311};
312
313static int mcf8390_init(struct net_device *dev)
314{
315	static u32 offsets[] = {
316		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
317		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
318	};
319	struct ei_device *ei_local = netdev_priv(dev);
320	unsigned char SA_prom[32];
321	u32 addr = dev->base_addr;
322	int start_page, stop_page;
323	int i, ret;
324
325	mcf8390_reset_8390(dev);
326
327	/*
328	 * Read the 16 bytes of station address PROM.
329	 * We must first initialize registers,
330	 * similar to NS8390_init(eifdev, 0).
331	 * We can't reliably read the SAPROM address without this.
332	 * (I learned the hard way!).
333	 */
334	{
335		static const struct {
336			u32 value;
337			u32 offset;
338		} program_seq[] = {
339			{E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD},
340						/* Select page 0 */
341			{0x48,	NE_EN0_DCFG},	/* 0x48: Set byte-wide access */
342			{0x00,	NE_EN0_RCNTLO},	/* Clear the count regs */
343			{0x00,	NE_EN0_RCNTHI},
344			{0x00,	NE_EN0_IMR},	/* Mask completion irq */
345			{0xFF,	NE_EN0_ISR},
346			{E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
347			{E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */
348			{32,	NE_EN0_RCNTLO},
349			{0x00,	NE_EN0_RCNTHI},
350			{0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000 */
351			{0x00,	NE_EN0_RSARHI},
352			{E8390_RREAD + E8390_START, NE_CMD},
353		};
354		for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
355			ei_outb(program_seq[i].value,
356				 addr + program_seq[i].offset);
357		}
358	}
359
360	for (i = 0; i < 16; i++) {
361		SA_prom[i] = ei_inb(addr + NE_DATAPORT);
362		ei_inb(addr + NE_DATAPORT);
363	}
364
365	/* We must set the 8390 for word mode. */
366	ei_outb(0x49, addr + NE_EN0_DCFG);
367	start_page = NESM_START_PG;
368	stop_page = NESM_STOP_PG;
369
370	/* Install the Interrupt handler */
371	ret = request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev);
372	if (ret)
373		return ret;
374
375	eth_hw_addr_set(dev, SA_prom);
376
377	netdev_dbg(dev, "Found ethernet address: %pM\n", dev->dev_addr);
378
379	ei_local->name = "mcf8390";
380	ei_local->tx_start_page = start_page;
381	ei_local->stop_page = stop_page;
382	ei_local->word16 = 1;
383	ei_local->rx_start_page = start_page + TX_PAGES;
384	ei_local->reset_8390 = mcf8390_reset_8390;
385	ei_local->block_input = mcf8390_block_input;
386	ei_local->block_output = mcf8390_block_output;
387	ei_local->get_8390_hdr = mcf8390_get_8390_hdr;
388	ei_local->reg_offset = offsets;
389
390	dev->netdev_ops = &mcf8390_netdev_ops;
391	__NS8390_init(dev, 0);
392	ret = register_netdev(dev);
393	if (ret) {
394		free_irq(dev->irq, dev);
395		return ret;
396	}
397
398	netdev_info(dev, "addr=0x%08x irq=%d, Ethernet Address %pM\n",
399		addr, dev->irq, dev->dev_addr);
400	return 0;
401}
402
403static int mcf8390_probe(struct platform_device *pdev)
404{
405	struct net_device *dev;
406	struct resource *mem;
407	resource_size_t msize;
408	int ret, irq;
409
410	irq = platform_get_irq(pdev, 0);
411	if (irq < 0)
412		return -ENXIO;
413
414	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
415	if (mem == NULL) {
416		dev_err(&pdev->dev, "no memory address specified?\n");
417		return -ENXIO;
418	}
419	msize = resource_size(mem);
420	if (!request_mem_region(mem->start, msize, pdev->name))
421		return -EBUSY;
422
423	dev = ____alloc_ei_netdev(0);
424	if (dev == NULL) {
425		release_mem_region(mem->start, msize);
426		return -ENOMEM;
427	}
428
429	SET_NETDEV_DEV(dev, &pdev->dev);
430	platform_set_drvdata(pdev, dev);
431
432	dev->irq = irq;
433	dev->base_addr = mem->start;
434
435	ret = mcf8390_init(dev);
436	if (ret) {
437		release_mem_region(mem->start, msize);
438		free_netdev(dev);
439		return ret;
440	}
441	return 0;
442}
443
444static void mcf8390_remove(struct platform_device *pdev)
445{
446	struct net_device *dev = platform_get_drvdata(pdev);
447	struct resource *mem;
448
449	unregister_netdev(dev);
450	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
451	release_mem_region(mem->start, resource_size(mem));
452	free_netdev(dev);
453}
454
455static struct platform_driver mcf8390_drv = {
456	.driver = {
457		.name	= "mcf8390",
458	},
459	.probe		= mcf8390_probe,
460	.remove_new	= mcf8390_remove,
461};
462
463module_platform_driver(mcf8390_drv);
464
465MODULE_DESCRIPTION("MCF8390 ColdFire NS8390 driver");
466MODULE_AUTHOR("Greg Ungerer <gerg@uclinux.org>");
467MODULE_LICENSE("GPL");
468MODULE_ALIAS("platform:mcf8390");