1/* -*- linux-c -*- */
2/*
3 * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 **/
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <linux/stddef.h>
16#include <linux/string.h>
17#include <linux/sockios.h>
18#include <asm/io.h>
19#include <asm/byteorder.h>
20#include <asm/pgtable.h>
21#include <linux/skbuff.h>
22#include <linux/if_arp.h>
23#include <linux/fs.h>
24#include <linux/sched.h>
25#include <asm/uaccess.h>
26#include <linux/version.h>
27#include <linux/etherdevice.h>
28#include "Reg9050.h"
29#include "8253xctl.h"
30#include "ring.h"
31#include "8253x.h"
32#include "crc32dcl.h"
33
34				/* turns network packet into a pseudoethernet */
35				/* frame -- does ethernet stuff that 8253x does */
36				/* not do -- makes minimum  64 bytes add crc, etc*/
37int
38sab8253xn_write2(struct sk_buff *skb, struct net_device *dev)
39{
40	size_t cnt;
41	unsigned int flags;
42	SAB_PORT *priv = (SAB_PORT*) dev->priv;
43	struct sk_buff *substitute;
44
45#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
46	if(dev->tbusy != 0)		/* something of an error */
47	{
48		++(priv->Counters.tx_drops);
49		dev_kfree_skb_any(skb);
50		return -EBUSY;		/* only during release */
51	}
52#endif
53
54	if(priv->active2.transmit == NULL)
55	{
56		return -ENOMEM;
57	}
58
59	DEBUGPRINT((KERN_ALERT "sab8253x: sending IP packet(bytes):\n"));
60
61	DEBUGPRINT((KERN_ALERT "sab8253x: start address is %p.\n", skb->data));
62
63	cnt = skb->tail - skb->data;
64	cnt = MIN(cnt, sab8253xn_rbufsize);
65	if(cnt < ETH_ZLEN)
66	{
67		if((skb->end - skb->data) >= ETH_ZLEN)
68		{
69			skb->tail = (skb->data + ETH_ZLEN);
70			cnt = ETH_ZLEN;
71		}
72		else
73		{
74			substitute = dev_alloc_skb(ETH_ZLEN);
75			if(substitute == NULL)
76			{
77				dev_kfree_skb_any(skb);
78				return 0;
79			}
80			substitute->tail = (substitute->data + ETH_ZLEN);
81			memcpy(substitute->data, skb->data, cnt);
82			cnt = ETH_ZLEN;
83			dev_kfree_skb_any(skb);
84			skb = substitute;
85		}
86	}
87
88	save_flags(flags); cli();
89	if((priv->active2.transmit->Count & OWNER) == OWN_SAB)
90	{
91		++(priv->Counters.tx_drops);
92#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
93		dev->tbusy = 1;
94#else
95		netif_stop_queue (dev);
96#endif
97		priv->tx_full = 1;
98		restore_flags(flags);
99		return 1;
100	}
101	restore_flags(flags);
102#ifndef FREEINTERRUPT
103	if(priv->active2.transmit->HostVaddr != NULL)
104	{
105		register RING_DESCRIPTOR *freeme;
106
107		freeme = priv->active2.transmit;
108		do
109		{
110			skb_unlink((struct sk_buff*)freeme->HostVaddr);
111			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
112			freeme->HostVaddr = NULL;
113			freeme = (RING_DESCRIPTOR*) freeme->VNext;
114		}
115		while(((freeme->Count & OWNER) != OWN_SAB) &&
116		      (freeme->HostVaddr != NULL));
117	}
118#endif
119	dev->trans_start = jiffies;
120	skb_queue_head(priv->sab8253xbuflist, skb);
121	priv->active2.transmit->HostVaddr = skb;
122	priv->active2.transmit->sendcrc = 1;
123	priv->active2.transmit->crcindex = 0;
124	priv->active2.transmit->crc = fn_calc_memory_crc32(skb->data, cnt);
125	priv->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */
126	priv->active2.transmit =
127		(RING_DESCRIPTOR*) priv->active2.transmit->VNext;
128	priv->Counters.transmitbytes += cnt;
129	sab8253x_start_txS(priv);
130	return 0;
131}
132
133	/* packetizes the received character */
134	/* stream */
135static void sab8253x_receive_charsN(struct sab_port *port,
136				    union sab8253x_irq_status *stat)
137{
138	unsigned char buf[32];
139	int free_fifo = 0;
140	int reset_fifo = 0;
141	int msg_done = 0;
142	int msg_bad = 0;
143	int count = 0;
144	int total_size = 0;
145	int rstatus = 0;
146	struct sk_buff *skb;
147
148	/* Read number of BYTES (Character + Status) available. */
149
150	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
151	{
152		++msg_bad;
153		++free_fifo;
154		++reset_fifo;
155	}
156	else
157	{
158		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF)
159		{
160			count = port->recv_fifo_size;
161			++free_fifo;
162		}
163
164		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME)
165		{
166			count = READB(port,rbcl);
167			count &= (port->recv_fifo_size - 1);
168			++msg_done;
169			++free_fifo;
170
171			total_size = READB(port, rbch);
172			if(total_size & SAB82532_RBCH_OV)
173			{
174				msg_bad++;
175			}
176
177			rstatus = READB(port, rsta);
178			if((rstatus & SAB82532_RSTA_VFR) == 0)
179			{
180				msg_bad++;
181			}
182			if(rstatus & SAB82532_RSTA_RDO)
183			{
184				msg_bad++;
185			}
186			if((rstatus & SAB82532_RSTA_CRC) == 0)
187			{
188				msg_bad++;
189			}
190			if(rstatus & SAB82532_RSTA_RAB)
191			{
192				msg_bad++;
193			}
194		}
195	}
196
197	/* Read the FIFO. */
198	(*port->readfifo)(port, buf, count);
199
200	/* Issue Receive Message Complete command. */
201
202	if (free_fifo)
203	{
204		sab8253x_cec_wait(port);
205		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
206	}
207
208	if(reset_fifo)
209	{
210		sab8253x_cec_wait(port);
211		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
212	}
213
214	if(port->active2.receive == NULL)
215	{
216		return;
217	}
218
219	if(msg_bad)
220	{
221		++(port->Counters.rx_drops);
222		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
223		port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
224		return;
225	}
226
227	memcpy(port->active2.receive->HostVaddr->tail, buf, count);
228	port->active2.receive->HostVaddr->tail += count;
229
230	if(msg_done)
231	{
232		port->active2.receive->Count =
233			(port->active2.receive->HostVaddr->tail - port->active2.receive->HostVaddr->data);
234		if((port->active2.receive->Count < (ETH_ZLEN+4+3)) || /* 4 is the CRC32 size 3 bytes from the SAB part */
235		   (skb = dev_alloc_skb(sab8253xn_rbufsize), skb == NULL))
236		{
237			++(port->Counters.rx_drops);
238			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data;
239				/* clear the buffer */
240			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
241		}
242		else
243		{
244			port->active2.receive->Count -= 3;
245			port->active2.receive->HostVaddr->len = port->active2.receive->Count;
246			port->active2.receive->HostVaddr->pkt_type = PACKET_HOST;
247			port->active2.receive->HostVaddr->dev = port->dev;
248			port->active2.receive->HostVaddr->protocol =
249				eth_type_trans(port->active2.receive->HostVaddr, port->dev);
250			port->active2.receive->HostVaddr->tail -= 3;
251			++(port->Counters.receivepacket);
252			port->Counters.receivebytes += port->active2.receive->Count;
253			skb_unlink(port->active2.receive->HostVaddr);
254
255			netif_rx(port->active2.receive->HostVaddr);
256
257			skb_queue_head(port->sab8253xbuflist, skb);
258			port->active2.receive->HostVaddr = skb;
259			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
260		}
261	}
262}
263
264static void sab8253x_check_statusN(struct sab_port *port,
265				   union sab8253x_irq_status *stat)
266{
267	int modem_change = 0;
268	mctlsig_t         *sig;
269
270
271	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO)
272	{
273		port->icount.buf_overrun++;
274	}
275
276	/* Checking DCD */
277	sig = &port->dcd;
278	if (stat->images[sig->irq] & sig->irqmask)
279	{
280		sig->val = ISON(port,dcd);
281		port->icount.dcd++;
282		modem_change++;
283	}
284	/* Checking CTS */
285	sig = &port->cts;
286	if (stat->images[sig->irq] & sig->irqmask)
287	{
288		sig->val = ISON(port,cts);
289		port->icount.cts++;
290		modem_change++;
291	}
292	/* Checking DSR */
293	sig = &port->dsr;
294	if (stat->images[sig->irq] & sig->irqmask)
295	{
296		sig->val = ISON(port,dsr);
297		port->icount.dsr++;
298		modem_change++;
299	}
300	if (modem_change)
301	{
302		wake_up_interruptible(&port->delta_msr_wait);
303	}
304
305	sig = &port->dcd;
306	if ((port->flags & FLAG8253X_CHECK_CD) &&
307	    (stat->images[sig->irq] & sig->irqmask))
308	{
309
310		if (sig->val)
311		{
312			netif_carrier_on(port->dev);
313		}
314		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
315			   (port->flags & FLAG8253X_CALLOUT_NOHUP)))
316		{
317			netif_carrier_off(port->dev);
318		}
319	}
320}
321
322static void Sab8253xCollectStats(struct net_device *dev)
323{
324
325	struct net_device_stats *statsp =
326		&((SAB_PORT*) dev->priv)->stats;
327
328	memset(statsp, 0, sizeof(struct net_device_stats));
329
330	statsp->rx_packets +=
331		((SAB_PORT*)dev->priv)->Counters.receivepacket;
332	statsp->tx_packets +=
333		((SAB_PORT*)dev->priv)->Counters.transmitpacket;
334	statsp->tx_dropped +=
335		((SAB_PORT*)dev->priv)->Counters.tx_drops;
336	statsp->rx_dropped +=
337		((SAB_PORT*)dev->priv)->Counters.rx_drops;
338}
339
340struct net_device_stats *sab8253xn_stats(struct net_device *dev)
341{
342	SAB_PORT *priv = (SAB_PORT*) dev->priv;
343
344	Sab8253xCollectStats(dev);
345	return &priv->stats;
346}
347
348/* minimal ioctls -- more to be added later */
349int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
350{
351
352	SAB_PORT *priv = (SAB_PORT*) dev->priv;
353
354	switch(cmd)
355	{
356	case SAB8253XCLEARCOUNTERS:
357		memset(&priv->Counters, 0, sizeof(struct counters));
358		break;
359
360	default:
361		break;
362	}
363	return 0;
364}
365
366
367int sab8253x_startupN(struct sab_port *port)
368{
369	unsigned long flags;
370	int retval = 0;
371
372	save_flags(flags); cli();
373
374	if (port->flags & FLAG8253X_INITIALIZED)
375	{
376		goto errout;
377	}
378
379	if (!port->regs)
380	{
381		retval = -ENODEV;
382		goto errout;
383	}
384	/*
385	 * Initialize the Hardware
386	 */
387	sab8253x_init_lineS(port);	/* nothing in this function
388					 * refers to tty structure */
389
390	/* Activate RTS */
391	RAISE(port,rts);
392	/* Activate DTR */
393	RAISE(port,dtr);
394	/*
395	 * Initialize the modem signals values
396	 */
397	port->dcd.val=ISON(port,dcd);
398	port->cts.val=ISON(port,cts);
399	port->dsr.val=ISON(port,dsr);
400	/*
401	 * Finally, enable interrupts
402	 */
403
404	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
405		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
406	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */
407
408	WRITEB(port,imr0,port->interrupt_mask0);
409	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
410		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
411	WRITEB(port, imr1, port->interrupt_mask1);
412	port->all_sent = 1;
413
414
415	/*
416	 * and set the speed of the serial port
417	 */
418	sab8253x_change_speedN(port);
419
420	port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */
421	port->receive_chars = sab8253x_receive_charsN;
422	port->transmit_chars = sab8253x_transmit_charsS;
423	port->check_status = sab8253x_check_statusN;
424	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
425	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
426			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
427	port->check_status_test = (SAB82532_ISR1_CSC);
428
429	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/
430
431	restore_flags(flags);
432	return 0;
433
434 errout:
435	restore_flags(flags);
436	return retval;
437}
438
439int sab8253xn_open(struct net_device *dev)
440{
441	unsigned int retval;
442	SAB_PORT *priv = (SAB_PORT*) dev->priv;
443
444	if(priv->function != FUNCTION_NR)
445	{
446		return -ENODEV;		/* only allowed if there are no restrictions on the port */
447	}
448
449
450	if(priv->flags & FLAG8253X_CLOSING) /* try again after the TTY close finishes */
451	{
452#ifdef SERIAL_DO_RESTART
453		return ((priv->flags & FLAG8253X_HUP_NOTIFY) ?
454			-EAGAIN : -ERESTARTSYS); /* The ifconfig UP will just fail */
455#else
456		return -EAGAIN;
457#endif
458	}
459
460	/*
461	 * Maybe start up serial port -- may already be running a TTY
462	 */
463	if(priv->flags & FLAG8253X_NORMAL_ACTIVE) /* probably should be a test open at all */
464	{
465		return -EBUSY;	/* can't reopen in NET */
466	}
467
468	if(Sab8253xSetUpLists(priv))
469	{
470		return -ENODEV;
471	}
472
473	if(Sab8253xInitDescriptors2(priv, sab8253xn_listsize, sab8253xn_rbufsize))
474	{
475		Sab8253xCleanUpTransceiveN(priv);
476		return -ENODEV;
477	}
478	netif_carrier_off(dev);
479
480	priv->open_type = OPEN_SYNC_NET;
481	priv->tty = 0;
482
483	retval = sab8253x_startupN(priv);
484	if (retval)
485	{
486		Sab8253xCleanUpTransceiveN(priv);
487		return retval;
488	}
489
490	priv->flags |= FLAG8253X_NETWORK; /* flag the call out driver that it has to reinitialize the port */
491	priv->tx_full = 0;
492#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
493	dev->start = 1;
494	dev->tbusy = 0;
495#else
496	netif_start_queue(dev);
497#endif
498
499	priv->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */
500	MOD_INC_USE_COUNT;
501	return 0;			/* success */
502}
503/* stop the PPC, free all skbuffers */
504int sab8253xn_release(struct net_device *dev)	/* stop */
505{
506	SAB_PORT *priv = (SAB_PORT*) dev->priv;
507	unsigned long flags;
508
509	printk(KERN_ALERT "sab8253xn: network interface going down.\n");
510	save_flags(flags); cli();
511
512#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
513	dev->start = 0;
514	dev->tbusy = 1;
515#else
516	netif_stop_queue (dev);
517#endif
518
519	sab8253x_shutdownN(priv);
520	Sab8253xCleanUpTransceiveN(priv);
521	netif_carrier_off(dev);
522	priv->flags &= ~FLAG8253X_NETWORK;
523	priv->flags &= ~(FLAG8253X_NORMAL_ACTIVE|/*FLAG8253X_CALLOUT_ACTIVE|*/
524			 FLAG8253X_CLOSING);
525	priv->open_type = OPEN_NOT;
526	MOD_DEC_USE_COUNT;
527	restore_flags(flags);
528	return 0;
529}
530
531SAB_PORT *current_sab_port = NULL;
532
533int sab8253xn_init(struct net_device *dev)
534{
535
536	SAB_PORT *priv;
537
538	printk(KERN_ALERT "sab8253xn: initializing SAB8253X network driver instance.\n");
539
540	priv = current_sab_port;
541	dev->priv = priv;
542
543	if(dev->priv == NULL)
544	{
545		printk(KERN_ALERT "sab8253xn: could not find active port!\n");
546		return -ENOMEM;
547	}
548	priv->dev = dev;
549
550	ether_setup(dev);
551
552	dev->irq = priv->irq;
553	dev->hard_start_xmit = sab8253xn_write2;
554	dev->do_ioctl = sab8253xn_ioctl;
555	dev->open = sab8253xn_open;
556	dev->stop = sab8253xn_release;
557	dev->get_stats = sab8253xn_stats;
558	dev->base_addr = (unsigned) priv->regs;
559	/* should I do a request region here */
560	priv->next_dev = Sab8253xRoot;
561	Sab8253xRoot = dev;
562	return 0;
563}
564
565