1/******************************************************************************
2 *
3 * Name:    skge.c
4 * Project:	GEnesis, PCI Gigabit Ethernet Adapter
5 * Version:	$Revision: 1.1.1.1 $
6 * Date:       	$Date: 2008/10/15 03:26:44 $
7 * Purpose:	The main driver source module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 *	(C)Copyright 1998-2001 SysKonnect GmbH.
14 *
15 *	Driver for SysKonnect Gigabit Ethernet Server Adapters:
16 *
17 *	SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
18 *	SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
19 *	SK-9841 (single link 1000Base-LX)
20 *	SK-9842 (dual link   1000Base-LX)
21 *	SK-9843 (single link 1000Base-SX)
22 *	SK-9844 (dual link   1000Base-SX)
23 *	SK-9821 (single link 1000Base-T)
24 *	SK-9822 (dual link   1000Base-T)
25 *
26 *	Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
27 *	SysKonnects GEnesis Solaris driver
28 *	Author: Christoph Goos (cgoos@syskonnect.de)
29 *	        Mirko Lindner (mlindner@syskonnect.de)
30 *
31 *	Address all question to: linux@syskonnect.de
32 *
33 *	The technical manual for the adapters is available from SysKonnect's
34 *	web pages: www.syskonnect.com
35 *	Goto "Support" and search Knowledge Base for "manual".
36 *
37 *	This program is free software; you can redistribute it and/or modify
38 *	it under the terms of the GNU General Public License as published by
39 *	the Free Software Foundation; either version 2 of the License, or
40 *	(at your option) any later version.
41 *
42 *	The information in this file is provided "AS IS" without warranty.
43 *
44 ******************************************************************************/
45
46/******************************************************************************
47 *
48 * History:
49 *
50 *	$Log: skge.c,v $
51 *	Revision 1.1.1.1  2008/10/15 03:26:44  james26_jang
52 *	Initial.
53 *
54 *	Revision 1.1.1.1  2008/07/21 09:15:07  james26_jang
55 *	New UI, New QoS, New wireless driver(4.151.10.29), ipmonitor.
56 *
57 *	Revision 1.1  2008/07/17 12:42:44  james26_jang
58 *	*** empty log message ***
59 *
60 *	Revision 1.1.1.1  2007/02/15 12:11:35  jiahao
61 *	initial update
62 *
63 *	Revision 1.1.1.1  2007/01/25 12:51:56  jiahao_jhou
64 *
65 *
66 *	Revision 1.1.1.1  2003/02/03 22:37:48  mhuang
67 *	LINUX_2_4 branch snapshot from linux-mips.org CVS
68 *
69 *	Revision 1.29.2.6  2001/05/21 07:59:29  mlindner
70 *	fix: MTU init problems
71 *
72 *	Revision 1.29.2.5  2001/05/08 11:25:08  mlindner
73 *	fix: removed VLAN error message
74 *
75 *	Revision 1.29.2.4  2001/05/04 13:31:43  gklug
76 *	fix: do not handle eth_copy on bad fragments received.
77 *
78 *	Revision 1.29.2.3  2001/04/23 08:06:43  mlindner
79 *	Fix: error handling
80 *
81 *	Revision 1.29.2.2  2001/03/15 12:04:54  mlindner
82 *	Fixed memory problem
83 *
84 *	Revision 1.29.2.1  2001/03/12 16:41:44  mlindner
85 *	add: procfs function
86 *	add: dual-net function
87 *	add: RLMT networks
88 *	add: extended PNMI features
89 *
90 *	Kernel 2.4.x specific:
91 *	Revision 1.xx  2000/09/12 13:31:56  cgoos
92 *	Fixed missign "dev=NULL in skge_probe.
93 *	Added counting for jumbo frames (corrects error statistic).
94 *	Removed VLAN tag check (enables VLAN support).
95 *
96 *	Kernel 2.2.x specific:
97 *	Revision 1.29  2000/02/21 13:31:56  cgoos
98 *	Fixed "unused" warning for UltraSPARC change.
99 *
100 *	Partially kernel 2.2.x specific:
101 *	Revision 1.28  2000/02/21 10:32:36  cgoos
102 *	Added fixes for UltraSPARC.
103 *	Now printing RlmtMode and PrefPort setting at startup.
104 *	Changed XmitFrame return value.
105 *	Fixed rx checksum calculation for BIG ENDIAN systems.
106 *	Fixed rx jumbo frames counted as ierrors.
107 *
108 *
109 *	Revision 1.27  1999/11/25 09:06:28  cgoos
110 *	Changed base_addr to unsigned long.
111 *
112 *	Revision 1.26  1999/11/22 13:29:16  cgoos
113 *	Changed license header to GPL.
114 *	Changes for inclusion in linux kernel (2.2.13).
115 *	Removed 2.0.x defines.
116 *	Changed SkGeProbe to skge_probe.
117 *	Added checks in SkGeIoctl.
118 *
119 *	Revision 1.25  1999/10/07 14:47:52  cgoos
120 *	Changed 984x to 98xx.
121 *
122 *	Revision 1.24  1999/09/30 07:21:01  cgoos
123 *	Removed SK_RLMT_SLOW_LOOKAHEAD option.
124 *	Giving spanning tree packets also to OS now.
125 *
126 *	Revision 1.23  1999/09/29 07:36:50  cgoos
127 *	Changed assignment for IsBc/IsMc.
128 *
129 *	Revision 1.22  1999/09/28 12:57:09  cgoos
130 *	Added CheckQueue also to Single-Port-ISR.
131 *
132 *	Revision 1.21  1999/09/28 12:42:41  cgoos
133 *	Changed parameter strings for RlmtMode.
134 *
135 *	Revision 1.20  1999/09/28 12:37:57  cgoos
136 *	Added CheckQueue for fast delivery of RLMT frames.
137 *
138 *	Revision 1.19  1999/09/16 07:57:25  cgoos
139 *	Copperfield changes.
140 *
141 *	Revision 1.18  1999/09/03 13:06:30  cgoos
142 *	Fixed RlmtMode=CheckSeg bug: wrong DEV_KFREE_SKB in RLMT_SEND caused
143 *	double allocated skb's.
144 *	FrameStat in ReceiveIrq was accessed via wrong Rxd.
145 *	Queue size for async. standby Tx queue was zero.
146 *	FillRxLimit of 0 could cause problems with ReQueue, changed to 1.
147 *	Removed debug output of checksum statistic.
148 *
149 *	Revision 1.17  1999/08/11 13:55:27  cgoos
150 *	Transmit descriptor polling was not reenabled after SkGePortInit.
151 *
152 *	Revision 1.16  1999/07/27 15:17:29  cgoos
153 *	Added some "\n" in output strings (removed while debuging...).
154 *
155 *	Revision 1.15  1999/07/23 12:09:30  cgoos
156 *	Performance optimization, rx checksumming, large frame support.
157 *
158 *	Revision 1.14  1999/07/14 11:26:27  cgoos
159 *	Removed Link LED settings (now in RLMT).
160 *	Added status output at NET UP.
161 *	Fixed SMP problems with Tx and SWITCH running in parallel.
162 *	Fixed return code problem at RLMT_SEND event.
163 *
164 *	Revision 1.13  1999/04/07 10:11:42  cgoos
165 *	Fixed Single Port problems.
166 *	Fixed Multi-Adapter problems.
167 *	Always display startup string.
168 *
169 *	Revision 1.12  1999/03/29 12:26:37  cgoos
170 *	Reversed locking to fine granularity.
171 *	Fixed skb double alloc problem (caused by incorrect xmit return code).
172 *	Enhanced function descriptions.
173 *
174 *	Revision 1.11  1999/03/15 13:10:51  cgoos
175 *	Changed device identifier in output string to ethX.
176 *
177 *	Revision 1.10  1999/03/15 12:12:34  cgoos
178 *	Changed copyright notice.
179 *
180 *	Revision 1.9  1999/03/15 12:10:17  cgoos
181 *	Changed locking to one driver lock.
182 *	Added check of SK_AC-size (for consistency with library).
183 *
184 *	Revision 1.8  1999/03/08 11:44:02  cgoos
185 *	Fixed missing dev->tbusy in SkGeXmit.
186 *	Changed large frame (jumbo) buffer number.
187 *	Added copying of short frames.
188 *
189 *	Revision 1.7  1999/03/04 13:26:57  cgoos
190 *	Fixed spinlock calls for SMP.
191 *
192 *	Revision 1.6  1999/03/02 09:53:51  cgoos
193 *	Added descriptor revertion for big endian machines.
194 *
195 *	Revision 1.5  1999/03/01 08:50:59  cgoos
196 *	Fixed SkGeChangeMtu.
197 *	Fixed pci config space accesses.
198 *
199 *	Revision 1.4  1999/02/18 15:48:44  cgoos
200 *	Corrected some printk's.
201 *
202 *	Revision 1.3  1999/02/18 12:45:55  cgoos
203 *	Changed SK_MAX_CARD_PARAM to default 16
204 *
205 *	Revision 1.2  1999/02/18 10:55:32  cgoos
206 *	Removed SkGeDrvTimeStamp function.
207 *	Printing "ethX:" before adapter type at adapter init.
208 *
209 *
210 *	10-Feb-1999 cg	Created, based on Linux' acenic.c, 3c59x.c and
211 *			SysKonnects GEnesis Solaris driver
212 *
213 ******************************************************************************/
214
215
216/******************************************************************************
217 *
218 * Description:
219 *
220 *	This is the main module of the Linux GE driver.
221 *
222 *	All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
223 *	are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
224 *	Those are used for drivers on multiple OS', so some thing may seem
225 *	unnecessary complicated on Linux. Please do not try to 'clean up'
226 *	them without VERY good reasons, because this will make it more
227 *	difficult to keep the Linux driver in synchronisation with the
228 *	other versions.
229 *
230 * Include file hierarchy:
231 *
232 *	<linux/module.h>
233 *
234 *	"h/skdrv1st.h"
235 *		<linux/version.h>
236 *		<linux/types.h>
237 *		<linux/kernel.h>
238 *		<linux/string.h>
239 *		<linux/errno.h>
240 *		<linux/ioport.h>
241 *		<linux/slab.h>
242 *		<linux/interrupt.h>
243 *		<linux/pci.h>
244 *		<asm/byteorder.h>
245 *		<asm/bitops.h>
246 *		<asm/io.h>
247 *		<linux/netdevice.h>
248 *		<linux/etherdevice.h>
249 *		<linux/skbuff.h>
250 *	    those three depending on kernel version used:
251 *		<linux/bios32.h>
252 *		<linux/init.h>
253 *		<asm/uaccess.h>
254 *		<net/checksum.h>
255 *
256 *		"h/skerror.h"
257 *		"h/skdebug.h"
258 *		"h/sktypes.h"
259 *		"h/lm80.h"
260 *		"h/xmac_ii.h"
261 *
262 *      "h/skdrv2nd.h"
263 *		"h/skqueue.h"
264 *		"h/skgehwt.h"
265 *		"h/sktimer.h"
266 *		"h/ski2c.h"
267 *		"h/skgepnmi.h"
268 *		"h/skvpd.h"
269 *		"h/skgehw.h"
270 *		"h/skgeinit.h"
271 *		"h/skaddr.h"
272 *		"h/skgesirq.h"
273 *		"h/skcsum.h"
274 *		"h/skrlmt.h"
275 *
276 ******************************************************************************/
277
278#include	"h/skversion.h"
279
280#include	<linux/module.h>
281#include	<linux/init.h>
282#include 	<linux/proc_fs.h>
283
284#include	"h/skdrv1st.h"
285#include	"h/skdrv2nd.h"
286
287/* defines ******************************************************************/
288/* for debuging on x86 only */
289/* #define BREAKPOINT() asm(" int $3"); */
290
291/* use of a transmit complete interrupt */
292#define USE_TX_COMPLETE
293
294/* use interrupt moderation (for tx complete only) */
295// #define USE_INT_MOD
296#define INTS_PER_SEC	1000
297
298/*
299 * threshold for copying small receive frames
300 * set to 0 to avoid copying, set to 9001 to copy all frames
301 */
302#define SK_COPY_THRESHOLD	200
303
304/* number of adapters that can be configured via command line params */
305#define SK_MAX_CARD_PARAM	16
306
307/*
308 * use those defines for a compile-in version of the driver instead
309 * of command line parameters
310 */
311// #define AUTO_NEG_A	{"Sense", }
312// #define AUTO_NEG_B	{"Sense", }
313// #define DUP_CAP_A	{"Both", }
314// #define DUP_CAP_B	{"Both", }
315// #define FLOW_CTRL_A	{"SymOrRem", }
316// #define FLOW_CTRL_B	{"SymOrRem", }
317// #define ROLE_A	{"Auto", }
318// #define ROLE_B	{"Auto", }
319// #define PREF_PORT	{"A", }
320// #define RLMT_MODE	{"CheckLinkState", }
321
322#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
323#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
324#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
325
326/* function prototypes ******************************************************/
327static void	FreeResources(struct net_device *dev);
328int		init_module(void);
329void		cleanup_module(void);
330static int	SkGeBoardInit(struct net_device *dev, SK_AC *pAC);
331static SK_BOOL	BoardAllocMem(SK_AC *pAC);
332static void	BoardFreeMem(SK_AC *pAC);
333static void	BoardInitMem(SK_AC *pAC);
334static void	SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**,
335			int*, SK_BOOL);
336
337static void	SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
338static void	SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
339static int	SkGeOpen(struct net_device *dev);
340static int	SkGeClose(struct net_device *dev);
341static int	SkGeXmit(struct sk_buff *skb, struct net_device *dev);
342static int	SkGeSetMacAddr(struct net_device *dev, void *p);
343static void	SkGeSetRxMode(struct net_device *dev);
344static struct net_device_stats *SkGeStats(struct net_device *dev);
345static int	SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd);
346static void	GetConfiguration(SK_AC*);
347static void	ProductStr(SK_AC*);
348static int	XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
349static void	FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
350static void	FillRxRing(SK_AC*, RX_PORT*);
351static SK_BOOL	FillRxDescriptor(SK_AC*, RX_PORT*);
352static void	ReceiveIrq(SK_AC*, RX_PORT*);
353static void	ClearAndStartRx(SK_AC*, int);
354static void	ClearTxIrq(SK_AC*, int, int);
355static void	ClearRxRing(SK_AC*, RX_PORT*);
356static void	ClearTxRing(SK_AC*, TX_PORT*);
357static void	SetQueueSizes(SK_AC	*pAC);
358static int	SkGeChangeMtu(struct net_device *dev, int new_mtu);
359static void	PortReInitBmu(SK_AC*, int);
360static int	SkGeIocMib(DEV_NET*, unsigned int, int);
361
362
363/*Extern */
364
365extern struct proc_dir_entry *pSkRootDir;
366
367//extern struct proc_dir_entry Our_Proc_Dir;
368extern int proc_read(char *buffer, char **buffer_location,
369	off_t offset, int buffer_length, int *eof, void *data);
370
371
372#ifdef DEBUG
373static void	DumpMsg(struct sk_buff*, char*);
374static void	DumpData(char*, int);
375static void	DumpLong(char*, int);
376#endif
377
378
379/* global variables *********************************************************/
380static const char *BootString = BOOT_STRING;
381struct net_device *sk98lin_root_dev = NULL;
382static int probed __initdata = 0;
383struct inode_operations SkInodeOps;
384//static struct file_operations SkFileOps;  /* with open/relase */
385
386/* local variables **********************************************************/
387static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
388static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
389
390
391
392void proc_fill_inode(struct inode *inode, int fill)
393{
394	if (fill)
395		MOD_INC_USE_COUNT;
396	else
397		MOD_DEC_USE_COUNT;
398}
399
400
401
402/*****************************************************************************
403 *
404 * 	skge_probe - find all SK-98xx adapters
405 *
406 * Description:
407 *	This function scans the PCI bus for SK-98xx adapters. Resources for
408 *	each adapter are allocated and the adapter is brought into Init 1
409 *	state.
410 *
411 * Returns:
412 *	0, if everything is ok
413 *	!=0, on error
414 */
415static int __init skge_probe (void)
416{
417	int			proc_root_initialized = 0;
418	int 		boards_found = 0;
419	int			version_disp = 0;
420	SK_AC		*pAC;
421	DEV_NET		*pNet = NULL;
422	struct 		pci_dev	*pdev = NULL;
423	unsigned long		base_address;
424	struct net_device *dev = NULL;
425	struct proc_dir_entry	*pProcFile;
426
427	if (probed)
428		return -ENODEV;
429	probed++;
430
431	/* display driver info */
432	if (!version_disp)
433	{
434		/* set display flag to TRUE so that */
435		/* we only display this string ONCE */
436		version_disp = 1;
437		printk("%s\n", BootString);
438	}
439
440	if (!pci_present())		/* is PCI support present? */
441		return -ENODEV;
442
443	while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
444				      PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
445
446		dev = NULL;
447		pNet = NULL;
448
449		if (pci_enable_device(pdev))
450			continue;
451
452		/* Configure DMA attributes. */
453		if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
454		    pci_set_dma_mask(pdev, (u64) 0xffffffff))
455				continue;
456
457		if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) {
458			printk(KERN_ERR "Unable to allocate etherdev "
459			       "structure!\n");
460			break;
461		}
462
463		pNet = dev->priv;
464		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
465		if (pNet->pAC == NULL){
466			kfree(dev->priv);
467			printk(KERN_ERR "Unable to allocate adapter "
468			       "structure!\n");
469			break;
470		}
471
472		memset(pNet->pAC, 0, sizeof(SK_AC));
473		pAC = pNet->pAC;
474		pAC->PciDev = *pdev;
475		pAC->PciDevId = pdev->device;
476		pAC->dev[0] = dev;
477		pAC->dev[1] = dev;
478		sprintf(pAC->Name, "SysKonnect SK-98xx");
479		pAC->CheckQueue = SK_FALSE;
480
481		pNet->Mtu = 1500;
482		pNet->Up = 0;
483		dev->irq = pdev->irq;
484
485		dev->open =		&SkGeOpen;
486		dev->stop =		&SkGeClose;
487		dev->hard_start_xmit =	&SkGeXmit;
488		dev->get_stats =	&SkGeStats;
489		dev->set_multicast_list = &SkGeSetRxMode;
490		dev->set_mac_address =	&SkGeSetMacAddr;
491		dev->do_ioctl =		&SkGeIoctl;
492		dev->change_mtu =	&SkGeChangeMtu;
493
494		if(!proc_root_initialized) {
495			pSkRootDir = create_proc_entry("sk98lin",
496				S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
497			pSkRootDir->owner = THIS_MODULE;
498
499			proc_root_initialized = 1;
500		}
501
502		pProcFile = create_proc_entry(dev->name,
503			S_IFREG | 0444, pSkRootDir);
504		pProcFile->read_proc = proc_read;
505		pProcFile->write_proc = NULL;
506		pProcFile->nlink = 1;
507		pProcFile->size = sizeof(dev->name+1);
508		pProcFile->data = (void*)pProcFile;
509
510		/*
511		 * Dummy value.
512		 */
513		dev->base_addr = 42;
514		pci_set_master(pdev);
515		base_address = pci_resource_start (pdev, 0);
516
517#ifdef SK_BIG_ENDIAN
518		/*
519		 * On big endian machines, we use the adapter's aibility of
520		 * reading the descriptors as big endian.
521		 */
522		{
523		SK_U32		our2;
524			SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
525			our2 |= PCI_REV_DESC;
526			SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
527		}
528#endif /* BIG ENDIAN */
529
530		/*
531		 * Remap the regs into kernel space.
532		 */
533
534		pAC->IoBase = (char*)ioremap(base_address, 0x4000);
535		if (!pAC->IoBase){
536			printk(KERN_ERR "%s:  Unable to map I/O register, "
537			       "SK 98xx No. %i will be disabled.\n",
538			       dev->name, boards_found);
539			kfree(dev);
540			break;
541		}
542		pAC->Index = boards_found;
543
544		if (SkGeBoardInit(dev, pAC)) {
545			FreeResources(dev);
546			kfree(dev);
547			continue;
548		}
549
550		memcpy((caddr_t) &dev->dev_addr,
551			(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
552
553		pNet->PortNr = 0;
554		pNet->NetNr = 0;
555
556		boards_found++;
557
558		/* More then one port found */
559		if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
560			if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
561				printk(KERN_ERR "Unable to allocate etherdev "
562					"structure!\n");
563				break;
564			}
565
566			pAC->dev[1] = dev;
567			pNet = dev->priv;
568			pNet->PortNr = 1;
569			pNet->NetNr = 1;
570			pNet->pAC = pAC;
571			pNet->Mtu = 1500;
572			pNet->Up = 0;
573
574			dev->open =		&SkGeOpen;
575			dev->stop =		&SkGeClose;
576			dev->hard_start_xmit =	&SkGeXmit;
577			dev->get_stats =	&SkGeStats;
578			dev->set_multicast_list = &SkGeSetRxMode;
579			dev->set_mac_address =	&SkGeSetMacAddr;
580			dev->do_ioctl =		&SkGeIoctl;
581			dev->change_mtu =	&SkGeChangeMtu;
582
583			pProcFile = create_proc_entry(dev->name,
584				S_IFREG | 0444, pSkRootDir);
585			pProcFile->read_proc = proc_read;
586			pProcFile->write_proc = NULL;
587			pProcFile->nlink = 1;
588			pProcFile->size = sizeof(dev->name+1);
589			pProcFile->data = (void*)pProcFile;
590
591			memcpy((caddr_t) &dev->dev_addr,
592			(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
593
594			printk("%s: %s\n", dev->name, pAC->DeviceStr);
595			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
596
597		}
598
599
600		/*
601		 * This is bollocks, but we need to tell the net-init
602		 * code that it shall go for the next device.
603		 */
604#ifndef MODULE
605		dev->base_addr = 0;
606#endif
607	}
608
609	/*
610	 * If we're at this point we're going through skge_probe() for
611	 * the first time.  Return success (0) if we've initialized 1
612	 * or more boards. Otherwise, return failure (-ENODEV).
613	 */
614
615	return boards_found;
616} /* skge_probe */
617
618
619/*****************************************************************************
620 *
621 * 	FreeResources - release resources allocated for adapter
622 *
623 * Description:
624 *	This function releases the IRQ, unmaps the IO and
625 *	frees the desriptor ring.
626 *
627 * Returns: N/A
628 *
629 */
630static void FreeResources(struct net_device *dev)
631{
632SK_U32 AllocFlag;
633DEV_NET		*pNet;
634SK_AC		*pAC;
635
636	if (dev->priv) {
637		pNet = (DEV_NET*) dev->priv;
638		pAC = pNet->pAC;
639		AllocFlag = pAC->AllocFlag;
640		if (AllocFlag & SK_ALLOC_IRQ) {
641			free_irq(dev->irq, dev);
642		}
643		if (pAC->IoBase) {
644			iounmap(pAC->IoBase);
645		}
646		if (pAC->pDescrMem) {
647			BoardFreeMem(pAC);
648		}
649	}
650
651} /* FreeResources */
652
653MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>");
654MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
655MODULE_LICENSE("GPL");
656MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
657MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
658MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
659MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
660MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
661MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
662MODULE_PARM(Role_A,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
663MODULE_PARM(Role_B,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
664MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
665MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
666/* not used, just there because every driver should have them: */
667MODULE_PARM(options,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
668MODULE_PARM(debug,      "i");
669
670
671#ifdef AUTO_NEG_A
672static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
673#else
674static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
675#endif
676
677#ifdef DUP_CAP_A
678static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
679#else
680static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
681#endif
682
683#ifdef FLOW_CTRL_A
684static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
685#else
686static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
687#endif
688
689#ifdef ROLE_A
690static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
691#else
692static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
693#endif
694
695#ifdef AUTO_NEG_B
696static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
697#else
698static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
699#endif
700
701#ifdef DUP_CAP_B
702static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
703#else
704static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
705#endif
706
707#ifdef FLOW_CTRL_B
708static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
709#else
710static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
711#endif
712
713#ifdef ROLE_B
714static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
715#else
716static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
717#endif
718
719#ifdef PREF_PORT
720static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
721#else
722static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
723#endif
724
725#ifdef RLMT_MODE
726static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
727#else
728static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
729#endif
730
731
732static int debug = 0; /* not used */
733static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
734
735
736/*****************************************************************************
737 *
738 * 	skge_init_module - module initialization function
739 *
740 * Description:
741 *	Very simple, only call skge_probe and return approriate result.
742 *
743 * Returns:
744 *	0, if everything is ok
745 *	!=0, on error
746 */
747static int __init skge_init_module(void)
748{
749	int cards;
750	sk98lin_root_dev = NULL;
751
752	/* just to avoid warnings ... */
753	debug = 0;
754	options[0] = 0;
755
756	cards = skge_probe();
757	if (cards == 0) {
758		printk("No adapter found\n");
759	}
760	return cards ? 0 : -ENODEV;
761} /* skge_init_module */
762
763
764/*****************************************************************************
765 *
766 * 	skge_cleanup_module - module unload function
767 *
768 * Description:
769 *	Disable adapter if it is still running, free resources,
770 *	free device struct.
771 *
772 * Returns: N/A
773 */
774static void __exit skge_cleanup_module(void)
775{
776DEV_NET		*pNet;
777SK_AC		*pAC;
778struct net_device *next;
779unsigned long Flags;
780SK_EVPARA EvPara;
781
782	while (sk98lin_root_dev) {
783		pNet = (DEV_NET*) sk98lin_root_dev->priv;
784		pAC = pNet->pAC;
785		next = pAC->Next;
786
787		netif_stop_queue(sk98lin_root_dev);
788		SkGeYellowLED(pAC, pAC->IoBase, 0);
789
790		if(pAC->BoardLevel == 2) {
791			/* board is still alive */
792			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
793			EvPara.Para32[0] = 0;
794			EvPara.Para32[1] = -1;
795			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
796			EvPara.Para32[0] = 1;
797			EvPara.Para32[1] = -1;
798			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
799			SkEventDispatcher(pAC, pAC->IoBase);
800			/* disable interrupts */
801			SK_OUT32(pAC->IoBase, B0_IMSK, 0);
802			SkGeDeInit(pAC, pAC->IoBase);
803			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
804			pAC->BoardLevel = 0;
805			/* We do NOT check here, if IRQ was pending, of course*/
806		}
807
808		if(pAC->BoardLevel == 1) {
809			/* board is still alive */
810			SkGeDeInit(pAC, pAC->IoBase);
811			pAC->BoardLevel = 0;
812		}
813
814		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
815			unregister_netdev(pAC->dev[1]);
816			kfree(pAC->dev[1]);
817		}
818
819		FreeResources(sk98lin_root_dev);
820
821		sk98lin_root_dev->get_stats = NULL;
822		/*
823		 * otherwise unregister_netdev calls get_stats with
824		 * invalid IO ...  :-(
825		 */
826		unregister_netdev(sk98lin_root_dev);
827		kfree(sk98lin_root_dev);
828		kfree(pAC);
829		sk98lin_root_dev = next;
830	}
831
832	/* clear proc-dir */
833	remove_proc_entry(pSkRootDir->name, proc_net);
834
835} /* skge_cleanup_module */
836
837module_init(skge_init_module);
838module_exit(skge_cleanup_module);
839
840/*****************************************************************************
841 *
842 * 	SkGeBoardInit - do level 0 and 1 initialization
843 *
844 * Description:
845 *	This function prepares the board hardware for running. The desriptor
846 *	ring is set up, the IRQ is allocated and the configuration settings
847 *	are examined.
848 *
849 * Returns:
850 *	0, if everything is ok
851 *	!=0, on error
852 */
853static int __init SkGeBoardInit(struct net_device *dev, SK_AC *pAC)
854{
855short	i;
856unsigned long Flags;
857char	*DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
858char	*VerStr	= VER_STRING;
859int	Ret;			/* return code of request_irq */
860
861	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
862		("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
863	for (i=0; i<SK_MAX_MACS; i++) {
864		pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
865		pAC->TxPort[i][0].PortIndex = i;
866		pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
867		pAC->RxPort[i].PortIndex = i;
868	}
869
870	/* Initialize the mutexes */
871
872	for (i=0; i<SK_MAX_MACS; i++) {
873		spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
874		spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
875	}
876	spin_lock_init(&pAC->SlowPathLock);
877
878	/* level 0 init common modules here */
879
880	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
881	/* Does a RESET on board ...*/
882	if (SkGeInit(pAC, pAC->IoBase, 0) != 0) {
883		printk("HWInit (0) failed.\n");
884		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
885		return(-EAGAIN);
886	}
887	SkI2cInit(  pAC, pAC->IoBase, 0);
888	SkEventInit(pAC, pAC->IoBase, 0);
889	SkPnmiInit( pAC, pAC->IoBase, 0);
890	SkAddrInit( pAC, pAC->IoBase, 0);
891	SkRlmtInit( pAC, pAC->IoBase, 0);
892	SkTimerInit(pAC, pAC->IoBase, 0);
893
894	pAC->BoardLevel = 0;
895	pAC->RxBufSize = ETH_BUF_SIZE;
896
897	SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
898	SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
899
900	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
901
902	/* level 1 init common modules here (HW init) */
903	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
904	if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
905		printk("HWInit (1) failed.\n");
906		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
907		return(-EAGAIN);
908	}
909	SkI2cInit(  pAC, pAC->IoBase, 1);
910	SkEventInit(pAC, pAC->IoBase, 1);
911	SkPnmiInit( pAC, pAC->IoBase, 1);
912	SkAddrInit( pAC, pAC->IoBase, 1);
913	SkRlmtInit( pAC, pAC->IoBase, 1);
914	SkTimerInit(pAC, pAC->IoBase, 1);
915
916	GetConfiguration(pAC);
917	if (pAC->RlmtNets == 2) {
918		pAC->GIni.GIPortUsage = SK_MUL_LINK;
919	}
920
921
922	pAC->BoardLevel = 1;
923	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
924
925	if (pAC->GIni.GIMacsFound == 2) {
926		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
927	} else if (pAC->GIni.GIMacsFound == 1) {
928		Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
929			pAC->Name, dev);
930	} else {
931		printk(KERN_WARNING "%s: illegal number of ports: %d\n",
932		       dev->name, pAC->GIni.GIMacsFound);
933		return -EAGAIN;
934	}
935	if (Ret) {
936		printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
937		       dev->name, dev->irq);
938		return -EAGAIN;
939	}
940	pAC->AllocFlag |= SK_ALLOC_IRQ;
941
942	/* Alloc memory for this board (Mem for RxD/TxD) : */
943	if(!BoardAllocMem(pAC)) {
944		printk("No memory for descriptor rings\n");
945       		return(-EAGAIN);
946	}
947
948	SkCsSetReceiveFlags(pAC,
949		SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
950		&pAC->CsOfs1, &pAC->CsOfs2, 0);
951	pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
952
953	BoardInitMem(pAC);
954
955	SetQueueSizes(pAC);
956
957	/* Print adapter specific string from vpd */
958	ProductStr(pAC);
959	printk("%s: %s\n", dev->name, pAC->DeviceStr);
960
961	/* Print configuration settings */
962	printk("      PrefPort:%c  RlmtMode:%s\n",
963		'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
964		(pAC->RlmtMode==0)  ? "Check Link State" :
965		((pAC->RlmtMode==1) ? "Check Link State" :
966		((pAC->RlmtMode==3) ? "Check Local Port" :
967		((pAC->RlmtMode==7) ? "Check Segmentation" :
968		((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
969
970
971	SkGeYellowLED(pAC, pAC->IoBase, 1);
972
973	/*
974	 * Register the device here
975	 */
976	pAC->Next = sk98lin_root_dev;
977	sk98lin_root_dev = dev;
978
979	return (0);
980} /* SkGeBoardInit */
981
982
983/*****************************************************************************
984 *
985 * 	BoardAllocMem - allocate the memory for the descriptor rings
986 *
987 * Description:
988 *	This function allocates the memory for all descriptor rings.
989 *	Each ring is aligned for the desriptor alignment and no ring
990 *	has a 4 GByte boundary in it (because the upper 32 bit must
991 *	be constant for all descriptiors in one rings).
992 *
993 * Returns:
994 *	SK_TRUE, if all memory could be allocated
995 *	SK_FALSE, if not
996 */
997static SK_BOOL BoardAllocMem(
998SK_AC	*pAC)
999{
1000caddr_t		pDescrMem;	/* pointer to descriptor memory area */
1001size_t		AllocLength;	/* length of complete descriptor area */
1002int		i;		/* loop counter */
1003unsigned long	BusAddr;
1004
1005
1006	/* rings plus one for alignment (do not cross 4 GB boundary) */
1007	/* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
1008#if BITS_PER_LONG == 32
1009	AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
1010#else
1011	AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
1012		+ RX_RING_SIZE + 8;
1013#endif
1014	pDescrMem = pci_alloc_consistent(&pAC->PciDev, AllocLength,
1015					 &pAC->pDescrMemDMA);
1016	if (pDescrMem == NULL) {
1017		return (SK_FALSE);
1018	}
1019	pAC->pDescrMem = pDescrMem;
1020
1021	/* Descriptors need 8 byte alignment, and this is ensured
1022	 * by pci_alloc_consistent.
1023	 */
1024	BusAddr = (unsigned long) pAC->pDescrMemDMA;
1025	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1026		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
1027			("TX%d/A: pDescrMem: %lX,   PhysDescrMem: %lX\n",
1028			i, (unsigned long) pDescrMem,
1029			BusAddr));
1030		pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
1031		pAC->TxPort[i][0].VTxDescrRing = BusAddr;
1032		pDescrMem += TX_RING_SIZE;
1033		BusAddr += TX_RING_SIZE;
1034
1035		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
1036			("RX%d: pDescrMem: %lX,   PhysDescrMem: %lX\n",
1037			i, (unsigned long) pDescrMem,
1038			(unsigned long)BusAddr));
1039		pAC->RxPort[i].pRxDescrRing = pDescrMem;
1040		pAC->RxPort[i].VRxDescrRing = BusAddr;
1041		pDescrMem += RX_RING_SIZE;
1042		BusAddr += RX_RING_SIZE;
1043	} /* for */
1044
1045	return (SK_TRUE);
1046} /* BoardAllocMem */
1047
1048
1049/****************************************************************************
1050 *
1051 *	BoardFreeMem - reverse of BoardAllocMem
1052 *
1053 * Description:
1054 *	Free all memory allocated in BoardAllocMem: adapter context,
1055 *	descriptor rings, locks.
1056 *
1057 * Returns:	N/A
1058 */
1059static void BoardFreeMem(
1060SK_AC		*pAC)
1061{
1062size_t		AllocLength;	/* length of complete descriptor area */
1063
1064	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1065		("BoardFreeMem\n"));
1066#if BITS_PER_LONG == 32
1067	AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
1068#else
1069	AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
1070		+ RX_RING_SIZE + 8;
1071#endif
1072	pci_free_consistent(&pAC->PciDev, AllocLength,
1073			    pAC->pDescrMem, pAC->pDescrMemDMA);
1074	pAC->pDescrMem = NULL;
1075} /* BoardFreeMem */
1076
1077
1078/*****************************************************************************
1079 *
1080 * 	BoardInitMem - initiate the descriptor rings
1081 *
1082 * Description:
1083 *	This function sets the descriptor rings up in memory.
1084 *	The adapter is initialized with the descriptor start addresses.
1085 *
1086 * Returns:	N/A
1087 */
1088static void BoardInitMem(
1089SK_AC	*pAC)	/* pointer to adapter context */
1090{
1091int	i;		/* loop counter */
1092int	RxDescrSize;	/* the size of a rx descriptor rounded up to alignment*/
1093int	TxDescrSize;	/* the size of a tx descriptor rounded up to alignment*/
1094
1095	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1096		("BoardInitMem\n"));
1097
1098	RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
1099	pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
1100	TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
1101	pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
1102
1103	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1104		SetupRing(
1105			pAC,
1106			pAC->TxPort[i][0].pTxDescrRing,
1107			pAC->TxPort[i][0].VTxDescrRing,
1108			(RXD**)&pAC->TxPort[i][0].pTxdRingHead,
1109			(RXD**)&pAC->TxPort[i][0].pTxdRingTail,
1110			(RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
1111			&pAC->TxPort[i][0].TxdRingFree,
1112			SK_TRUE);
1113		SetupRing(
1114			pAC,
1115			pAC->RxPort[i].pRxDescrRing,
1116			pAC->RxPort[i].VRxDescrRing,
1117			&pAC->RxPort[i].pRxdRingHead,
1118			&pAC->RxPort[i].pRxdRingTail,
1119			&pAC->RxPort[i].pRxdRingPrev,
1120			&pAC->RxPort[i].RxdRingFree,
1121			SK_FALSE);
1122	}
1123} /* BoardInitMem */
1124
1125
1126/*****************************************************************************
1127 *
1128 * 	SetupRing - create one descriptor ring
1129 *
1130 * Description:
1131 *	This function creates one descriptor ring in the given memory area.
1132 *	The head, tail and number of free descriptors in the ring are set.
1133 *
1134 * Returns:
1135 *	none
1136 */
1137static void SetupRing(
1138SK_AC		*pAC,
1139void		*pMemArea,	/* a pointer to the memory area for the ring */
1140uintptr_t	VMemArea,	/* the virtual bus address of the memory area */
1141RXD		**ppRingHead,	/* address where the head should be written */
1142RXD		**ppRingTail,	/* address where the tail should be written */
1143RXD		**ppRingPrev,	/* address where the tail should be written */
1144int		*pRingFree,	/* address where the # of free descr. goes */
1145SK_BOOL		IsTx)		/* flag: is this a tx ring */
1146{
1147int	i;		/* loop counter */
1148int	DescrSize;	/* the size of a descriptor rounded up to alignment*/
1149int	DescrNum;	/* number of descriptors per ring */
1150RXD	*pDescr;	/* pointer to a descriptor (receive or transmit) */
1151RXD	*pNextDescr;	/* pointer to the next descriptor */
1152RXD	*pPrevDescr;	/* pointer to the previous descriptor */
1153uintptr_t VNextDescr;	/* the virtual bus address of the next descriptor */
1154
1155	if (IsTx == SK_TRUE) {
1156		DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
1157			DESCR_ALIGN;
1158		DescrNum = TX_RING_SIZE / DescrSize;
1159	}
1160	else {
1161		DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
1162			DESCR_ALIGN;
1163		DescrNum = RX_RING_SIZE / DescrSize;
1164	}
1165
1166	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
1167		("Descriptor size: %d   Descriptor Number: %d\n",
1168		DescrSize,DescrNum));
1169
1170	pDescr = (RXD*) pMemArea;
1171	pPrevDescr = NULL;
1172	pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
1173	VNextDescr = VMemArea + DescrSize;
1174	for(i=0; i<DescrNum; i++) {
1175		/* set the pointers right */
1176		pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
1177		pDescr->pNextRxd = pNextDescr;
1178		pDescr->TcpSumStarts = pAC->CsOfs;
1179		/* advance on step */
1180		pPrevDescr = pDescr;
1181		pDescr = pNextDescr;
1182		pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
1183		VNextDescr += DescrSize;
1184	}
1185	pPrevDescr->pNextRxd = (RXD*) pMemArea;
1186	pPrevDescr->VNextRxd = VMemArea;
1187	pDescr = (RXD*) pMemArea;
1188	*ppRingHead = (RXD*) pMemArea;
1189	*ppRingTail = *ppRingHead;
1190	*ppRingPrev = pPrevDescr;
1191	*pRingFree = DescrNum;
1192} /* SetupRing */
1193
1194
1195/*****************************************************************************
1196 *
1197 * 	PortReInitBmu - re-initiate the descriptor rings for one port
1198 *
1199 * Description:
1200 *	This function reinitializes the descriptor rings of one port
1201 *	in memory. The port must be stopped before.
1202 *	The HW is initialized with the descriptor start addresses.
1203 *
1204 * Returns:
1205 *	none
1206 */
1207static void PortReInitBmu(
1208SK_AC	*pAC,		/* pointer to adapter context */
1209int	PortIndex)	/* index of the port for which to re-init */
1210{
1211	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1212		("PortReInitBmu "));
1213
1214	/* set address of first descriptor of ring in BMU */
1215	SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
1216		TX_Q_CUR_DESCR_LOW,
1217		(uint32_t)(((caddr_t)
1218		(pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
1219		pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
1220		pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
1221		0xFFFFFFFF));
1222	SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+
1223		TX_Q_DESCR_HIGH,
1224		(uint32_t)(((caddr_t)
1225		(pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
1226		pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
1227		pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
1228	SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CUR_DESCR_LOW,
1229		(uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
1230		pAC->RxPort[PortIndex].pRxDescrRing +
1231		pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
1232	SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_DESCR_HIGH,
1233		(uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
1234		pAC->RxPort[PortIndex].pRxDescrRing +
1235		pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
1236} /* PortReInitBmu */
1237
1238
1239/****************************************************************************
1240 *
1241 *	SkGeIsr - handle adapter interrupts
1242 *
1243 * Description:
1244 *	The interrupt routine is called when the network adapter
1245 *	generates an interrupt. It may also be called if another device
1246 *	shares this interrupt vector with the driver.
1247 *
1248 * Returns: N/A
1249 *
1250 */
1251static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
1252{
1253struct net_device *dev = (struct net_device *)dev_id;
1254
1255DEV_NET		*pNet;
1256SK_AC		*pAC;
1257SK_U32		IntSrc;		/* interrupts source register contents */
1258
1259	pNet = (DEV_NET*) dev->priv;
1260	pAC = pNet->pAC;
1261
1262	/*
1263	 * Check and process if its our interrupt
1264	 */
1265	SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1266	if (IntSrc == 0) {
1267		return;
1268	}
1269
1270	while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1271		if (IntSrc & IRQ_EOF_RX1) {
1272			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1273				SK_DBGCAT_DRV_INT_SRC,
1274				("EOF RX1 IRQ\n"));
1275			ReceiveIrq(pAC, &pAC->RxPort[0]);
1276			SK_PNMI_CNT_RX_INTR(pAC,0);
1277		}
1278		if (IntSrc & IRQ_EOF_RX2) {
1279			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1280				SK_DBGCAT_DRV_INT_SRC,
1281				("EOF RX2 IRQ\n"));
1282			ReceiveIrq(pAC, &pAC->RxPort[1]);
1283			SK_PNMI_CNT_RX_INTR(pAC,1);
1284		}
1285#ifdef USE_TX_COMPLETE     /* only if tx complete interrupt used */
1286		if (IntSrc & IRQ_EOF_AS_TX1) {
1287			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1288				SK_DBGCAT_DRV_INT_SRC,
1289				("EOF AS TX1 IRQ\n"));
1290			SK_PNMI_CNT_TX_INTR(pAC,0);
1291			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1292			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1293			spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1294		}
1295		if (IntSrc & IRQ_EOF_AS_TX2) {
1296			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1297				SK_DBGCAT_DRV_INT_SRC,
1298				("EOF AS TX2 IRQ\n"));
1299			SK_PNMI_CNT_TX_INTR(pAC,1);
1300			spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
1301			FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
1302			spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
1303		}
1304#endif /* USE_TX_COMPLETE */
1305
1306		/* do all IO at once */
1307		if (IntSrc & IRQ_EOF_RX1)
1308			ClearAndStartRx(pAC, 0);
1309		if (IntSrc & IRQ_EOF_RX2)
1310			ClearAndStartRx(pAC, 1);
1311#ifdef USE_TX_COMPLETE     /* only if tx complete interrupt used */
1312		if (IntSrc & IRQ_EOF_AS_TX1)
1313			ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1314		if (IntSrc & IRQ_EOF_AS_TX2)
1315			ClearTxIrq(pAC, 1, TX_PRIO_LOW);
1316#endif
1317		SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1318	} /* while (IntSrc & IRQ_MASK != 0) */
1319
1320	if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1321		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1322			("SPECIAL IRQ\n"));
1323		pAC->CheckQueue = SK_FALSE;
1324		spin_lock(&pAC->SlowPathLock);
1325		if (IntSrc & SPECIAL_IRQS)
1326			SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1327		SkEventDispatcher(pAC, pAC->IoBase);
1328		spin_unlock(&pAC->SlowPathLock);
1329	}
1330	/*
1331	 * do it all again is case we cleared an interrupt that
1332	 * came in after handling the ring (OUTs may be delayed
1333	 * in hardware buffers, but are through after IN)
1334	 */
1335	// ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]);
1336	ReceiveIrq(pAC, &pAC->RxPort[0]);
1337	ReceiveIrq(pAC, &pAC->RxPort[1]);
1338
1339
1340
1341
1342
1343	/* IRQ is processed - Enable IRQs again*/
1344	SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
1345
1346	return;
1347} /* SkGeIsr */
1348
1349
1350/****************************************************************************
1351 *
1352 *	SkGeIsrOnePort - handle adapter interrupts for single port adapter
1353 *
1354 * Description:
1355 *	The interrupt routine is called when the network adapter
1356 *	generates an interrupt. It may also be called if another device
1357 *	shares this interrupt vector with the driver.
1358 *	This is the same as above, but handles only one port.
1359 *
1360 * Returns: N/A
1361 *
1362 */
1363static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
1364{
1365struct net_device *dev = (struct net_device *)dev_id;
1366DEV_NET		*pNet;
1367SK_AC		*pAC;
1368SK_U32		IntSrc;		/* interrupts source register contents */
1369
1370	pNet = (DEV_NET*) dev->priv;
1371	pAC = pNet->pAC;
1372
1373	/*
1374	 * Check and process if its our interrupt
1375	 */
1376	SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1377	if (IntSrc == 0) {
1378		return;
1379	}
1380
1381	while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1382		if (IntSrc & IRQ_EOF_RX1) {
1383			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1384				SK_DBGCAT_DRV_INT_SRC,
1385				("EOF RX1 IRQ\n"));
1386			ReceiveIrq(pAC, &pAC->RxPort[0]);
1387			SK_PNMI_CNT_RX_INTR(pAC,0);
1388		}
1389#ifdef USE_TX_COMPLETE     /* only if tx complete interrupt used */
1390		if (IntSrc & IRQ_EOF_AS_TX1) {
1391			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1392				SK_DBGCAT_DRV_INT_SRC,
1393				("EOF AS TX1 IRQ\n"));
1394			SK_PNMI_CNT_TX_INTR(pAC,0);
1395			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1396			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1397			spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1398		}
1399#endif /* USE_TX_COMPLETE */
1400
1401		/* do all IO at once */
1402		if (IntSrc & IRQ_EOF_RX1)
1403			ClearAndStartRx(pAC, 0);
1404#ifdef USE_TX_COMPLETE     /* only if tx complete interrupt used */
1405		if (IntSrc & IRQ_EOF_AS_TX1)
1406			ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1407#endif
1408		SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1409	} /* while (IntSrc & IRQ_MASK != 0) */
1410
1411	if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1412		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1413			("SPECIAL IRQ\n"));
1414		pAC->CheckQueue = SK_FALSE;
1415		spin_lock(&pAC->SlowPathLock);
1416		if (IntSrc & SPECIAL_IRQS)
1417			SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1418		SkEventDispatcher(pAC, pAC->IoBase);
1419		spin_unlock(&pAC->SlowPathLock);
1420	}
1421	/*
1422	 * do it all again is case we cleared an interrupt that
1423	 * came in after handling the ring (OUTs may be delayed
1424	 * in hardware buffers, but are through after IN)
1425	 */
1426	ReceiveIrq(pAC, &pAC->RxPort[0]);
1427
1428
1429	/* IRQ is processed - Enable IRQs again*/
1430	SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
1431
1432	return;
1433} /* SkGeIsrOnePort */
1434
1435
1436/****************************************************************************
1437 *
1438 *	SkGeOpen - handle start of initialized adapter
1439 *
1440 * Description:
1441 *	This function starts the initialized adapter.
1442 *	The board level variable is set and the adapter is
1443 *	brought to full functionality.
1444 *	The device flags are set for operation.
1445 *	Do all necessary level 2 initialization, enable interrupts and
1446 *	give start command to RLMT.
1447 *
1448 * Returns:
1449 *	0 on success
1450 *	!= 0 on error
1451 */
1452static int SkGeOpen(
1453struct net_device	*dev)
1454{
1455DEV_NET			*pNet;
1456SK_AC			*pAC;
1457unsigned long	Flags;		/* for spin lock */
1458int		i;
1459SK_EVPARA		EvPara;		/* an event parameter union */
1460
1461	pNet = (DEV_NET*) dev->priv;
1462	pAC = pNet->pAC;
1463
1464	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1465		("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
1466
1467	if (pAC->BoardLevel == 0) {
1468		/* level 1 init common modules here */
1469		if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
1470			printk("%s: HWInit(1) failed\n", pAC->dev[pNet->PortNr]->name);
1471			return (-1);
1472		}
1473		SkI2cInit	(pAC, pAC->IoBase, 1);
1474		SkEventInit	(pAC, pAC->IoBase, 1);
1475		SkPnmiInit	(pAC, pAC->IoBase, 1);
1476		SkAddrInit	(pAC, pAC->IoBase, 1);
1477		SkRlmtInit	(pAC, pAC->IoBase, 1);
1478		SkTimerInit	(pAC, pAC->IoBase, 1);
1479		pAC->BoardLevel = 1;
1480	}
1481
1482	if (pAC->BoardLevel != 2) {
1483		/* level 2 init modules here */
1484		SkGeInit	(pAC, pAC->IoBase, 2);
1485		SkI2cInit	(pAC, pAC->IoBase, 2);
1486		SkEventInit	(pAC, pAC->IoBase, 2);
1487		SkPnmiInit	(pAC, pAC->IoBase, 2);
1488		SkAddrInit	(pAC, pAC->IoBase, 2);
1489		SkRlmtInit	(pAC, pAC->IoBase, 2);
1490		SkTimerInit	(pAC, pAC->IoBase, 2);
1491		pAC->BoardLevel = 2;
1492	}
1493	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1494		/* Enable transmit descriptor polling. */
1495		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
1496		FillRxRing(pAC, &pAC->RxPort[i]);
1497	}
1498	SkGeYellowLED(pAC, pAC->IoBase, 1);
1499
1500#ifdef USE_INT_MOD
1501/* moderate only TX complete interrupts (these are not time critical) */
1502#define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2)
1503	{
1504		unsigned long ModBase;
1505		ModBase = 53125000 / INTS_PER_SEC;
1506		SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
1507		SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
1508		SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
1509	}
1510#endif
1511
1512	/* enable Interrupts */
1513	SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
1514	SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
1515
1516	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1517
1518	if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
1519		EvPara.Para32[0] = pAC->RlmtNets;
1520		EvPara.Para32[1] = -1;
1521		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
1522			EvPara);
1523		EvPara.Para32[0] = pAC->RlmtMode;
1524		EvPara.Para32[1] = 0;
1525		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
1526			EvPara);
1527	}
1528
1529	EvPara.Para32[0] = pNet->NetNr;
1530	EvPara.Para32[1] = -1;
1531	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
1532	SkEventDispatcher(pAC, pAC->IoBase);
1533	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1534
1535	pAC->MaxPorts++;
1536	pNet->Up = 1;
1537
1538	MOD_INC_USE_COUNT;
1539
1540	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1541		("SkGeOpen suceeded\n"));
1542
1543	return (0);
1544} /* SkGeOpen */
1545
1546
1547/****************************************************************************
1548 *
1549 *	SkGeClose - Stop initialized adapter
1550 *
1551 * Description:
1552 *	Close initialized adapter.
1553 *
1554 * Returns:
1555 *	0 - on success
1556 *	error code - on error
1557 */
1558static int SkGeClose(
1559struct net_device	*dev)
1560{
1561DEV_NET		*pNet;
1562SK_AC		*pAC;
1563
1564unsigned long	Flags;		/* for spin lock */
1565int				i;
1566int				PortIdx;
1567SK_EVPARA		EvPara;
1568
1569	netif_stop_queue(dev);
1570
1571	pNet = (DEV_NET*) dev->priv;
1572	pAC = pNet->pAC;
1573
1574	if (pAC->RlmtNets == 1)
1575		PortIdx = pAC->ActivePort;
1576	else
1577		PortIdx = pNet->NetNr;
1578
1579	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1580		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
1581
1582	/*
1583	 * Clear multicast table, promiscuous mode ....
1584	 */
1585
1586	SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
1587	SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
1588		SK_PROM_MODE_NONE);
1589
1590	if (pAC->MaxPorts == 1) {
1591		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1592		/* disable interrupts */
1593		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1594		EvPara.Para32[0] = pNet->NetNr;
1595		EvPara.Para32[1] = -1;
1596		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1597		SkEventDispatcher(pAC, pAC->IoBase);
1598		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1599		/* stop the hardware */
1600		SkGeDeInit(pAC, pAC->IoBase);
1601		pAC->BoardLevel = 0;
1602		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1603	} else {
1604
1605		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1606		EvPara.Para32[0] = pNet->NetNr;
1607		EvPara.Para32[1] = -1;
1608		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1609		SkEventDispatcher(pAC, pAC->IoBase);
1610		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1611
1612		/* Stop port */
1613		spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
1614			[TX_PRIO_LOW].TxDesRingLock, Flags);
1615		SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
1616			SK_STOP_ALL, SK_HARD_RST);
1617		spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
1618			[TX_PRIO_LOW].TxDesRingLock, Flags);
1619	}
1620	if (pAC->RlmtNets == 1) {
1621		/* clear all descriptor rings */
1622		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1623			ReceiveIrq(pAC, &pAC->RxPort[i]);
1624			ClearRxRing(pAC, &pAC->RxPort[i]);
1625			ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
1626		}
1627	} else {
1628		/* clear port descriptor rings */
1629		ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr]);
1630		ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
1631		ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
1632	}
1633
1634	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1635		("SkGeClose: done "));
1636
1637	pAC->MaxPorts--;
1638	pNet->Up = 0;
1639	MOD_DEC_USE_COUNT;
1640
1641	return (0);
1642} /* SkGeClose */
1643
1644/*****************************************************************************
1645 *
1646 * 	SkGeXmit - Linux frame transmit function
1647 *
1648 * Description:
1649 *	The system calls this function to send frames onto the wire.
1650 *	It puts the frame in the tx descriptor ring. If the ring is
1651 *	full then, the 'tbusy' flag is set.
1652 *
1653 * Returns:
1654 *	0, if everything is ok
1655 *	!=0, on error
1656 * WARNING: returning 1 in 'tbusy' case caused system crashes (double
1657 *	allocated skb's) !!!
1658 */
1659static int SkGeXmit(struct sk_buff *skb, struct net_device *dev)
1660{
1661DEV_NET		*pNet;
1662SK_AC		*pAC;
1663int			Rc;	/* return code of XmitFrame */
1664
1665	pNet = (DEV_NET*) dev->priv;
1666	pAC = pNet->pAC;
1667
1668	if (pAC->RlmtNets == 2)
1669		Rc = XmitFrame(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], skb);
1670	else
1671		Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb);
1672
1673	/* Transmitter out of resources? */
1674	if (Rc <= 0)
1675		netif_stop_queue(dev);
1676
1677	/* If not taken, give buffer ownership back to the
1678	 * queueing layer.
1679	 */
1680	if (Rc < 0)
1681		return (1);
1682
1683	dev->trans_start = jiffies;
1684	return (0);
1685} /* SkGeXmit */
1686
1687
1688/*****************************************************************************
1689 *
1690 * 	XmitFrame - fill one socket buffer into the transmit ring
1691 *
1692 * Description:
1693 *	This function puts a message into the transmit descriptor ring
1694 *	if there is a descriptors left.
1695 *	Linux skb's consist of only one continuous buffer.
1696 *	The first step locks the ring. It is held locked
1697 *	all time to avoid problems with SWITCH_../PORT_RESET.
1698 *	Then the descriptoris allocated.
1699 *	The second part is linking the buffer to the descriptor.
1700 *	At the very last, the Control field of the descriptor
1701 *	is made valid for the BMU and a start TX command is given
1702 *	if necessary.
1703 *
1704 * Returns:
1705 *  > 0 - on succes: the number of bytes in the message
1706 *  = 0 - on resource shortage: this frame sent or dropped, now
1707 *        the ring is full ( -> set tbusy)
1708 *  < 0 - on failure: other problems ( -> return failure to upper layers)
1709 */
1710static int XmitFrame(
1711SK_AC 		*pAC,		/* pointer to adapter context */
1712TX_PORT		*pTxPort,	/* pointer to struct of port to send to */
1713struct sk_buff	*pMessage)	/* pointer to send-message */
1714{
1715TXD		*pTxd;		/* the rxd to fill */
1716unsigned long	Flags;
1717SK_U64		PhysAddr;
1718int		BytesSend;
1719
1720	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
1721		("X"));
1722
1723	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1724
1725	if (pTxPort->TxdRingFree == 0) {
1726		/* no enough free descriptors in ring at the moment */
1727		FreeTxDescriptors(pAC, pTxPort);
1728		if (pTxPort->TxdRingFree == 0) {
1729			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1730			SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1731			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1732				SK_DBGCAT_DRV_TX_PROGRESS,
1733				("XmitFrame failed\n"));
1734			/* this message can not be sent now */
1735			return (-1);
1736		}
1737	}
1738	/* advance head counter behind descriptor needed for this frame */
1739	pTxd = pTxPort->pTxdRingHead;
1740	pTxPort->pTxdRingHead = pTxd->pNextTxd;
1741	pTxPort->TxdRingFree--;
1742	/* the needed descriptor is reserved now */
1743
1744	/*
1745	 * everything allocated ok, so add buffer to descriptor
1746	 */
1747
1748#ifdef SK_DUMP_TX
1749	DumpMsg(pMessage, "XmitFrame");
1750#endif
1751
1752	/* set up descriptor and CONTROL dword */
1753	PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev,
1754					 virt_to_page(pMessage->data),
1755					 ((unsigned long) pMessage->data &
1756					  ~PAGE_MASK),
1757					 pMessage->len,
1758					 PCI_DMA_TODEVICE);
1759	pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);
1760	pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1761	pTxd->pMBuf = pMessage;
1762	pTxd->TBControl = TX_CTRL_OWN_BMU | TX_CTRL_STF |
1763		TX_CTRL_CHECK_DEFAULT | TX_CTRL_SOFTWARE |
1764#ifdef USE_TX_COMPLETE
1765		TX_CTRL_EOF | TX_CTRL_EOF_IRQ | pMessage->len;
1766#else
1767		TX_CTRL_EOF | pMessage->len;
1768#endif
1769
1770	if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {
1771		/* previous descriptor already done, so give tx start cmd */
1772		/* StartTx(pAC, pTxPort->HwAddr); */
1773		SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);
1774	}
1775	pTxPort->pTxdRingPrev = pTxd;
1776
1777
1778	BytesSend = pMessage->len;
1779	/* after releasing the lock, the skb may be immidiately freed */
1780	if (pTxPort->TxdRingFree != 0) {
1781		spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1782		return (BytesSend);
1783	}
1784	else {
1785		/* ring full: set tbusy on return */
1786		spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1787		return (0);
1788	}
1789} /* XmitFrame */
1790
1791
1792/*****************************************************************************
1793 *
1794 * 	FreeTxDescriptors - release descriptors from the descriptor ring
1795 *
1796 * Description:
1797 *	This function releases descriptors from a transmit ring if they
1798 *	have been sent by the BMU.
1799 *	If a descriptors is sent, it can be freed and the message can
1800 *	be freed, too.
1801 *	The SOFTWARE controllable bit is used to prevent running around a
1802 *	completely free ring for ever. If this bit is no set in the
1803 *	frame (by XmitFrame), this frame has never been sent or is
1804 *	already freed.
1805 *	The Tx descriptor ring lock must be held while calling this function !!!
1806 *
1807 * Returns:
1808 *	none
1809 */
1810static void FreeTxDescriptors(
1811SK_AC	*pAC,		/* pointer to the adapter context */
1812TX_PORT	*pTxPort)	/* pointer to destination port structure */
1813{
1814TXD	*pTxd;		/* pointer to the checked descriptor */
1815TXD	*pNewTail;	/* pointer to 'end' of the ring */
1816SK_U32	Control;	/* TBControl field of descriptor */
1817SK_U64	PhysAddr;	/* address of DMA mapping */
1818
1819	pNewTail = pTxPort->pTxdRingTail;
1820	pTxd = pNewTail;
1821
1822	/*
1823	 * loop forever; exits if TX_CTRL_SOFTWARE bit not set in start frame
1824	 * or TX_CTRL_OWN_BMU bit set in any frame
1825	 */
1826	while (1) {
1827		Control = pTxd->TBControl;
1828		if ((Control & TX_CTRL_SOFTWARE) == 0) {
1829			/*
1830			 * software controllable bit is set in first
1831			 * fragment when given to BMU. Not set means that
1832			 * this fragment was never sent or is already
1833			 * freed ( -> ring completely free now).
1834			 */
1835			pTxPort->pTxdRingTail = pTxd;
1836			netif_start_queue(pAC->dev[pTxPort->PortIndex]);
1837			return;
1838		}
1839		if (Control & TX_CTRL_OWN_BMU) {
1840			pTxPort->pTxdRingTail = pTxd;
1841			if (pTxPort->TxdRingFree > 0) {
1842				netif_start_queue(pAC->dev[pTxPort->PortIndex]);
1843			}
1844			return;
1845		}
1846
1847		/* release the DMA mapping */
1848		PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
1849		PhysAddr |= (SK_U64) pTxd->VDataLow;
1850		pci_unmap_page(&pAC->PciDev, PhysAddr,
1851			       pTxd->pMBuf->len,
1852			       PCI_DMA_TODEVICE);
1853
1854		/* free message */
1855		DEV_KFREE_SKB_ANY(pTxd->pMBuf);
1856		pTxPort->TxdRingFree++;
1857		pTxd->TBControl &= ~TX_CTRL_SOFTWARE;
1858		pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
1859	} /* while(forever) */
1860} /* FreeTxDescriptors */
1861
1862
1863/*****************************************************************************
1864 *
1865 * 	FillRxRing - fill the receive ring with valid descriptors
1866 *
1867 * Description:
1868 *	This function fills the receive ring descriptors with data
1869 *	segments and makes them valid for the BMU.
1870 *	The active ring is filled completely, if possible.
1871 *	The non-active ring is filled only partial to save memory.
1872 *
1873 * Description of rx ring structure:
1874 *	head - points to the descriptor which will be used next by the BMU
1875 *	tail - points to the next descriptor to give to the BMU
1876 *
1877 * Returns:	N/A
1878 */
1879static void FillRxRing(
1880SK_AC		*pAC,		/* pointer to the adapter context */
1881RX_PORT		*pRxPort)	/* ptr to port struct for which the ring
1882				   should be filled */
1883{
1884unsigned long	Flags;
1885
1886	spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
1887	while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
1888		if(!FillRxDescriptor(pAC, pRxPort))
1889			break;
1890	}
1891	spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
1892} /* FillRxRing */
1893
1894
1895/*****************************************************************************
1896 *
1897 * 	FillRxDescriptor - fill one buffer into the receive ring
1898 *
1899 * Description:
1900 *	The function allocates a new receive buffer and
1901 *	puts it into the next descriptor.
1902 *
1903 * Returns:
1904 *	SK_TRUE - a buffer was added to the ring
1905 *	SK_FALSE - a buffer could not be added
1906 */
1907static SK_BOOL FillRxDescriptor(
1908SK_AC		*pAC,		/* pointer to the adapter context struct */
1909RX_PORT		*pRxPort)	/* ptr to port struct of ring to fill */
1910{
1911struct sk_buff	*pMsgBlock;	/* pointer to a new message block */
1912RXD		*pRxd;		/* the rxd to fill */
1913SK_U16		Length;		/* data fragment length */
1914SK_U64		PhysAddr;	/* physical address of a rx buffer */
1915
1916	pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
1917	if (pMsgBlock == NULL) {
1918		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1919			SK_DBGCAT_DRV_ENTRY,
1920			("%s: Allocation of rx buffer failed !\n",
1921			pAC->dev[pRxPort->PortIndex]->name));
1922		SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
1923		return(SK_FALSE);
1924	}
1925	skb_reserve(pMsgBlock, 2); /* to align IP frames */
1926	/* skb allocated ok, so add buffer */
1927	pRxd = pRxPort->pRxdRingTail;
1928	pRxPort->pRxdRingTail = pRxd->pNextRxd;
1929	pRxPort->RxdRingFree--;
1930	Length = pAC->RxBufSize;
1931	PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev,
1932					 virt_to_page(pMsgBlock->data),
1933					 ((unsigned long) pMsgBlock->data &
1934					  ~PAGE_MASK),
1935					 pAC->RxBufSize - 2,
1936					 PCI_DMA_FROMDEVICE);
1937	pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1938	pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1939	pRxd->pMBuf = pMsgBlock;
1940	pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
1941		RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
1942	return (SK_TRUE);
1943
1944} /* FillRxDescriptor */
1945
1946
1947/*****************************************************************************
1948 *
1949 * 	ReQueueRxBuffer - fill one buffer back into the receive ring
1950 *
1951 * Description:
1952 *	Fill a given buffer back into the rx ring. The buffer
1953 *	has been previously allocated and aligned, and its phys.
1954 *	address calculated, so this is no more necessary.
1955 *
1956 * Returns: N/A
1957 */
1958static void ReQueueRxBuffer(
1959SK_AC		*pAC,		/* pointer to the adapter context struct */
1960RX_PORT		*pRxPort,	/* ptr to port struct of ring to fill */
1961struct sk_buff	*pMsg,		/* pointer to the buffer */
1962SK_U32		PhysHigh,	/* phys address high dword */
1963SK_U32		PhysLow)	/* phys address low dword */
1964{
1965RXD		*pRxd;		/* the rxd to fill */
1966SK_U16		Length;		/* data fragment length */
1967
1968	pRxd = pRxPort->pRxdRingTail;
1969	pRxPort->pRxdRingTail = pRxd->pNextRxd;
1970	pRxPort->RxdRingFree--;
1971	Length = pAC->RxBufSize;
1972	pRxd->VDataLow = PhysLow;
1973	pRxd->VDataHigh = PhysHigh;
1974	pRxd->pMBuf = pMsg;
1975	pRxd->RBControl = RX_CTRL_OWN_BMU | RX_CTRL_STF |
1976		RX_CTRL_EOF_IRQ | RX_CTRL_CHECK_CSUM | Length;
1977	return;
1978} /* ReQueueRxBuffer */
1979
1980
1981/*****************************************************************************
1982 *
1983 * 	ReceiveIrq - handle a receive IRQ
1984 *
1985 * Description:
1986 *	This function is called when a receive IRQ is set.
1987 *	It walks the receive descriptor ring and sends up all
1988 *	frames that are complete.
1989 *
1990 * Returns:	N/A
1991 */
1992static void ReceiveIrq(
1993SK_AC		*pAC,		/* pointer to adapter context */
1994RX_PORT		*pRxPort)	/* pointer to receive port struct */
1995{
1996RXD		*pRxd;		/* pointer to receive descriptors */
1997SK_U32		Control;	/* control field of descriptor */
1998struct sk_buff	*pMsg;		/* pointer to message holding frame */
1999struct sk_buff	*pNewMsg;	/* pointer to a new message for copying frame */
2000int		FrameLength;	/* total length of received frame */
2001SK_MBUF		*pRlmtMbuf;	/* ptr to a buffer for giving a frame to rlmt */
2002SK_EVPARA	EvPara;		/* an event parameter union */
2003int		PortIndex = pRxPort->PortIndex;
2004unsigned int	Offset;
2005unsigned int	NumBytes;
2006unsigned int	ForRlmt;
2007SK_BOOL		IsBc;
2008SK_BOOL		IsMc;
2009SK_U32		FrameStat;
2010unsigned short	Csum1;
2011unsigned short	Csum2;
2012unsigned short	Type;
2013int		Result;
2014SK_U64		PhysAddr;
2015
2016rx_start:
2017	/* do forever; exit if RX_CTRL_OWN_BMU found */
2018	for ( pRxd = pRxPort->pRxdRingHead ;
2019		  pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
2020		  pRxd = pRxd->pNextRxd,
2021		  pRxPort->pRxdRingHead = pRxd,
2022		  pRxPort->RxdRingFree ++) {
2023
2024		/*
2025		 * For a better understanding of this loop
2026		 * Go through every descriptor beginning at the head
2027		 * Please note: the ring might be completely received so the OWN bit
2028		 * set is not a good crirteria to leave that loop.
2029		 * Therefore the RingFree counter is used.
2030		 * On entry of this loop pRxd is a pointer to the Rxd that needs
2031		 * to be checked next.
2032		 */
2033
2034		Control = pRxd->RBControl;
2035
2036		/* check if this descriptor is ready */
2037		if ((Control & RX_CTRL_OWN_BMU) != 0) {
2038			/* this descriptor is not yet ready */
2039			/* This is the usual end of the loop */
2040			/* We don't need to start the ring again */
2041			FillRxRing(pAC, pRxPort);
2042			return;
2043		}
2044
2045		/* get length of frame and check it */
2046		FrameLength = Control & RX_CTRL_LEN_MASK;
2047		if (FrameLength > pAC->RxBufSize) {
2048			goto rx_failed;
2049		}
2050
2051		/* check for STF and EOF */
2052		if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) !=
2053			(RX_CTRL_STF | RX_CTRL_EOF)) {
2054			goto rx_failed;
2055		}
2056
2057		/* here we have a complete frame in the ring */
2058		pMsg = pRxd->pMBuf;
2059
2060		FrameStat = pRxd->FrameStat;
2061		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2062			("Received frame of length %d on port %d\n",
2063			FrameLength, PortIndex));
2064		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2065			("Number of free rx descriptors: %d\n",
2066			pRxPort->RxdRingFree));
2067		/*DumpMsg(pMsg, "Rx");	*/
2068
2069		if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID ||
2070			(FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
2071			/* there is a receive error in this frame */
2072			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2073				SK_DBGCAT_DRV_RX_PROGRESS,
2074				("skge: Error in received frame, dropped!\n"
2075				"Control: %x\nRxStat: %x\n",
2076				Control, FrameStat));
2077			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2078			PhysAddr |= (SK_U64) pRxd->VDataLow;
2079			pci_dma_sync_single(&pAC->PciDev,
2080					    (dma_addr_t) PhysAddr,
2081					    FrameLength,
2082					    PCI_DMA_FROMDEVICE);
2083			ReQueueRxBuffer(pAC, pRxPort, pMsg,
2084				pRxd->VDataHigh, pRxd->VDataLow);
2085
2086			continue;
2087		}
2088
2089		/*
2090		 * if short frame then copy data to reduce memory waste
2091		 */
2092		if ((FrameLength < SK_COPY_THRESHOLD) &&
2093			((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
2094			/*
2095			 * Short frame detected and allocation successfull
2096			 */
2097			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2098			PhysAddr |= (SK_U64) pRxd->VDataLow;
2099
2100			/* use new skb and copy data */
2101			skb_reserve(pNewMsg, 2);
2102			skb_put(pNewMsg, FrameLength);
2103			pci_dma_sync_single(&pAC->PciDev,
2104					    (dma_addr_t) PhysAddr,
2105					    FrameLength,
2106					    PCI_DMA_FROMDEVICE);
2107			eth_copy_and_sum(pNewMsg, pMsg->data,
2108				FrameLength, 0);
2109			ReQueueRxBuffer(pAC, pRxPort, pMsg,
2110				pRxd->VDataHigh, pRxd->VDataLow);
2111			pMsg = pNewMsg;
2112
2113		}
2114		else {
2115			/*
2116			 * if large frame, or SKB allocation failed, pass
2117			 * the SKB directly to the networking
2118			 */
2119
2120			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2121			PhysAddr |= (SK_U64) pRxd->VDataLow;
2122
2123			/* release the DMA mapping */
2124			pci_unmap_page(&pAC->PciDev,
2125				       PhysAddr,
2126				       pAC->RxBufSize - 2,
2127				       PCI_DMA_FROMDEVICE);
2128
2129			/* set length in message */
2130			skb_put(pMsg, FrameLength);
2131			/* hardware checksum */
2132			Type = ntohs(*((short*)&pMsg->data[12]));
2133			if (Type == 0x800) {
2134				Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
2135				Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
2136				if ((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) {
2137					Result = SkCsGetReceiveInfo(pAC,
2138						&pMsg->data[14],
2139						Csum1, Csum2, pRxPort->PortIndex);
2140					if (Result ==
2141						SKCS_STATUS_IP_FRAGMENT ||
2142						Result ==
2143						SKCS_STATUS_IP_CSUM_OK ||
2144						Result ==
2145						SKCS_STATUS_TCP_CSUM_OK ||
2146						Result ==
2147						SKCS_STATUS_UDP_CSUM_OK) {
2148						pMsg->ip_summed =
2149						CHECKSUM_UNNECESSARY;
2150					}
2151				} /* checksum calculation valid */
2152			} /* IP frame */
2153		} /* frame > SK_COPY_TRESHOLD */
2154
2155		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
2156		ForRlmt = SK_RLMT_RX_PROTOCOL;
2157		IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
2158		SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
2159			IsBc, &Offset, &NumBytes);
2160		if (NumBytes != 0) {
2161			IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
2162			SK_RLMT_LOOKAHEAD(pAC, PortIndex,
2163				&pMsg->data[Offset],
2164				IsBc, IsMc, &ForRlmt);
2165		}
2166		if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
2167					SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("W"));
2168			/* send up only frames from active port */
2169			if ((PortIndex == pAC->ActivePort) ||
2170				(pAC->RlmtNets == 2)) {
2171				/* frame for upper layer */
2172				SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
2173#ifdef xDEBUG
2174				DumpMsg(pMsg, "Rx");
2175#endif
2176				SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
2177					FrameLength, pRxPort->PortIndex);
2178
2179				pMsg->dev = pAC->dev[pRxPort->PortIndex];
2180				pMsg->protocol = eth_type_trans(pMsg,
2181					pAC->dev[pRxPort->PortIndex]);
2182				netif_rx(pMsg);
2183				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2184			}
2185			else {
2186				/* drop frame */
2187				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2188					SK_DBGCAT_DRV_RX_PROGRESS,
2189					("D"));
2190				DEV_KFREE_SKB(pMsg);
2191			}
2192
2193		} /* if not for rlmt */
2194		else {
2195			/* packet for rlmt */
2196			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2197				SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
2198			pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
2199				pAC->IoBase, FrameLength);
2200			if (pRlmtMbuf != NULL) {
2201				pRlmtMbuf->pNext = NULL;
2202				pRlmtMbuf->Length = FrameLength;
2203				pRlmtMbuf->PortIdx = PortIndex;
2204				EvPara.pParaPtr = pRlmtMbuf;
2205				memcpy((char*)(pRlmtMbuf->pData),
2206					   (char*)(pMsg->data),
2207					   FrameLength);
2208				SkEventQueue(pAC, SKGE_RLMT,
2209					SK_RLMT_PACKET_RECEIVED,
2210					EvPara);
2211				pAC->CheckQueue = SK_TRUE;
2212				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2213					SK_DBGCAT_DRV_RX_PROGRESS,
2214					("Q"));
2215			}
2216			if ((pAC->dev[pRxPort->PortIndex]->flags &
2217				(IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
2218				(ForRlmt & SK_RLMT_RX_PROTOCOL) ==
2219				SK_RLMT_RX_PROTOCOL) {
2220				pMsg->dev = pAC->dev[pRxPort->PortIndex];
2221				pMsg->protocol = eth_type_trans(pMsg,
2222					pAC->dev[pRxPort->PortIndex]);
2223				netif_rx(pMsg);
2224				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2225			}
2226			else {
2227				DEV_KFREE_SKB(pMsg);
2228			}
2229
2230		} /* if packet for rlmt */
2231	} /* for ... scanning the RXD ring */
2232
2233	/* RXD ring is empty -> fill and restart */
2234	FillRxRing(pAC, pRxPort);
2235	/* do not start if called from Close */
2236	if (pAC->BoardLevel > 0) {
2237		ClearAndStartRx(pAC, PortIndex);
2238	}
2239	return;
2240
2241rx_failed:
2242	/* remove error frame */
2243	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
2244		("Schrottdescriptor, length: 0x%x\n", FrameLength));
2245
2246	/* release the DMA mapping */
2247	PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2248	PhysAddr |= (SK_U64) pRxd->VDataLow;
2249	pci_unmap_page(&pAC->PciDev,
2250		       PhysAddr,
2251		       pAC->RxBufSize - 2,
2252		       PCI_DMA_FROMDEVICE);
2253	DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
2254	pRxd->pMBuf = NULL;
2255	pRxPort->RxdRingFree++;
2256	pRxPort->pRxdRingHead = pRxd->pNextRxd;
2257	goto rx_start;
2258
2259} /* ReceiveIrq */
2260
2261
2262/*****************************************************************************
2263 *
2264 * 	ClearAndStartRx - give a start receive command to BMU, clear IRQ
2265 *
2266 * Description:
2267 *	This function sends a start command and a clear interrupt
2268 *	command for one receive queue to the BMU.
2269 *
2270 * Returns: N/A
2271 *	none
2272 */
2273static void ClearAndStartRx(
2274SK_AC	*pAC,		/* pointer to the adapter context */
2275int	PortIndex)	/* index of the receive port (XMAC) */
2276{
2277	SK_OUT8(pAC->IoBase, RxQueueAddr[PortIndex]+RX_Q_CTRL,
2278		RX_Q_CTRL_START | RX_Q_CTRL_CLR_I_EOF);
2279} /* ClearAndStartRx */
2280
2281
2282/*****************************************************************************
2283 *
2284 * 	ClearTxIrq - give a clear transmit IRQ command to BMU
2285 *
2286 * Description:
2287 *	This function sends a clear tx IRQ command for one
2288 *	transmit queue to the BMU.
2289 *
2290 * Returns: N/A
2291 */
2292static void ClearTxIrq(
2293SK_AC	*pAC,		/* pointer to the adapter context */
2294int	PortIndex,	/* index of the transmit port (XMAC) */
2295int	Prio)		/* priority or normal queue */
2296{
2297	SK_OUT8(pAC->IoBase, TxQueueAddr[PortIndex][Prio]+TX_Q_CTRL,
2298		TX_Q_CTRL_CLR_I_EOF);
2299} /* ClearTxIrq */
2300
2301
2302/*****************************************************************************
2303 *
2304 * 	ClearRxRing - remove all buffers from the receive ring
2305 *
2306 * Description:
2307 *	This function removes all receive buffers from the ring.
2308 *	The receive BMU must be stopped before calling this function.
2309 *
2310 * Returns: N/A
2311 */
2312static void ClearRxRing(
2313SK_AC	*pAC,		/* pointer to adapter context */
2314RX_PORT	*pRxPort)	/* pointer to rx port struct */
2315{
2316RXD		*pRxd;	/* pointer to the current descriptor */
2317unsigned long	Flags;
2318 SK_U64		PhysAddr;
2319
2320	if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
2321		return;
2322	}
2323	spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
2324	pRxd = pRxPort->pRxdRingHead;
2325	do {
2326		if (pRxd->pMBuf != NULL) {
2327			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2328			PhysAddr |= (SK_U64) pRxd->VDataLow;
2329			pci_unmap_page(&pAC->PciDev,
2330				       PhysAddr,
2331				       pAC->RxBufSize - 2,
2332				       PCI_DMA_FROMDEVICE);
2333			DEV_KFREE_SKB(pRxd->pMBuf);
2334			pRxd->pMBuf = NULL;
2335		}
2336		pRxd->RBControl &= RX_CTRL_OWN_BMU;
2337		pRxd = pRxd->pNextRxd;
2338		pRxPort->RxdRingFree++;
2339	} while (pRxd != pRxPort->pRxdRingTail);
2340	pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
2341	spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
2342} /* ClearRxRing */
2343
2344
2345/*****************************************************************************
2346 *
2347 *	ClearTxRing - remove all buffers from the transmit ring
2348 *
2349 * Description:
2350 *	This function removes all transmit buffers from the ring.
2351 *	The transmit BMU must be stopped before calling this function
2352 *	and transmitting at the upper level must be disabled.
2353 *	The BMU own bit of all descriptors is cleared, the rest is
2354 *	done by calling FreeTxDescriptors.
2355 *
2356 * Returns: N/A
2357 */
2358static void ClearTxRing(
2359SK_AC	*pAC,		/* pointer to adapter context */
2360TX_PORT	*pTxPort)	/* pointer to tx prt struct */
2361{
2362TXD		*pTxd;		/* pointer to the current descriptor */
2363int		i;
2364unsigned long	Flags;
2365
2366	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
2367	pTxd = pTxPort->pTxdRingHead;
2368	for (i=0; i<pAC->TxDescrPerRing; i++) {
2369		pTxd->TBControl &= ~TX_CTRL_OWN_BMU;
2370		pTxd = pTxd->pNextTxd;
2371	}
2372	FreeTxDescriptors(pAC, pTxPort);
2373	spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
2374} /* ClearTxRing */
2375
2376
2377/*****************************************************************************
2378 *
2379 * 	SetQueueSizes - configure the sizes of rx and tx queues
2380 *
2381 * Description:
2382 *	This function assigns the sizes for active and passive port
2383 *	to the appropriate HWinit structure variables.
2384 *	The passive port(s) get standard values, all remaining RAM
2385 *	is given to the active port.
2386 *	The queue sizes are in kbyte and must be multiple of 8.
2387 *	The limits for the number of buffers filled into the rx rings
2388 *	is also set in this routine.
2389 *
2390 * Returns:
2391 *	none
2392 */
2393static void SetQueueSizes(
2394SK_AC	*pAC)	/* pointer to the adapter context */
2395{
2396int	StandbyRam;	/* adapter RAM used for a standby port */
2397int	RemainingRam;	/* adapter RAM available for the active port */
2398int	RxRam;		/* RAM used for the active port receive queue */
2399int	i;		/* loop counter */
2400
2401if (pAC->RlmtNets == 1) {
2402	StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE +
2403		SK_RLMT_STANDBY_QXSSIZE;
2404	RemainingRam = pAC->GIni.GIRamSize -
2405		(pAC->GIni.GIMacsFound-1) * StandbyRam;
2406	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2407		pAC->GIni.GP[i].PRxQSize = SK_RLMT_STANDBY_QRXSIZE;
2408		pAC->GIni.GP[i].PXSQSize = SK_RLMT_STANDBY_QXSSIZE;
2409		pAC->GIni.GP[i].PXAQSize = SK_RLMT_STANDBY_QXASIZE;
2410	}
2411	RxRam = (RemainingRam * 8 / 10) & ~7;
2412	pAC->GIni.GP[pAC->ActivePort].PRxQSize = RxRam;
2413	pAC->GIni.GP[pAC->ActivePort].PXSQSize = 0;
2414	pAC->GIni.GP[pAC->ActivePort].PXAQSize =
2415		(RemainingRam - RxRam) & ~7;
2416	pAC->RxQueueSize = RxRam;
2417	pAC->TxSQueueSize = 0;
2418	pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
2419	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2420		("queue sizes settings - rx:%d  txA:%d txS:%d\n",
2421		pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize));
2422} else {
2423	RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound;
2424	RxRam = (RemainingRam * 8 / 10) & ~7;
2425	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2426		pAC->GIni.GP[i].PRxQSize = RxRam;
2427		pAC->GIni.GP[i].PXSQSize = 0;
2428		pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7;
2429	}
2430
2431	pAC->RxQueueSize = RxRam;
2432	pAC->TxSQueueSize = 0;
2433	pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
2434}
2435	for (i=0; i<SK_MAX_MACS; i++) {
2436		pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing;
2437	}
2438
2439	if (pAC->RlmtNets == 2) {
2440		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2441			pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
2442		}
2443	} else {
2444		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2445			pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
2446		}
2447		/*
2448		 * Do not set the Limit to 0, because this could cause
2449		 * wrap around with ReQueue'ed buffers (a buffer could
2450		 * be requeued in the same position, made accessable to
2451		 * the hardware, and the hardware could change its
2452		 * contents!
2453		 */
2454		pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
2455	}
2456
2457#ifdef DEBUG
2458	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2459		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
2460			("i: %d,  RxQSize: %d,  PXSQsize: %d, PXAQSize: %d\n",
2461			i,
2462			pAC->GIni.GP[i].PRxQSize,
2463			pAC->GIni.GP[i].PXSQSize,
2464			pAC->GIni.GP[i].PXAQSize));
2465	}
2466#endif
2467} /* SetQueueSizes */
2468
2469
2470/*****************************************************************************
2471 *
2472 * 	SkGeSetMacAddr - Set the hardware MAC address
2473 *
2474 * Description:
2475 *	This function sets the MAC address used by the adapter.
2476 *
2477 * Returns:
2478 *	0, if everything is ok
2479 *	!=0, on error
2480 */
2481static int SkGeSetMacAddr(struct net_device *dev, void *p)
2482{
2483
2484DEV_NET *pNet = (DEV_NET*) dev->priv;
2485SK_AC	*pAC = pNet->pAC;
2486
2487struct sockaddr	*addr = p;
2488unsigned long	Flags;
2489
2490	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2491		("SkGeSetMacAddr starts now...\n"));
2492	if(netif_running(dev)) {
2493		return -EBUSY;
2494	}
2495	memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
2496
2497	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2498
2499	if (pAC->RlmtNets == 2)
2500		SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
2501			(SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2502	else
2503		SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
2504			(SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2505
2506
2507
2508	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2509	return 0;
2510} /* SkGeSetMacAddr */
2511
2512
2513/*****************************************************************************
2514 *
2515 * 	SkGeSetRxMode - set receive mode
2516 *
2517 * Description:
2518 *	This function sets the receive mode of an adapter. The adapter
2519 *	supports promiscuous mode, allmulticast mode and a number of
2520 *	multicast addresses. If more multicast addresses the available
2521 *	are selected, a hash function in the hardware is used.
2522 *
2523 * Returns:
2524 *	0, if everything is ok
2525 *	!=0, on error
2526 */
2527static void SkGeSetRxMode(struct net_device *dev)
2528{
2529
2530DEV_NET		*pNet;
2531SK_AC		*pAC;
2532
2533struct dev_mc_list	*pMcList;
2534int			i;
2535int			PortIdx;
2536unsigned long		Flags;
2537
2538	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2539		("SkGeSetRxMode starts now... "));
2540
2541	pNet = (DEV_NET*) dev->priv;
2542	pAC = pNet->pAC;
2543	if (pAC->RlmtNets == 1)
2544		PortIdx = pAC->ActivePort;
2545	else
2546		PortIdx = pNet->NetNr;
2547
2548	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2549	if (dev->flags & IFF_PROMISC) {
2550		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2551			("PROMISCUOUS mode\n"));
2552		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2553			SK_PROM_MODE_LLC);
2554	} else if (dev->flags & IFF_ALLMULTI) {
2555		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2556			("ALLMULTI mode\n"));
2557		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2558			SK_PROM_MODE_ALL_MC);
2559	} else {
2560		SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2561			SK_PROM_MODE_NONE);
2562		SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
2563
2564		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2565			("Number of MC entries: %d ", dev->mc_count));
2566
2567		pMcList = dev->mc_list;
2568		for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
2569			SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
2570				(SK_MAC_ADDR*)pMcList->dmi_addr, 0);
2571			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
2572				("%02x:%02x:%02x:%02x:%02x:%02x\n",
2573				pMcList->dmi_addr[0],
2574				pMcList->dmi_addr[1],
2575				pMcList->dmi_addr[2],
2576				pMcList->dmi_addr[3],
2577				pMcList->dmi_addr[4],
2578				pMcList->dmi_addr[5]));
2579		}
2580		SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
2581
2582	}
2583	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2584
2585	return;
2586} /* SkGeSetRxMode */
2587
2588
2589static int SkGeChangeMtu(struct net_device *dev, int NewMtu)
2590{
2591DEV_NET		*pNet;
2592DEV_NET		*pOtherNet;
2593SK_AC		*pAC;
2594unsigned long	Flags;
2595int		i;
2596SK_EVPARA 	EvPara;
2597
2598	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2599		("SkGeChangeMtu starts now...\n"));
2600
2601	pNet = (DEV_NET*) dev->priv;
2602	pAC = pNet->pAC;
2603
2604	if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
2605		return -EINVAL;
2606	}
2607
2608	pNet->Mtu = NewMtu;
2609	pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
2610	if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) {
2611		return(0);
2612	}
2613
2614	EvPara.Para32[0] = pNet->NetNr;
2615	EvPara.Para32[1] = -1;
2616
2617	pAC->RxBufSize = NewMtu + 32;
2618	dev->mtu = NewMtu;
2619
2620	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2621		("New MTU: %d\n", NewMtu));
2622
2623	if(pAC->BoardLevel != 2) {
2624		return 0;
2625	}
2626
2627	/* prevent reconfiguration while changing the MTU */
2628
2629	/* disable interrupts */
2630	SK_OUT32(pAC->IoBase, B0_IMSK, 0);
2631	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2632
2633	/* Found more than one port */
2634	if ((pAC->GIni.GIMacsFound == 2 ) &&
2635		(pAC->RlmtNets == 2)) {
2636			/* Stop both ports */
2637			EvPara.Para32[0] = 0;
2638			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2639			EvPara.Para32[0] = 1;
2640			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2641	} else {
2642		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2643	}
2644
2645	SkEventDispatcher(pAC, pAC->IoBase);
2646
2647	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2648		spin_lock_irqsave(
2649			&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
2650		netif_stop_queue(pAC->dev[i]);
2651	}
2652
2653	/*
2654	 * adjust number of rx buffers allocated
2655	 */
2656	if (NewMtu > 1500) {
2657		/* use less rx buffers */
2658		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2659			/* Found more than one port */
2660			if ((pAC->GIni.GIMacsFound == 2 ) &&
2661				(pAC->RlmtNets == 2)) {
2662					pAC->RxPort[i].RxFillLimit =
2663						pAC->RxDescrPerRing - 100;
2664			} else {
2665				if (i == pAC->ActivePort)
2666					pAC->RxPort[i].RxFillLimit =
2667						pAC->RxDescrPerRing - 100;
2668				else
2669					pAC->RxPort[i].RxFillLimit =
2670						pAC->RxDescrPerRing - 10;
2671			}
2672		}
2673	}
2674	else {
2675		/* use normal anoumt of rx buffers */
2676		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2677			/* Found more than one port */
2678			if ((pAC->GIni.GIMacsFound == 2 ) &&
2679				(pAC->RlmtNets == 2)) {
2680					pAC->RxPort[i].RxFillLimit = 1;
2681			} else {
2682				if (i == pAC->ActivePort)
2683					pAC->RxPort[i].RxFillLimit = 1;
2684				else
2685					pAC->RxPort[i].RxFillLimit =
2686						pAC->RxDescrPerRing - 100;
2687			}
2688		}
2689	}
2690
2691	SkGeDeInit(pAC, pAC->IoBase);
2692
2693	/*
2694	 * enable/disable hardware support for long frames
2695	 */
2696	if (NewMtu > 1500) {
2697//		pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
2698		pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
2699		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2700			pAC->GIni.GP[i].PRxCmd =
2701				XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
2702		}
2703	}
2704	else {
2705		if ((pAC->GIni.GIMacsFound == 2 ) &&
2706			(pAC->RlmtNets == 2)) {
2707			pAC->GIni.GIPortUsage = SK_MUL_LINK;
2708		} else {
2709			pAC->GIni.GIPortUsage = SK_RED_LINK;
2710		}
2711		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2712			pAC->GIni.GP[i].PRxCmd = XM_RX_STRIP_FCS;
2713		}
2714	}
2715
2716	SkGeInit(   pAC, pAC->IoBase, 1);
2717	SkI2cInit(  pAC, pAC->IoBase, 1);
2718	SkEventInit(pAC, pAC->IoBase, 1);
2719	SkPnmiInit( pAC, pAC->IoBase, 1);
2720	SkAddrInit( pAC, pAC->IoBase, 1);
2721	SkRlmtInit( pAC, pAC->IoBase, 1);
2722	SkTimerInit(pAC, pAC->IoBase, 1);
2723
2724	SkGeInit(   pAC, pAC->IoBase, 2);
2725	SkI2cInit(  pAC, pAC->IoBase, 2);
2726	SkEventInit(pAC, pAC->IoBase, 2);
2727	SkPnmiInit( pAC, pAC->IoBase, 2);
2728	SkAddrInit( pAC, pAC->IoBase, 2);
2729	SkRlmtInit( pAC, pAC->IoBase, 2);
2730	SkTimerInit(pAC, pAC->IoBase, 2);
2731
2732	/*
2733	 * clear and reinit the rx rings here
2734	 */
2735	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2736		ReceiveIrq(pAC, &pAC->RxPort[i]);
2737		ClearRxRing(pAC, &pAC->RxPort[i]);
2738		FillRxRing(pAC, &pAC->RxPort[i]);
2739
2740		/* Enable transmit descriptor polling. */
2741		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
2742		FillRxRing(pAC, &pAC->RxPort[i]);
2743	};
2744
2745	SkGeYellowLED(pAC, pAC->IoBase, 1);
2746
2747#ifdef USE_INT_MOD
2748	{
2749		unsigned long ModBase;
2750		ModBase = 53125000 / INTS_PER_SEC;
2751		SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
2752		SK_OUT32(pAC->IoBase, B2_IRQM_MSK, IRQ_MOD_MASK);
2753		SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
2754	}
2755#endif
2756
2757	netif_start_queue(pAC->dev[pNet->PortNr]);
2758	for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
2759		spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2760	}
2761
2762	/* enable Interrupts */
2763	SK_OUT32(pAC->IoBase, B0_IMSK, IRQ_MASK);
2764	SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
2765
2766	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2767	SkEventDispatcher(pAC, pAC->IoBase);
2768
2769	/* Found more than one port */
2770	if ((pAC->GIni.GIMacsFound == 2 ) &&
2771		(pAC->RlmtNets == 2)) {
2772			/* Start both ports */
2773			EvPara.Para32[0] = pAC->RlmtNets;
2774			EvPara.Para32[1] = -1;
2775			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
2776				EvPara);
2777
2778
2779			EvPara.Para32[1] = -1;
2780			EvPara.Para32[0] = pNet->PortNr;
2781			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2782
2783			if (pOtherNet->Up) {
2784				EvPara.Para32[0] = pOtherNet->PortNr;
2785				SkEventQueue(pAC, SKGE_RLMT,
2786					SK_RLMT_START, EvPara);
2787			}
2788	} else {
2789		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2790	}
2791
2792	SkEventDispatcher(pAC, pAC->IoBase);
2793	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2794
2795	return 0;
2796} /* SkGeChangeMtu */
2797
2798
2799/*****************************************************************************
2800 *
2801 * 	SkGeStats - return ethernet device statistics
2802 *
2803 * Description:
2804 *	This function return statistic data about the ethernet device
2805 *	to the operating system.
2806 *
2807 * Returns:
2808 *	pointer to the statistic structure.
2809 */
2810static struct net_device_stats *SkGeStats(struct net_device *dev)
2811{
2812DEV_NET *pNet = (DEV_NET*) dev->priv;
2813SK_AC	*pAC = pNet->pAC;
2814SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
2815SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
2816unsigned int    Size;                   /* size of pnmi struct */
2817unsigned long	Flags;			/* for spin lock */
2818
2819	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2820		("SkGeStats starts now...\n"));
2821	pPnmiStruct = &pAC->PnmiStruct;
2822        memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
2823        spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2824        Size = SK_PNMI_STRUCT_SIZE;
2825		SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
2826        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2827        pPnmiStat = &pPnmiStruct->Stat[0];
2828        pPnmiConf = &pPnmiStruct->Conf[0];
2829
2830	pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
2831	pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
2832	pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
2833	pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
2834	pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
2835	pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2836	pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
2837	pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
2838	pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
2839	pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2840
2841	/* detailed rx_errors: */
2842	pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
2843	pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2844	pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
2845	pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
2846	pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2847	pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
2848
2849	/* detailed tx_errors */
2850	pAC->stats.tx_aborted_errors = (SK_U32) 0;
2851	pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2852	pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
2853	pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2854	pAC->stats.tx_window_errors = (SK_U32) 0;
2855
2856	return(&pAC->stats);
2857} /* SkGeStats */
2858
2859
2860/*****************************************************************************
2861 *
2862 * 	SkGeIoctl - IO-control function
2863 *
2864 * Description:
2865 *	This function is called if an ioctl is issued on the device.
2866 *	There are three subfunction for reading, writing and test-writing
2867 *	the private MIB data structure (usefull for SysKonnect-internal tools).
2868 *
2869 * Returns:
2870 *	0, if everything is ok
2871 *	!=0, on error
2872 */
2873static int SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd)
2874{
2875DEV_NET		*pNet;
2876SK_AC		*pAC;
2877
2878SK_GE_IOCTL	Ioctl;
2879unsigned int	Err = 0;
2880int		Size;
2881
2882	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2883		("SkGeIoctl starts now...\n"));
2884
2885	pNet = (DEV_NET*) dev->priv;
2886	pAC = pNet->pAC;
2887
2888	if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
2889		return -EFAULT;
2890	}
2891
2892	switch(cmd) {
2893	case SK_IOCTL_SETMIB:
2894	case SK_IOCTL_PRESETMIB:
2895		if (!capable(CAP_NET_ADMIN)) return -EPERM;
2896 	case SK_IOCTL_GETMIB:
2897		if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
2898			Ioctl.Len<sizeof(pAC->PnmiStruct)?
2899			Ioctl.Len : sizeof(pAC->PnmiStruct))) {
2900			return -EFAULT;
2901		}
2902		Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
2903		if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
2904			Ioctl.Len<Size? Ioctl.Len : Size)) {
2905			return -EFAULT;
2906		}
2907		Ioctl.Len = Size;
2908		if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
2909			return -EFAULT;
2910		}
2911		break;
2912	default:
2913		Err = -EOPNOTSUPP;
2914	}
2915	return(Err);
2916} /* SkGeIoctl */
2917
2918
2919/*****************************************************************************
2920 *
2921 * 	SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
2922 *
2923 * Description:
2924 *	This function reads/writes the MIB data using PNMI (Private Network
2925 *	Management Interface).
2926 *	The destination for the data must be provided with the
2927 *	ioctl call and is given to the driver in the form of
2928 *	a user space address.
2929 *	Copying from the user-provided data area into kernel messages
2930 *	and back is done by copy_from_user and copy_to_user calls in
2931 *	SkGeIoctl.
2932 *
2933 * Returns:
2934 *	returned size from PNMI call
2935 */
2936static int SkGeIocMib(
2937DEV_NET		*pNet,	/* pointer to the adapter context */
2938unsigned int	Size,	/* length of ioctl data */
2939int		mode)	/* flag for set/preset */
2940{
2941unsigned long	Flags;	/* for spin lock */
2942SK_AC		*pAC;
2943
2944	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2945		("SkGeIocMib starts now...\n"));
2946	pAC = pNet->pAC;
2947	/* access MIB */
2948	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2949	switch(mode) {
2950	case SK_IOCTL_GETMIB:
2951		SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
2952			pNet->NetNr);
2953		break;
2954	case SK_IOCTL_PRESETMIB:
2955		SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
2956			pNet->NetNr);
2957		break;
2958	case SK_IOCTL_SETMIB:
2959		SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
2960			pNet->NetNr);
2961		break;
2962	default:
2963		break;
2964	}
2965	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2966	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2967		("MIB data access succeeded\n"));
2968	return (Size);
2969} /* SkGeIocMib */
2970
2971
2972/*****************************************************************************
2973 *
2974 * 	GetConfiguration - read configuration information
2975 *
2976 * Description:
2977 *	This function reads per-adapter configuration information from
2978 *	the options provided on the command line.
2979 *
2980 * Returns:
2981 *	none
2982 */
2983static void GetConfiguration(
2984SK_AC	*pAC)	/* pointer to the adapter context structure */
2985{
2986SK_I32	Port;		/* preferred port */
2987int	AutoNeg;	/* auto negotiation off (0) or on (1) */
2988int	DuplexCap;	/* duplex capabilities (0=both, 1=full, 2=half */
2989int	MSMode;		/* master / slave mode selection */
2990SK_BOOL	AutoSet;
2991SK_BOOL DupSet;
2992/*
2993 *	The two parameters AutoNeg. and DuplexCap. map to one configuration
2994 *	parameter. The mapping is described by this table:
2995 *	DuplexCap ->	|	both	|	full	|	half	|
2996 *	AutoNeg		|		|		|		|
2997 *	-----------------------------------------------------------------
2998 *	Off		|    illegal	|	Full	|	Half	|
2999 *	-----------------------------------------------------------------
3000 *	On		|   AutoBoth	|   AutoFull	|   AutoHalf	|
3001 *	-----------------------------------------------------------------
3002 *	Sense		|   AutoSense	|   AutoSense	|   AutoSense	|
3003 */
3004int	Capabilities[3][3] =
3005		{ {		  -1, SK_LMODE_FULL,     SK_LMODE_HALF},
3006		  {SK_LMODE_AUTOBOTH, SK_LMODE_AUTOFULL, SK_LMODE_AUTOHALF},
3007		  {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
3008#define DC_BOTH	0
3009#define DC_FULL 1
3010#define DC_HALF 2
3011#define AN_OFF	0
3012#define AN_ON	1
3013#define AN_SENS	2
3014
3015	/* settings for port A */
3016	AutoNeg = AN_SENS; /* default: do auto Sense */
3017	AutoSet = SK_FALSE;
3018	if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3019		AutoNeg_A[pAC->Index] != NULL) {
3020		AutoSet = SK_TRUE;
3021		if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
3022			AutoSet = SK_FALSE;
3023		}
3024		else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
3025			AutoNeg = AN_ON;
3026		}
3027		else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
3028			AutoNeg = AN_OFF;
3029		}
3030		else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
3031			AutoNeg = AN_SENS;
3032		}
3033		else printk("%s: Illegal value for AutoNeg_A\n",
3034			pAC->dev[0]->name);
3035	}
3036
3037	DuplexCap = DC_BOTH;
3038	DupSet = SK_FALSE;
3039	if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3040		DupCap_A[pAC->Index] != NULL) {
3041		DupSet = SK_TRUE;
3042		if (strcmp(DupCap_A[pAC->Index],"")==0) {
3043			DupSet = SK_FALSE;
3044		}
3045		else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
3046			DuplexCap = DC_BOTH;
3047		}
3048		else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
3049			DuplexCap = DC_FULL;
3050		}
3051		else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
3052			DuplexCap = DC_HALF;
3053		}
3054		else printk("%s: Illegal value for DupCap_A\n",
3055			pAC->dev[0]->name);
3056	}
3057
3058	/* check for illegal combinations */
3059	if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3060		printk("%s, Port A: DuplexCapabilities"
3061			" ignored using Sense mode\n", pAC->dev[0]->name);
3062	}
3063	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3064		printk("%s, Port A: Illegal combination"
3065			" of values AutoNeg. and DuplexCap.\n    Using "
3066			"Full Duplex\n", pAC->dev[0]->name);
3067
3068		DuplexCap = DC_FULL;
3069	}
3070	if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3071		DuplexCap = DC_FULL;
3072	}
3073
3074	if (!AutoSet && DupSet) {
3075		printk("%s, Port A: Duplex setting not"
3076			" possible in\n    default AutoNegotiation mode"
3077			" (Sense).\n    Using AutoNegotiation On\n",
3078			pAC->dev[0]->name);
3079		AutoNeg = AN_ON;
3080	}
3081
3082	/* set the desired mode */
3083	pAC->GIni.GP[0].PLinkModeConf =
3084		Capabilities[AutoNeg][DuplexCap];
3085
3086	pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3087	if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3088		FlowCtrl_A[pAC->Index] != NULL) {
3089		if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
3090		}
3091		else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
3092			pAC->GIni.GP[0].PFlowCtrlMode =
3093				SK_FLOW_MODE_SYM_OR_REM;
3094		}
3095		else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
3096			pAC->GIni.GP[0].PFlowCtrlMode =
3097				SK_FLOW_MODE_SYMMETRIC;
3098		}
3099		else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
3100			pAC->GIni.GP[0].PFlowCtrlMode =
3101				SK_FLOW_MODE_LOC_SEND;
3102		}
3103		else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
3104			pAC->GIni.GP[0].PFlowCtrlMode =
3105				SK_FLOW_MODE_NONE;
3106		}
3107		else printk("Illegal value for FlowCtrl_A\n");
3108	}
3109	if (AutoNeg==AN_OFF && pAC->GIni.GP[0].PFlowCtrlMode!=
3110		SK_FLOW_MODE_NONE) {
3111		printk("%s, Port A: FlowControl"
3112			" impossible without AutoNegotiation,"
3113			" disabled\n", pAC->dev[0]->name);
3114		pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE;
3115	}
3116
3117	MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
3118	if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3119		Role_A[pAC->Index] != NULL) {
3120		if (strcmp(Role_A[pAC->Index],"")==0) {
3121		}
3122		else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
3123			MSMode = SK_MS_MODE_AUTO;
3124		}
3125		else if (strcmp(Role_A[pAC->Index],"Master")==0) {
3126			MSMode = SK_MS_MODE_MASTER;
3127		}
3128		else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
3129			MSMode = SK_MS_MODE_SLAVE;
3130		}
3131		else printk("%s: Illegal value for Role_A\n",
3132			pAC->dev[0]->name);
3133	}
3134	pAC->GIni.GP[0].PMSMode = MSMode;
3135
3136
3137	/* settings for port B */
3138	AutoNeg = AN_SENS; /* default: do auto Sense */
3139	AutoSet = SK_FALSE;
3140	if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3141		AutoNeg_B[pAC->Index] != NULL) {
3142		AutoSet = SK_TRUE;
3143		if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
3144			AutoSet = SK_FALSE;
3145		}
3146		else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
3147			AutoNeg = AN_ON;
3148		}
3149		else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
3150			AutoNeg = AN_OFF;
3151		}
3152		else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
3153			AutoNeg = AN_SENS;
3154		}
3155		else printk("Illegal value for AutoNeg_B\n");
3156	}
3157
3158	DuplexCap = DC_BOTH;
3159	DupSet = SK_FALSE;
3160	if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3161		DupCap_B[pAC->Index] != NULL) {
3162		DupSet = SK_TRUE;
3163		if (strcmp(DupCap_B[pAC->Index],"")==0) {
3164			DupSet = SK_FALSE;
3165		}
3166		else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
3167			DuplexCap = DC_BOTH;
3168		}
3169		else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
3170			DuplexCap = DC_FULL;
3171		}
3172		else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
3173			DuplexCap = DC_HALF;
3174		}
3175		else printk("Illegal value for DupCap_B\n");
3176	}
3177
3178	/* check for illegal combinations */
3179	if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3180		printk("%s, Port B: DuplexCapabilities"
3181			" ignored using Sense mode\n", pAC->dev[1]->name);
3182	}
3183	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3184		printk("%s, Port B: Illegal combination"
3185			" of values AutoNeg. and DuplexCap.\n    Using "
3186			"Full Duplex\n", pAC->dev[1]->name);
3187
3188		DuplexCap = DC_FULL;
3189	}
3190	if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3191		DuplexCap = DC_FULL;
3192	}
3193
3194	if (!AutoSet && DupSet) {
3195		printk("%s, Port B: Duplex setting not"
3196			" possible in\n    default AutoNegotiation mode"
3197			" (Sense).\n    Using AutoNegotiation On\n",
3198			pAC->dev[1]->name);
3199		AutoNeg = AN_ON;
3200	}
3201
3202	/* set the desired mode */
3203	pAC->GIni.GP[1].PLinkModeConf =
3204		Capabilities[AutoNeg][DuplexCap];
3205
3206	pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3207	if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3208		FlowCtrl_B[pAC->Index] != NULL) {
3209		if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
3210		}
3211		else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
3212			pAC->GIni.GP[1].PFlowCtrlMode =
3213				SK_FLOW_MODE_SYM_OR_REM;
3214		}
3215		else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
3216			pAC->GIni.GP[1].PFlowCtrlMode =
3217				SK_FLOW_MODE_SYMMETRIC;
3218		}
3219		else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
3220			pAC->GIni.GP[1].PFlowCtrlMode =
3221				SK_FLOW_MODE_LOC_SEND;
3222		}
3223		else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
3224			pAC->GIni.GP[1].PFlowCtrlMode =
3225				SK_FLOW_MODE_NONE;
3226		}
3227		else printk("Illegal value for FlowCtrl_B\n");
3228	}
3229	if (AutoNeg==AN_OFF && pAC->GIni.GP[1].PFlowCtrlMode!=
3230		SK_FLOW_MODE_NONE) {
3231		printk("%s, Port B: FlowControl"
3232			" impossible without AutoNegotiation,"
3233			" disabled\n", pAC->dev[1]->name);
3234		pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE;
3235	}
3236
3237	MSMode = SK_MS_MODE_AUTO; /* default: do auto select */
3238	if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3239		Role_B[pAC->Index] != NULL) {
3240		if (strcmp(Role_B[pAC->Index],"")==0) {
3241		}
3242		else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
3243			MSMode = SK_MS_MODE_AUTO;
3244		}
3245		else if (strcmp(Role_B[pAC->Index],"Master")==0) {
3246			MSMode = SK_MS_MODE_MASTER;
3247		}
3248		else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
3249			MSMode = SK_MS_MODE_SLAVE;
3250		}
3251		else printk("%s: Illegal value for Role_B\n",
3252			pAC->dev[1]->name);
3253	}
3254	pAC->GIni.GP[1].PMSMode = MSMode;
3255
3256
3257	/* settings for both ports */
3258	pAC->ActivePort = 0;
3259	if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3260		PrefPort[pAC->Index] != NULL) {
3261		if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
3262			pAC->ActivePort = 0;
3263			pAC->Rlmt.Net[0].Preference = -1; /* auto */
3264			pAC->Rlmt.Net[0].PrefPort = 0;
3265		}
3266		else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
3267			/*
3268			 * do not set ActivePort here, thus a port
3269			 * switch is issued after net up.
3270			 */
3271			Port = 0;
3272			pAC->Rlmt.Net[0].Preference = Port;
3273			pAC->Rlmt.Net[0].PrefPort = Port;
3274		}
3275		else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
3276			/*
3277			 * do not set ActivePort here, thus a port
3278			 * switch is issued after net up.
3279			 */
3280			Port = 1;
3281			pAC->Rlmt.Net[0].Preference = Port;
3282			pAC->Rlmt.Net[0].PrefPort = Port;
3283		}
3284		else printk("%s: Illegal value for PrefPort\n",
3285			pAC->dev[0]->name);
3286	}
3287
3288	pAC->RlmtNets = 1;
3289
3290	if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3291		RlmtMode[pAC->Index] != NULL) {
3292		if (strcmp(RlmtMode[pAC->Index], "") == 0) {
3293			pAC->RlmtMode = 0;
3294		}
3295		else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
3296			pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3297		}
3298		else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
3299			pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3300				SK_RLMT_CHECK_LOC_LINK;
3301		}
3302		else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
3303			pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3304				SK_RLMT_CHECK_LOC_LINK |
3305				SK_RLMT_CHECK_SEG;
3306		}
3307		else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
3308			(pAC->GIni.GIMacsFound == 2)) {
3309				pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3310				pAC->RlmtNets = 2;
3311		}
3312		else {
3313			printk("%s: Illegal value for"
3314				" RlmtMode, using default\n", pAC->dev[0]->name);
3315
3316printk("MacFound = %d\nRlmtMode = %s", pAC->GIni.GIMacsFound, RlmtMode[pAC->Index]);
3317
3318
3319			pAC->RlmtMode = 0;
3320		}
3321	}
3322	else {
3323		pAC->RlmtMode = 0;
3324	}
3325} /* GetConfiguration */
3326
3327
3328/*****************************************************************************
3329 *
3330 * 	ProductStr - return a adapter identification string from vpd
3331 *
3332 * Description:
3333 *	This function reads the product name string from the vpd area
3334 *	and puts it the field pAC->DeviceString.
3335 *
3336 * Returns: N/A
3337 */
3338static void ProductStr(
3339SK_AC	*pAC		/* pointer to adapter context */
3340)
3341{
3342int	StrLen = 80;		/* length of the string, defined in SK_AC */
3343char	Keyword[] = VPD_NAME;	/* vpd productname identifier */
3344int	ReturnCode;		/* return code from vpd_read */
3345unsigned long Flags;
3346
3347	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3348	ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
3349		&StrLen);
3350	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3351	if (ReturnCode != 0) {
3352		/* there was an error reading the vpd data */
3353		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
3354			("Error reading VPD data: %d\n", ReturnCode));
3355		pAC->DeviceStr[0] = '\0';
3356	}
3357} /* ProductStr */
3358
3359
3360
3361
3362/****************************************************************************/
3363/* functions for common modules *********************************************/
3364/****************************************************************************/
3365
3366
3367/*****************************************************************************
3368 *
3369 *	SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
3370 *
3371 * Description:
3372 *	This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
3373 *	is embedded into a socket buff data area.
3374 *
3375 * Context:
3376 *	runtime
3377 *
3378 * Returns:
3379 *	NULL or pointer to Mbuf.
3380 */
3381SK_MBUF *SkDrvAllocRlmtMbuf(
3382SK_AC		*pAC,		/* pointer to adapter context */
3383SK_IOC		IoC,		/* the IO-context */
3384unsigned	BufferSize)	/* size of the requested buffer */
3385{
3386SK_MBUF		*pRlmtMbuf;	/* pointer to a new rlmt-mbuf structure */
3387struct sk_buff	*pMsgBlock;	/* pointer to a new message block */
3388
3389	pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
3390	if (pMsgBlock == NULL) {
3391		return (NULL);
3392	}
3393	pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
3394	skb_reserve(pMsgBlock, sizeof(SK_MBUF));
3395	pRlmtMbuf->pNext = NULL;
3396	pRlmtMbuf->pOs = pMsgBlock;
3397	pRlmtMbuf->pData = pMsgBlock->data;	/* Data buffer. */
3398	pRlmtMbuf->Size = BufferSize;		/* Data buffer size. */
3399	pRlmtMbuf->Length = 0;		/* Length of packet (<= Size). */
3400	return (pRlmtMbuf);
3401
3402} /* SkDrvAllocRlmtMbuf */
3403
3404
3405/*****************************************************************************
3406 *
3407 *	SkDrvFreeRlmtMbuf - free an RLMT mbuf
3408 *
3409 * Description:
3410 *	This routine frees one or more RLMT mbuf(s).
3411 *
3412 * Context:
3413 *	runtime
3414 *
3415 * Returns:
3416 *	Nothing
3417 */
3418void  SkDrvFreeRlmtMbuf(
3419SK_AC		*pAC,		/* pointer to adapter context */
3420SK_IOC		IoC,		/* the IO-context */
3421SK_MBUF		*pMbuf)		/* size of the requested buffer */
3422{
3423SK_MBUF		*pFreeMbuf;
3424SK_MBUF		*pNextMbuf;
3425
3426	pFreeMbuf = pMbuf;
3427	do {
3428		pNextMbuf = pFreeMbuf->pNext;
3429		DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
3430		pFreeMbuf = pNextMbuf;
3431	} while ( pFreeMbuf != NULL );
3432} /* SkDrvFreeRlmtMbuf */
3433
3434
3435/*****************************************************************************
3436 *
3437 *	SkOsGetTime - provide a time value
3438 *
3439 * Description:
3440 *	This routine provides a time value. The unit is 1/HZ (defined by Linux).
3441 *	It is not used for absolute time, but only for time differences.
3442 *
3443 *
3444 * Returns:
3445 *	Time value
3446 */
3447SK_U64 SkOsGetTime(SK_AC *pAC)
3448{
3449	return jiffies;
3450} /* SkOsGetTime */
3451
3452
3453/*****************************************************************************
3454 *
3455 *	SkPciReadCfgDWord - read a 32 bit value from pci config space
3456 *
3457 * Description:
3458 *	This routine reads a 32 bit value from the pci configuration
3459 *	space.
3460 *
3461 * Returns:
3462 *	0 - indicate everything worked ok.
3463 *	!= 0 - error indication
3464 */
3465int SkPciReadCfgDWord(
3466SK_AC *pAC,		/* Adapter Control structure pointer */
3467int PciAddr,		/* PCI register address */
3468SK_U32 *pVal)		/* pointer to store the read value */
3469{
3470	pci_read_config_dword(&pAC->PciDev, PciAddr, pVal);
3471	return(0);
3472} /* SkPciReadCfgDWord */
3473
3474
3475/*****************************************************************************
3476 *
3477 *	SkPciReadCfgWord - read a 16 bit value from pci config space
3478 *
3479 * Description:
3480 *	This routine reads a 16 bit value from the pci configuration
3481 *	space.
3482 *
3483 * Returns:
3484 *	0 - indicate everything worked ok.
3485 *	!= 0 - error indication
3486 */
3487int SkPciReadCfgWord(
3488SK_AC *pAC,	/* Adapter Control structure pointer */
3489int PciAddr,		/* PCI register address */
3490SK_U16 *pVal)		/* pointer to store the read value */
3491{
3492	pci_read_config_word(&pAC->PciDev, PciAddr, pVal);
3493	return(0);
3494} /* SkPciReadCfgWord */
3495
3496
3497/*****************************************************************************
3498 *
3499 *	SkPciReadCfgByte - read a 8 bit value from pci config space
3500 *
3501 * Description:
3502 *	This routine reads a 8 bit value from the pci configuration
3503 *	space.
3504 *
3505 * Returns:
3506 *	0 - indicate everything worked ok.
3507 *	!= 0 - error indication
3508 */
3509int SkPciReadCfgByte(
3510SK_AC *pAC,	/* Adapter Control structure pointer */
3511int PciAddr,		/* PCI register address */
3512SK_U8 *pVal)		/* pointer to store the read value */
3513{
3514	pci_read_config_byte(&pAC->PciDev, PciAddr, pVal);
3515	return(0);
3516} /* SkPciReadCfgByte */
3517
3518
3519/*****************************************************************************
3520 *
3521 *	SkPciWriteCfgDWord - write a 32 bit value to pci config space
3522 *
3523 * Description:
3524 *	This routine writes a 32 bit value to the pci configuration
3525 *	space.
3526 *
3527 * Returns:
3528 *	0 - indicate everything worked ok.
3529 *	!= 0 - error indication
3530 */
3531int SkPciWriteCfgDWord(
3532SK_AC *pAC,	/* Adapter Control structure pointer */
3533int PciAddr,		/* PCI register address */
3534SK_U32 Val)		/* pointer to store the read value */
3535{
3536	pci_write_config_dword(&pAC->PciDev, PciAddr, Val);
3537	return(0);
3538} /* SkPciWriteCfgDWord */
3539
3540
3541/*****************************************************************************
3542 *
3543 *	SkPciWriteCfgWord - write a 16 bit value to pci config space
3544 *
3545 * Description:
3546 *	This routine writes a 16 bit value to the pci configuration
3547 *	space. The flag PciConfigUp indicates whether the config space
3548 *	is accesible or must be set up first.
3549 *
3550 * Returns:
3551 *	0 - indicate everything worked ok.
3552 *	!= 0 - error indication
3553 */
3554int SkPciWriteCfgWord(
3555SK_AC *pAC,	/* Adapter Control structure pointer */
3556int PciAddr,		/* PCI register address */
3557SK_U16 Val)		/* pointer to store the read value */
3558{
3559	pci_write_config_word(&pAC->PciDev, PciAddr, Val);
3560	return(0);
3561} /* SkPciWriteCfgWord */
3562
3563
3564/*****************************************************************************
3565 *
3566 *	SkPciWriteCfgWord - write a 8 bit value to pci config space
3567 *
3568 * Description:
3569 *	This routine writes a 8 bit value to the pci configuration
3570 *	space. The flag PciConfigUp indicates whether the config space
3571 *	is accesible or must be set up first.
3572 *
3573 * Returns:
3574 *	0 - indicate everything worked ok.
3575 *	!= 0 - error indication
3576 */
3577int SkPciWriteCfgByte(
3578SK_AC *pAC,	/* Adapter Control structure pointer */
3579int PciAddr,		/* PCI register address */
3580SK_U8 Val)		/* pointer to store the read value */
3581{
3582	pci_write_config_byte(&pAC->PciDev, PciAddr, Val);
3583	return(0);
3584} /* SkPciWriteCfgByte */
3585
3586
3587/*****************************************************************************
3588 *
3589 *	SkDrvEvent - handle driver events
3590 *
3591 * Description:
3592 *	This function handles events from all modules directed to the driver
3593 *
3594 * Context:
3595 *	Is called under protection of slow path lock.
3596 *
3597 * Returns:
3598 *	0 if everything ok
3599 *	< 0  on error
3600 *
3601 */
3602int SkDrvEvent(
3603SK_AC *pAC,		/* pointer to adapter context */
3604SK_IOC IoC,		/* io-context */
3605SK_U32 Event,		/* event-id */
3606SK_EVPARA Param)	/* event-parameter */
3607{
3608SK_MBUF		*pRlmtMbuf;	/* pointer to a rlmt-mbuf structure */
3609struct sk_buff	*pMsg;		/* pointer to a message block */
3610int		FromPort;	/* the port from which we switch away */
3611int		ToPort;		/* the port we switch to */
3612SK_EVPARA	NewPara;	/* parameter for further events */
3613int		Stat;
3614unsigned long	Flags;
3615
3616	switch (Event) {
3617	case SK_DRV_ADAP_FAIL:
3618		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3619			("ADAPTER FAIL EVENT\n"));
3620		printk("%s: Adapter failed.\n", pAC->dev[0]->name);
3621		/* disable interrupts */
3622		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
3623		/* cgoos */
3624		break;
3625	case SK_DRV_PORT_FAIL:
3626		FromPort = Param.Para32[0];
3627		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3628			("PORT FAIL EVENT, Port: %d\n", FromPort));
3629		if (FromPort == 0) {
3630			printk("%s: Port A failed.\n", pAC->dev[0]->name);
3631		} else {
3632			printk("%s: Port B failed.\n", pAC->dev[1]->name);
3633		}
3634		/* cgoos */
3635		break;
3636	case SK_DRV_PORT_RESET:	 /* SK_U32 PortIdx */
3637		/* action list 4 */
3638		FromPort = Param.Para32[0];
3639		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3640			("PORT RESET EVENT, Port: %d ", FromPort));
3641		NewPara.Para64 = FromPort;
3642		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
3643		spin_lock_irqsave(
3644			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3645			Flags);
3646		SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
3647		spin_unlock_irqrestore(
3648			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3649			Flags);
3650
3651		/* clear rx ring from received frames */
3652		ReceiveIrq(pAC, &pAC->RxPort[FromPort]);
3653
3654		ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
3655		spin_lock_irqsave(
3656			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3657			Flags);
3658		SkGeInitPort(pAC, IoC, FromPort);
3659		SkAddrMcUpdate(pAC,IoC, FromPort);
3660		PortReInitBmu(pAC, FromPort);
3661		SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
3662		ClearAndStartRx(pAC, FromPort);
3663		spin_unlock_irqrestore(
3664			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3665			Flags);
3666		break;
3667	case SK_DRV_NET_UP:	 /* SK_U32 PortIdx */
3668		/* action list 5 */
3669		FromPort = Param.Para32[0];
3670		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3671			("NET UP EVENT, Port: %d ", Param.Para32[0]));
3672		printk("%s: network connection up using"
3673			" port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
3674		printk("    speed:           1000\n");
3675		Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
3676		if (Stat == SK_LMODE_STAT_AUTOHALF ||
3677			Stat == SK_LMODE_STAT_AUTOFULL) {
3678			printk("    autonegotiation: yes\n");
3679		}
3680		else {
3681			printk("    autonegotiation: no\n");
3682		}
3683		if (Stat == SK_LMODE_STAT_AUTOHALF ||
3684			Stat == SK_LMODE_STAT_HALF) {
3685			printk("    duplex mode:     half\n");
3686		}
3687		else {
3688			printk("    duplex mode:     full\n");
3689		}
3690		Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
3691		if (Stat == SK_FLOW_STAT_REM_SEND ) {
3692			printk("    flowctrl:        remote send\n");
3693		}
3694		else if (Stat == SK_FLOW_STAT_LOC_SEND ){
3695			printk("    flowctrl:        local send\n");
3696		}
3697		else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
3698			printk("    flowctrl:        symmetric\n");
3699		}
3700		else {
3701			printk("    flowctrl:        none\n");
3702		}
3703		if (pAC->GIni.GP[FromPort].PhyType != SK_PHY_XMAC) {
3704		Stat = pAC->GIni.GP[FromPort].PMSStatus;
3705			if (Stat == SK_MS_STAT_MASTER ) {
3706				printk("    role:            master\n");
3707			}
3708			else if (Stat == SK_MS_STAT_SLAVE ) {
3709				printk("    role:            slave\n");
3710			}
3711			else {
3712				printk("    role:            ???\n");
3713			}
3714		}
3715
3716		if ((Param.Para32[0] != pAC->ActivePort) &&
3717			(pAC->RlmtNets == 1)) {
3718			NewPara.Para32[0] = pAC->ActivePort;
3719			NewPara.Para32[1] = Param.Para32[0];
3720			SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
3721				NewPara);
3722		}
3723		break;
3724	case SK_DRV_NET_DOWN:	 /* SK_U32 Reason */
3725		/* action list 7 */
3726		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3727			("NET DOWN EVENT "));
3728		printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
3729		break;
3730	case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
3731		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3732			("PORT SWITCH HARD "));
3733	case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
3734	/* action list 6 */
3735		printk("%s: switching to port %c\n", pAC->dev[0]->name,
3736			'A'+Param.Para32[1]);
3737	case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
3738		FromPort = Param.Para32[0];
3739		ToPort = Param.Para32[1];
3740		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3741			("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
3742			FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
3743		NewPara.Para64 = FromPort;
3744		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
3745		NewPara.Para64 = ToPort;
3746		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
3747		spin_lock_irqsave(
3748			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3749			Flags);
3750		spin_lock_irqsave(
3751			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
3752		SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
3753		SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
3754		spin_unlock_irqrestore(
3755			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
3756		spin_unlock_irqrestore(
3757			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3758			Flags);
3759
3760		ReceiveIrq(pAC, &pAC->RxPort[FromPort]); /* clears rx ring */
3761		ReceiveIrq(pAC, &pAC->RxPort[ToPort]); /* clears rx ring */
3762
3763		ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
3764		ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
3765		spin_lock_irqsave(
3766			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3767			Flags);
3768		spin_lock_irqsave(
3769			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
3770		pAC->ActivePort = ToPort;
3771		SetQueueSizes(pAC);
3772		SkGeInitPort(pAC, IoC, FromPort);
3773		SkGeInitPort(pAC, IoC, ToPort);
3774		if (Event == SK_DRV_SWITCH_SOFT) {
3775			SkXmRxTxEnable(pAC, IoC, FromPort);
3776		}
3777		SkXmRxTxEnable(pAC, IoC, ToPort);
3778		SkAddrSwap(pAC, IoC, FromPort, ToPort);
3779		SkAddrMcUpdate(pAC, IoC, FromPort);
3780		SkAddrMcUpdate(pAC, IoC, ToPort);
3781		PortReInitBmu(pAC, FromPort);
3782		PortReInitBmu(pAC, ToPort);
3783		SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
3784		SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
3785		ClearAndStartRx(pAC, FromPort);
3786		ClearAndStartRx(pAC, ToPort);
3787		spin_unlock_irqrestore(
3788			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
3789		spin_unlock_irqrestore(
3790			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
3791			Flags);
3792		break;
3793	case SK_DRV_RLMT_SEND:	 /* SK_MBUF *pMb */
3794		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3795			("RLS "));
3796		pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
3797		pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
3798		skb_put(pMsg, pRlmtMbuf->Length);
3799		if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
3800			      pMsg) < 0)
3801			DEV_KFREE_SKB_ANY(pMsg);
3802		break;
3803	default:
3804		break;
3805	}
3806	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
3807		("END EVENT "));
3808
3809	return (0);
3810} /* SkDrvEvent */
3811
3812
3813/*****************************************************************************
3814 *
3815 *	SkErrorLog - log errors
3816 *
3817 * Description:
3818 *	This function logs errors to the system buffer and to the console
3819 *
3820 * Returns:
3821 *	0 if everything ok
3822 *	< 0  on error
3823 *
3824 */
3825void SkErrorLog(
3826SK_AC	*pAC,
3827int	ErrClass,
3828int	ErrNum,
3829char	*pErrorMsg)
3830{
3831char	ClassStr[80];
3832
3833	switch (ErrClass) {
3834	case SK_ERRCL_OTHER:
3835		strcpy(ClassStr, "Other error");
3836		break;
3837	case SK_ERRCL_CONFIG:
3838		strcpy(ClassStr, "Configuration error");
3839		break;
3840	case SK_ERRCL_INIT:
3841		strcpy(ClassStr, "Initialization error");
3842		break;
3843	case SK_ERRCL_NORES:
3844		strcpy(ClassStr, "Out of resources error");
3845		break;
3846	case SK_ERRCL_SW:
3847		strcpy(ClassStr, "internal Software error");
3848		break;
3849	case SK_ERRCL_HW:
3850		strcpy(ClassStr, "Hardware failure");
3851		break;
3852	case SK_ERRCL_COMM:
3853		strcpy(ClassStr, "Communication error");
3854		break;
3855	}
3856	printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
3857		"        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
3858		ClassStr, ErrNum, pErrorMsg);
3859
3860} /* SkErrorLog */
3861
3862#ifdef DEBUG     /***************************************************************/
3863/* "debug only" section *****************************************************/
3864/****************************************************************************/
3865
3866
3867/*****************************************************************************
3868 *
3869 *	DumpMsg - print a frame
3870 *
3871 * Description:
3872 *	This function prints frames to the system logfile/to the console.
3873 *
3874 * Returns: N/A
3875 *
3876 */
3877static void DumpMsg(struct sk_buff *skb, char *str)
3878{
3879	int	msglen;
3880
3881	if (skb == NULL) {
3882		printk("DumpMsg(): NULL-Message\n");
3883		return;
3884	}
3885
3886	if (skb->data == NULL) {
3887		printk("DumpMsg(): Message empty\n");
3888		return;
3889	}
3890
3891	msglen = skb->len;
3892	if (msglen > 64)
3893		msglen = 64;
3894
3895	printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
3896
3897	DumpData((char *)skb->data, msglen);
3898
3899	printk("------- End of message ---------\n");
3900} /* DumpMsg */
3901
3902
3903
3904/*****************************************************************************
3905 *
3906 *	DumpData - print a data area
3907 *
3908 * Description:
3909 *	This function prints a area of data to the system logfile/to the
3910 *	console.
3911 *
3912 * Returns: N/A
3913 *
3914 */
3915static void DumpData(char *p, int size)
3916{
3917register int    i;
3918int	haddr, addr;
3919char	hex_buffer[180];
3920char	asc_buffer[180];
3921char	HEXCHAR[] = "0123456789ABCDEF";
3922
3923	addr = 0;
3924	haddr = 0;
3925	hex_buffer[0] = 0;
3926	asc_buffer[0] = 0;
3927	for (i=0; i < size; ) {
3928		if (*p >= '0' && *p <='z')
3929			asc_buffer[addr] = *p;
3930		else
3931			asc_buffer[addr] = '.';
3932		addr++;
3933		asc_buffer[addr] = 0;
3934		hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
3935		haddr++;
3936		hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
3937		haddr++;
3938		hex_buffer[haddr] = ' ';
3939		haddr++;
3940		hex_buffer[haddr] = 0;
3941		p++;
3942		i++;
3943		if (i%16 == 0) {
3944			printk("%s  %s\n", hex_buffer, asc_buffer);
3945			addr = 0;
3946			haddr = 0;
3947		}
3948	}
3949} /* DumpData */
3950
3951
3952/*****************************************************************************
3953 *
3954 *	DumpLong - print a data area as long values
3955 *
3956 * Description:
3957 *	This function prints a area of data to the system logfile/to the
3958 *	console.
3959 *
3960 * Returns: N/A
3961 *
3962 */
3963static void DumpLong(char *pc, int size)
3964{
3965register int    i;
3966int	haddr, addr;
3967char	hex_buffer[180];
3968char	asc_buffer[180];
3969char	HEXCHAR[] = "0123456789ABCDEF";
3970long	*p;
3971int	l;
3972
3973	addr = 0;
3974	haddr = 0;
3975	hex_buffer[0] = 0;
3976	asc_buffer[0] = 0;
3977	p = (long*) pc;
3978	for (i=0; i < size; ) {
3979		l = (long) *p;
3980		hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
3981		haddr++;
3982		hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
3983		haddr++;
3984		hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
3985		haddr++;
3986		hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
3987		haddr++;
3988		hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
3989		haddr++;
3990		hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
3991		haddr++;
3992		hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
3993		haddr++;
3994		hex_buffer[haddr] = HEXCHAR[l & 0x0f];
3995		haddr++;
3996		hex_buffer[haddr] = ' ';
3997		haddr++;
3998		hex_buffer[haddr] = 0;
3999		p++;
4000		i++;
4001		if (i%8 == 0) {
4002			printk("%4x %s\n", (i-8)*4, hex_buffer);
4003			haddr = 0;
4004		}
4005	}
4006	printk("------------------------\n");
4007} /* DumpLong */
4008
4009#endif /* DEBUG */
4010
4011/*
4012 * Local variables:
4013 * compile-command: "make"
4014 * End:
4015 */
4016
4017