[PATCH] drivers/net/sk98lin/skge.c: make SkPciWriteCfgDWord() a static inline
[linux-2.6.git] / drivers / net / sk98lin / skge.c
1 /******************************************************************************
2  *
3  * Name:        skge.c
4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
5  * Version:     $Revision: 1.45 $
6  * Date:        $Date: 2004/02/12 14:41:02 $
7  * Purpose:     The main driver source module
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2002 SysKonnect GmbH.
14  *      (C)Copyright 2002-2003 Marvell.
15  *
16  *      Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
17  *      Server Adapters.
18  *
19  *      Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
20  *      SysKonnects GEnesis Solaris driver
21  *      Author: Christoph Goos (cgoos@syskonnect.de)
22  *              Mirko Lindner (mlindner@syskonnect.de)
23  *
24  *      Address all question to: linux@syskonnect.de
25  *
26  *      The technical manual for the adapters is available from SysKonnect's
27  *      web pages: www.syskonnect.com
28  *      Goto "Support" and search Knowledge Base for "manual".
29  *      
30  *      This program is free software; you can redistribute it and/or modify
31  *      it under the terms of the GNU General Public License as published by
32  *      the Free Software Foundation; either version 2 of the License, or
33  *      (at your option) any later version.
34  *
35  *      The information in this file is provided "AS IS" without warranty.
36  *
37  ******************************************************************************/
38
39 /******************************************************************************
40  *
41  * Possible compiler options (#define xxx / -Dxxx):
42  *
43  *      debugging can be enable by changing SK_DEBUG_CHKMOD and
44  *      SK_DEBUG_CHKCAT in makefile (described there).
45  *
46  ******************************************************************************/
47
48 /******************************************************************************
49  *
50  * Description:
51  *
52  *      This is the main module of the Linux GE driver.
53  *      
54  *      All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
55  *      are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
56  *      Those are used for drivers on multiple OS', so some thing may seem
57  *      unnecessary complicated on Linux. Please do not try to 'clean up'
58  *      them without VERY good reasons, because this will make it more
59  *      difficult to keep the Linux driver in synchronisation with the
60  *      other versions.
61  *
62  * Include file hierarchy:
63  *
64  *      <linux/module.h>
65  *
66  *      "h/skdrv1st.h"
67  *              <linux/types.h>
68  *              <linux/kernel.h>
69  *              <linux/string.h>
70  *              <linux/errno.h>
71  *              <linux/ioport.h>
72  *              <linux/slab.h>
73  *              <linux/interrupt.h>
74  *              <linux/pci.h>
75  *              <linux/bitops.h>
76  *              <asm/byteorder.h>
77  *              <asm/io.h>
78  *              <linux/netdevice.h>
79  *              <linux/etherdevice.h>
80  *              <linux/skbuff.h>
81  *          those three depending on kernel version used:
82  *              <linux/bios32.h>
83  *              <linux/init.h>
84  *              <asm/uaccess.h>
85  *              <net/checksum.h>
86  *
87  *              "h/skerror.h"
88  *              "h/skdebug.h"
89  *              "h/sktypes.h"
90  *              "h/lm80.h"
91  *              "h/xmac_ii.h"
92  *
93  *      "h/skdrv2nd.h"
94  *              "h/skqueue.h"
95  *              "h/skgehwt.h"
96  *              "h/sktimer.h"
97  *              "h/ski2c.h"
98  *              "h/skgepnmi.h"
99  *              "h/skvpd.h"
100  *              "h/skgehw.h"
101  *              "h/skgeinit.h"
102  *              "h/skaddr.h"
103  *              "h/skgesirq.h"
104  *              "h/skcsum.h"
105  *              "h/skrlmt.h"
106  *
107  ******************************************************************************/
108
109 #include        "h/skversion.h"
110
111 #include        <linux/module.h>
112 #include        <linux/moduleparam.h>
113 #include        <linux/init.h>
114 #include        <linux/proc_fs.h>
115 #include        <linux/dma-mapping.h>
116
117 #include        "h/skdrv1st.h"
118 #include        "h/skdrv2nd.h"
119
120 /*******************************************************************************
121  *
122  * Defines
123  *
124  ******************************************************************************/
125
126 /* for debuging on x86 only */
127 /* #define BREAKPOINT() asm(" int $3"); */
128
129 /* use the transmit hw checksum driver functionality */
130 #define USE_SK_TX_CHECKSUM
131
132 /* use the receive hw checksum driver functionality */
133 #define USE_SK_RX_CHECKSUM
134
135 /* use the scatter-gather functionality with sendfile() */
136 #define SK_ZEROCOPY
137
138 /* use of a transmit complete interrupt */
139 #define USE_TX_COMPLETE
140
141 /*
142  * threshold for copying small receive frames
143  * set to 0 to avoid copying, set to 9001 to copy all frames
144  */
145 #define SK_COPY_THRESHOLD       50
146
147 /* number of adapters that can be configured via command line params */
148 #define SK_MAX_CARD_PARAM       16
149
150
151
152 /*
153  * use those defines for a compile-in version of the driver instead
154  * of command line parameters
155  */
156 // #define LINK_SPEED_A {"Auto", }
157 // #define LINK_SPEED_B {"Auto", }
158 // #define AUTO_NEG_A   {"Sense", }
159 // #define AUTO_NEG_B   {"Sense", }
160 // #define DUP_CAP_A    {"Both", }
161 // #define DUP_CAP_B    {"Both", }
162 // #define FLOW_CTRL_A  {"SymOrRem", }
163 // #define FLOW_CTRL_B  {"SymOrRem", }
164 // #define ROLE_A       {"Auto", }
165 // #define ROLE_B       {"Auto", }
166 // #define PREF_PORT    {"A", }
167 // #define CON_TYPE     {"Auto", }
168 // #define RLMT_MODE    {"CheckLinkState", }
169
170 #define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
171 #define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
172 #define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
173
174
175 /* Set blink mode*/
176 #define OEM_CONFIG_VALUE (      SK_ACT_LED_BLINK | \
177                                 SK_DUP_LED_NORMAL | \
178                                 SK_LED_LINK100_ON)
179
180
181 /* Isr return value */
182 #define SkIsrRetVar     irqreturn_t
183 #define SkIsrRetNone    IRQ_NONE
184 #define SkIsrRetHandled IRQ_HANDLED
185
186
187 /*******************************************************************************
188  *
189  * Local Function Prototypes
190  *
191  ******************************************************************************/
192
193 static void     FreeResources(struct SK_NET_DEVICE *dev);
194 static int      SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
195 static SK_BOOL  BoardAllocMem(SK_AC *pAC);
196 static void     BoardFreeMem(SK_AC *pAC);
197 static void     BoardInitMem(SK_AC *pAC);
198 static void     SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
199 static SkIsrRetVar      SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
200 static SkIsrRetVar      SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
201 static int      SkGeOpen(struct SK_NET_DEVICE *dev);
202 static int      SkGeClose(struct SK_NET_DEVICE *dev);
203 static int      SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
204 static int      SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
205 static void     SkGeSetRxMode(struct SK_NET_DEVICE *dev);
206 static struct   net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
207 static int      SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
208 static void     GetConfiguration(SK_AC*);
209 static void     ProductStr(SK_AC*);
210 static int      XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
211 static void     FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
212 static void     FillRxRing(SK_AC*, RX_PORT*);
213 static SK_BOOL  FillRxDescriptor(SK_AC*, RX_PORT*);
214 static void     ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
215 static void     ClearAndStartRx(SK_AC*, int);
216 static void     ClearTxIrq(SK_AC*, int, int);
217 static void     ClearRxRing(SK_AC*, RX_PORT*);
218 static void     ClearTxRing(SK_AC*, TX_PORT*);
219 static int      SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
220 static void     PortReInitBmu(SK_AC*, int);
221 static int      SkGeIocMib(DEV_NET*, unsigned int, int);
222 static int      SkGeInitPCI(SK_AC *pAC);
223 static void     StartDrvCleanupTimer(SK_AC *pAC);
224 static void     StopDrvCleanupTimer(SK_AC *pAC);
225 static int      XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
226
227 #ifdef SK_DIAG_SUPPORT
228 static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
229 static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
230 static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
231 #endif
232
233 /*******************************************************************************
234  *
235  * Extern Function Prototypes
236  *
237  ******************************************************************************/
238 static const char       SKRootName[] = "net/sk98lin";
239 static struct           proc_dir_entry *pSkRootDir;
240 extern struct   file_operations sk_proc_fops;
241
242 static inline void SkGeProcCreate(struct net_device *dev)
243 {
244         struct proc_dir_entry *pe;
245
246         if (pSkRootDir && 
247             (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
248                 pe->proc_fops = &sk_proc_fops;
249                 pe->data = dev;
250                 pe->owner = THIS_MODULE;
251         }
252 }
253  
254 static inline void SkGeProcRemove(struct net_device *dev)
255 {
256         if (pSkRootDir)
257                 remove_proc_entry(dev->name, pSkRootDir);
258 }
259
260 extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);  
261 extern void SkDimDisplayModerationSettings(SK_AC *pAC);
262 extern void SkDimStartModerationTimer(SK_AC *pAC);
263 extern void SkDimModerate(SK_AC *pAC);
264 extern void SkGeBlinkTimer(unsigned long data);
265
266 #ifdef DEBUG
267 static void     DumpMsg(struct sk_buff*, char*);
268 static void     DumpData(char*, int);
269 static void     DumpLong(char*, int);
270 #endif
271
272 /* global variables *********************************************************/
273 static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
274 extern  struct ethtool_ops SkGeEthtoolOps;
275
276 /* local variables **********************************************************/
277 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
278 static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
279
280 /*****************************************************************************
281  *
282  *      SkPciWriteCfgDWord - write a 32 bit value to pci config space
283  *
284  * Description:
285  *      This routine writes a 32 bit value to the pci configuration
286  *      space.
287  *
288  * Returns:
289  *      0 - indicate everything worked ok.
290  *      != 0 - error indication
291  */
292 static inline int SkPciWriteCfgDWord(
293 SK_AC *pAC,     /* Adapter Control structure pointer */
294 int PciAddr,            /* PCI register address */
295 SK_U32 Val)             /* pointer to store the read value */
296 {
297         pci_write_config_dword(pAC->PciDev, PciAddr, Val);
298         return(0);
299 } /* SkPciWriteCfgDWord */
300
301 /*****************************************************************************
302  *
303  *      SkGeInitPCI - Init the PCI resources
304  *
305  * Description:
306  *      This function initialize the PCI resources and IO
307  *
308  * Returns: N/A
309  *      
310  */
311 int SkGeInitPCI(SK_AC *pAC)
312 {
313         struct SK_NET_DEVICE *dev = pAC->dev[0];
314         struct pci_dev *pdev = pAC->PciDev;
315         int retval;
316
317         if (pci_enable_device(pdev) != 0) {
318                 return 1;
319         }
320
321         dev->mem_start = pci_resource_start (pdev, 0);
322         pci_set_master(pdev);
323
324         if (pci_request_regions(pdev, pAC->Name) != 0) {
325                 retval = 2;
326                 goto out_disable;
327         }
328
329 #ifdef SK_BIG_ENDIAN
330         /*
331          * On big endian machines, we use the adapter's aibility of
332          * reading the descriptors as big endian.
333          */
334         {
335                 SK_U32          our2;
336                 SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
337                 our2 |= PCI_REV_DESC;
338                 SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
339         }
340 #endif
341
342         /*
343          * Remap the regs into kernel space.
344          */
345         pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
346
347         if (!pAC->IoBase){
348                 retval = 3;
349                 goto out_release;
350         }
351
352         return 0;
353
354  out_release:
355         pci_release_regions(pdev);
356  out_disable:
357         pci_disable_device(pdev);
358         return retval;
359 }
360
361
362 /*****************************************************************************
363  *
364  *      FreeResources - release resources allocated for adapter
365  *
366  * Description:
367  *      This function releases the IRQ, unmaps the IO and
368  *      frees the desriptor ring.
369  *
370  * Returns: N/A
371  *      
372  */
373 static void FreeResources(struct SK_NET_DEVICE *dev)
374 {
375 SK_U32 AllocFlag;
376 DEV_NET         *pNet;
377 SK_AC           *pAC;
378
379         pNet = netdev_priv(dev);
380         pAC = pNet->pAC;
381         AllocFlag = pAC->AllocFlag;
382         if (pAC->PciDev) {
383                 pci_release_regions(pAC->PciDev);
384         }
385         if (AllocFlag & SK_ALLOC_IRQ) {
386                 free_irq(dev->irq, dev);
387         }
388         if (pAC->IoBase) {
389                 iounmap(pAC->IoBase);
390         }
391         if (pAC->pDescrMem) {
392                 BoardFreeMem(pAC);
393         }
394         
395 } /* FreeResources */
396
397 MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
398 MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
399 MODULE_LICENSE("GPL");
400
401 #ifdef LINK_SPEED_A
402 static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
403 #else
404 static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
405 #endif
406
407 #ifdef LINK_SPEED_B
408 static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
409 #else
410 static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
411 #endif
412
413 #ifdef AUTO_NEG_A
414 static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
415 #else
416 static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
417 #endif
418
419 #ifdef DUP_CAP_A
420 static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
421 #else
422 static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
423 #endif
424
425 #ifdef FLOW_CTRL_A
426 static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
427 #else
428 static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
429 #endif
430
431 #ifdef ROLE_A
432 static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
433 #else
434 static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
435 #endif
436
437 #ifdef AUTO_NEG_B
438 static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
439 #else
440 static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
441 #endif
442
443 #ifdef DUP_CAP_B
444 static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
445 #else
446 static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
447 #endif
448
449 #ifdef FLOW_CTRL_B
450 static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
451 #else
452 static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
453 #endif
454
455 #ifdef ROLE_B
456 static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
457 #else
458 static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
459 #endif
460
461 #ifdef CON_TYPE
462 static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
463 #else
464 static char *ConType[SK_MAX_CARD_PARAM] = {"", };
465 #endif
466
467 #ifdef PREF_PORT
468 static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
469 #else
470 static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
471 #endif
472
473 #ifdef RLMT_MODE
474 static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
475 #else
476 static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
477 #endif
478
479 static int   IntsPerSec[SK_MAX_CARD_PARAM];
480 static char *Moderation[SK_MAX_CARD_PARAM];
481 static char *ModerationMask[SK_MAX_CARD_PARAM];
482 static char *AutoSizing[SK_MAX_CARD_PARAM];
483 static char *Stats[SK_MAX_CARD_PARAM];
484
485 module_param_array(Speed_A, charp, NULL, 0);
486 module_param_array(Speed_B, charp, NULL, 0);
487 module_param_array(AutoNeg_A, charp, NULL, 0);
488 module_param_array(AutoNeg_B, charp, NULL, 0);
489 module_param_array(DupCap_A, charp, NULL, 0);
490 module_param_array(DupCap_B, charp, NULL, 0);
491 module_param_array(FlowCtrl_A, charp, NULL, 0);
492 module_param_array(FlowCtrl_B, charp, NULL, 0);
493 module_param_array(Role_A, charp, NULL, 0);
494 module_param_array(Role_B, charp, NULL, 0);
495 module_param_array(ConType, charp, NULL, 0);
496 module_param_array(PrefPort, charp, NULL, 0);
497 module_param_array(RlmtMode, charp, NULL, 0);
498 /* used for interrupt moderation */
499 module_param_array(IntsPerSec, int, NULL, 0);
500 module_param_array(Moderation, charp, NULL, 0);
501 module_param_array(Stats, charp, NULL, 0);
502 module_param_array(ModerationMask, charp, NULL, 0);
503 module_param_array(AutoSizing, charp, NULL, 0);
504
505 /*****************************************************************************
506  *
507  *      SkGeBoardInit - do level 0 and 1 initialization
508  *
509  * Description:
510  *      This function prepares the board hardware for running. The desriptor
511  *      ring is set up, the IRQ is allocated and the configuration settings
512  *      are examined.
513  *
514  * Returns:
515  *      0, if everything is ok
516  *      !=0, on error
517  */
518 static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
519 {
520 short   i;
521 unsigned long Flags;
522 char    *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
523 char    *VerStr = VER_STRING;
524 int     Ret;                    /* return code of request_irq */
525 SK_BOOL DualNet;
526
527         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
528                 ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
529         for (i=0; i<SK_MAX_MACS; i++) {
530                 pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
531                 pAC->TxPort[i][0].PortIndex = i;
532                 pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
533                 pAC->RxPort[i].PortIndex = i;
534         }
535
536         /* Initialize the mutexes */
537         for (i=0; i<SK_MAX_MACS; i++) {
538                 spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
539                 spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
540         }
541         spin_lock_init(&pAC->SlowPathLock);
542
543         /* setup phy_id blink timer */
544         pAC->BlinkTimer.function = SkGeBlinkTimer;
545         pAC->BlinkTimer.data = (unsigned long) dev;
546         init_timer(&pAC->BlinkTimer);
547
548         /* level 0 init common modules here */
549         
550         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
551         /* Does a RESET on board ...*/
552         if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
553                 printk("HWInit (0) failed.\n");
554                 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
555                 return(-EAGAIN);
556         }
557         SkI2cInit(  pAC, pAC->IoBase, SK_INIT_DATA);
558         SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
559         SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
560         SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
561         SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
562         SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
563
564         pAC->BoardLevel = SK_INIT_DATA;
565         pAC->RxBufSize  = ETH_BUF_SIZE;
566
567         SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
568         SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
569
570         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
571
572         /* level 1 init common modules here (HW init) */
573         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
574         if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
575                 printk("sk98lin: HWInit (1) failed.\n");
576                 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
577                 return(-EAGAIN);
578         }
579         SkI2cInit(  pAC, pAC->IoBase, SK_INIT_IO);
580         SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
581         SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
582         SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
583         SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
584         SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
585
586         /* Set chipset type support */
587         pAC->ChipsetType = 0;
588         if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
589                 (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
590                 pAC->ChipsetType = 1;
591         }
592
593         GetConfiguration(pAC);
594         if (pAC->RlmtNets == 2) {
595                 pAC->GIni.GIPortUsage = SK_MUL_LINK;
596         }
597
598         pAC->BoardLevel = SK_INIT_IO;
599         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
600
601         if (pAC->GIni.GIMacsFound == 2) {
602                  Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
603         } else if (pAC->GIni.GIMacsFound == 1) {
604                 Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
605                         pAC->Name, dev);
606         } else {
607                 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
608                        pAC->GIni.GIMacsFound);
609                 return -EAGAIN;
610         }
611
612         if (Ret) {
613                 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
614                        dev->irq);
615                 return -EAGAIN;
616         }
617         pAC->AllocFlag |= SK_ALLOC_IRQ;
618
619         /* Alloc memory for this board (Mem for RxD/TxD) : */
620         if(!BoardAllocMem(pAC)) {
621                 printk("No memory for descriptor rings.\n");
622                 return(-EAGAIN);
623         }
624
625         SkCsSetReceiveFlags(pAC,
626                 SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
627                 &pAC->CsOfs1, &pAC->CsOfs2, 0);
628         pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
629
630         BoardInitMem(pAC);
631         /* tschilling: New common function with minimum size check. */
632         DualNet = SK_FALSE;
633         if (pAC->RlmtNets == 2) {
634                 DualNet = SK_TRUE;
635         }
636         
637         if (SkGeInitAssignRamToQueues(
638                 pAC,
639                 pAC->ActivePort,
640                 DualNet)) {
641                 BoardFreeMem(pAC);
642                 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
643                 return(-EAGAIN);
644         }
645
646         return (0);
647 } /* SkGeBoardInit */
648
649
650 /*****************************************************************************
651  *
652  *      BoardAllocMem - allocate the memory for the descriptor rings
653  *
654  * Description:
655  *      This function allocates the memory for all descriptor rings.
656  *      Each ring is aligned for the desriptor alignment and no ring
657  *      has a 4 GByte boundary in it (because the upper 32 bit must
658  *      be constant for all descriptiors in one rings).
659  *
660  * Returns:
661  *      SK_TRUE, if all memory could be allocated
662  *      SK_FALSE, if not
663  */
664 static SK_BOOL BoardAllocMem(
665 SK_AC   *pAC)
666 {
667 caddr_t         pDescrMem;      /* pointer to descriptor memory area */
668 size_t          AllocLength;    /* length of complete descriptor area */
669 int             i;              /* loop counter */
670 unsigned long   BusAddr;
671
672         
673         /* rings plus one for alignment (do not cross 4 GB boundary) */
674         /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
675 #if (BITS_PER_LONG == 32)
676         AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
677 #else
678         AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
679                 + RX_RING_SIZE + 8;
680 #endif
681
682         pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
683                                          &pAC->pDescrMemDMA);
684
685         if (pDescrMem == NULL) {
686                 return (SK_FALSE);
687         }
688         pAC->pDescrMem = pDescrMem;
689         BusAddr = (unsigned long) pAC->pDescrMemDMA;
690
691         /* Descriptors need 8 byte alignment, and this is ensured
692          * by pci_alloc_consistent.
693          */
694         for (i=0; i<pAC->GIni.GIMacsFound; i++) {
695                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
696                         ("TX%d/A: pDescrMem: %lX,   PhysDescrMem: %lX\n",
697                         i, (unsigned long) pDescrMem,
698                         BusAddr));
699                 pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
700                 pAC->TxPort[i][0].VTxDescrRing = BusAddr;
701                 pDescrMem += TX_RING_SIZE;
702                 BusAddr += TX_RING_SIZE;
703         
704                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
705                         ("RX%d: pDescrMem: %lX,   PhysDescrMem: %lX\n",
706                         i, (unsigned long) pDescrMem,
707                         (unsigned long)BusAddr));
708                 pAC->RxPort[i].pRxDescrRing = pDescrMem;
709                 pAC->RxPort[i].VRxDescrRing = BusAddr;
710                 pDescrMem += RX_RING_SIZE;
711                 BusAddr += RX_RING_SIZE;
712         } /* for */
713         
714         return (SK_TRUE);
715 } /* BoardAllocMem */
716
717
718 /****************************************************************************
719  *
720  *      BoardFreeMem - reverse of BoardAllocMem
721  *
722  * Description:
723  *      Free all memory allocated in BoardAllocMem: adapter context,
724  *      descriptor rings, locks.
725  *
726  * Returns:     N/A
727  */
728 static void BoardFreeMem(
729 SK_AC           *pAC)
730 {
731 size_t          AllocLength;    /* length of complete descriptor area */
732
733         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
734                 ("BoardFreeMem\n"));
735 #if (BITS_PER_LONG == 32)
736         AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
737 #else
738         AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
739                 + RX_RING_SIZE + 8;
740 #endif
741
742         pci_free_consistent(pAC->PciDev, AllocLength,
743                             pAC->pDescrMem, pAC->pDescrMemDMA);
744         pAC->pDescrMem = NULL;
745 } /* BoardFreeMem */
746
747
748 /*****************************************************************************
749  *
750  *      BoardInitMem - initiate the descriptor rings
751  *
752  * Description:
753  *      This function sets the descriptor rings up in memory.
754  *      The adapter is initialized with the descriptor start addresses.
755  *
756  * Returns:     N/A
757  */
758 static void BoardInitMem(
759 SK_AC   *pAC)   /* pointer to adapter context */
760 {
761 int     i;              /* loop counter */
762 int     RxDescrSize;    /* the size of a rx descriptor rounded up to alignment*/
763 int     TxDescrSize;    /* the size of a tx descriptor rounded up to alignment*/
764
765         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
766                 ("BoardInitMem\n"));
767
768         RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
769         pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
770         TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
771         pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
772         
773         for (i=0; i<pAC->GIni.GIMacsFound; i++) {
774                 SetupRing(
775                         pAC,
776                         pAC->TxPort[i][0].pTxDescrRing,
777                         pAC->TxPort[i][0].VTxDescrRing,
778                         (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
779                         (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
780                         (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
781                         &pAC->TxPort[i][0].TxdRingFree,
782                         SK_TRUE);
783                 SetupRing(
784                         pAC,
785                         pAC->RxPort[i].pRxDescrRing,
786                         pAC->RxPort[i].VRxDescrRing,
787                         &pAC->RxPort[i].pRxdRingHead,
788                         &pAC->RxPort[i].pRxdRingTail,
789                         &pAC->RxPort[i].pRxdRingPrev,
790                         &pAC->RxPort[i].RxdRingFree,
791                         SK_FALSE);
792         }
793 } /* BoardInitMem */
794
795
796 /*****************************************************************************
797  *
798  *      SetupRing - create one descriptor ring
799  *
800  * Description:
801  *      This function creates one descriptor ring in the given memory area.
802  *      The head, tail and number of free descriptors in the ring are set.
803  *
804  * Returns:
805  *      none
806  */
807 static void SetupRing(
808 SK_AC           *pAC,
809 void            *pMemArea,      /* a pointer to the memory area for the ring */
810 uintptr_t       VMemArea,       /* the virtual bus address of the memory area */
811 RXD             **ppRingHead,   /* address where the head should be written */
812 RXD             **ppRingTail,   /* address where the tail should be written */
813 RXD             **ppRingPrev,   /* address where the tail should be written */
814 int             *pRingFree,     /* address where the # of free descr. goes */
815 SK_BOOL         IsTx)           /* flag: is this a tx ring */
816 {
817 int     i;              /* loop counter */
818 int     DescrSize;      /* the size of a descriptor rounded up to alignment*/
819 int     DescrNum;       /* number of descriptors per ring */
820 RXD     *pDescr;        /* pointer to a descriptor (receive or transmit) */
821 RXD     *pNextDescr;    /* pointer to the next descriptor */
822 RXD     *pPrevDescr;    /* pointer to the previous descriptor */
823 uintptr_t VNextDescr;   /* the virtual bus address of the next descriptor */
824
825         if (IsTx == SK_TRUE) {
826                 DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
827                         DESCR_ALIGN;
828                 DescrNum = TX_RING_SIZE / DescrSize;
829         } else {
830                 DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
831                         DESCR_ALIGN;
832                 DescrNum = RX_RING_SIZE / DescrSize;
833         }
834         
835         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
836                 ("Descriptor size: %d   Descriptor Number: %d\n",
837                 DescrSize,DescrNum));
838         
839         pDescr = (RXD*) pMemArea;
840         pPrevDescr = NULL;
841         pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
842         VNextDescr = VMemArea + DescrSize;
843         for(i=0; i<DescrNum; i++) {
844                 /* set the pointers right */
845                 pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
846                 pDescr->pNextRxd = pNextDescr;
847                 pDescr->TcpSumStarts = pAC->CsOfs;
848
849                 /* advance one step */
850                 pPrevDescr = pDescr;
851                 pDescr = pNextDescr;
852                 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
853                 VNextDescr += DescrSize;
854         }
855         pPrevDescr->pNextRxd = (RXD*) pMemArea;
856         pPrevDescr->VNextRxd = VMemArea;
857         pDescr = (RXD*) pMemArea;
858         *ppRingHead = (RXD*) pMemArea;
859         *ppRingTail = *ppRingHead;
860         *ppRingPrev = pPrevDescr;
861         *pRingFree = DescrNum;
862 } /* SetupRing */
863
864
865 /*****************************************************************************
866  *
867  *      PortReInitBmu - re-initiate the descriptor rings for one port
868  *
869  * Description:
870  *      This function reinitializes the descriptor rings of one port
871  *      in memory. The port must be stopped before.
872  *      The HW is initialized with the descriptor start addresses.
873  *
874  * Returns:
875  *      none
876  */
877 static void PortReInitBmu(
878 SK_AC   *pAC,           /* pointer to adapter context */
879 int     PortIndex)      /* index of the port for which to re-init */
880 {
881         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
882                 ("PortReInitBmu "));
883
884         /* set address of first descriptor of ring in BMU */
885         SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
886                 (uint32_t)(((caddr_t)
887                 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
888                 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
889                 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
890                 0xFFFFFFFF));
891         SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
892                 (uint32_t)(((caddr_t)
893                 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
894                 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
895                 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
896         SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
897                 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
898                 pAC->RxPort[PortIndex].pRxDescrRing +
899                 pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
900         SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
901                 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
902                 pAC->RxPort[PortIndex].pRxDescrRing +
903                 pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
904 } /* PortReInitBmu */
905
906
907 /****************************************************************************
908  *
909  *      SkGeIsr - handle adapter interrupts
910  *
911  * Description:
912  *      The interrupt routine is called when the network adapter
913  *      generates an interrupt. It may also be called if another device
914  *      shares this interrupt vector with the driver.
915  *
916  * Returns: N/A
917  *
918  */
919 static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
920 {
921 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
922 DEV_NET         *pNet;
923 SK_AC           *pAC;
924 SK_U32          IntSrc;         /* interrupts source register contents */       
925
926         pNet = netdev_priv(dev);
927         pAC = pNet->pAC;
928         
929         /*
930          * Check and process if its our interrupt
931          */
932         SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
933         if (IntSrc == 0) {
934                 return SkIsrRetNone;
935         }
936
937         while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
938 #if 0 /* software irq currently not used */
939                 if (IntSrc & IS_IRQ_SW) {
940                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
941                                 SK_DBGCAT_DRV_INT_SRC,
942                                 ("Software IRQ\n"));
943                 }
944 #endif
945                 if (IntSrc & IS_R1_F) {
946                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
947                                 SK_DBGCAT_DRV_INT_SRC,
948                                 ("EOF RX1 IRQ\n"));
949                         ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
950                         SK_PNMI_CNT_RX_INTR(pAC, 0);
951                 }
952                 if (IntSrc & IS_R2_F) {
953                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
954                                 SK_DBGCAT_DRV_INT_SRC,
955                                 ("EOF RX2 IRQ\n"));
956                         ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
957                         SK_PNMI_CNT_RX_INTR(pAC, 1);
958                 }
959 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
960                 if (IntSrc & IS_XA1_F) {
961                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
962                                 SK_DBGCAT_DRV_INT_SRC,
963                                 ("EOF AS TX1 IRQ\n"));
964                         SK_PNMI_CNT_TX_INTR(pAC, 0);
965                         spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
966                         FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
967                         spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
968                 }
969                 if (IntSrc & IS_XA2_F) {
970                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
971                                 SK_DBGCAT_DRV_INT_SRC,
972                                 ("EOF AS TX2 IRQ\n"));
973                         SK_PNMI_CNT_TX_INTR(pAC, 1);
974                         spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
975                         FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
976                         spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
977                 }
978 #if 0 /* only if sync. queues used */
979                 if (IntSrc & IS_XS1_F) {
980                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
981                                 SK_DBGCAT_DRV_INT_SRC,
982                                 ("EOF SY TX1 IRQ\n"));
983                         SK_PNMI_CNT_TX_INTR(pAC, 1);
984                         spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
985                         FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
986                         spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
987                         ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
988                 }
989                 if (IntSrc & IS_XS2_F) {
990                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
991                                 SK_DBGCAT_DRV_INT_SRC,
992                                 ("EOF SY TX2 IRQ\n"));
993                         SK_PNMI_CNT_TX_INTR(pAC, 1);
994                         spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
995                         FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
996                         spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
997                         ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
998                 }
999 #endif
1000 #endif
1001
1002                 /* do all IO at once */
1003                 if (IntSrc & IS_R1_F)
1004                         ClearAndStartRx(pAC, 0);
1005                 if (IntSrc & IS_R2_F)
1006                         ClearAndStartRx(pAC, 1);
1007 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1008                 if (IntSrc & IS_XA1_F)
1009                         ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1010                 if (IntSrc & IS_XA2_F)
1011                         ClearTxIrq(pAC, 1, TX_PRIO_LOW);
1012 #endif
1013                 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1014         } /* while (IntSrc & IRQ_MASK != 0) */
1015
1016         IntSrc &= pAC->GIni.GIValIrqMask;
1017         if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1018                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1019                         ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
1020                 pAC->CheckQueue = SK_FALSE;
1021                 spin_lock(&pAC->SlowPathLock);
1022                 if (IntSrc & SPECIAL_IRQS)
1023                         SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1024
1025                 SkEventDispatcher(pAC, pAC->IoBase);
1026                 spin_unlock(&pAC->SlowPathLock);
1027         }
1028         /*
1029          * do it all again is case we cleared an interrupt that
1030          * came in after handling the ring (OUTs may be delayed
1031          * in hardware buffers, but are through after IN)
1032          *
1033          * rroesler: has been commented out and shifted to
1034          *           SkGeDrvEvent(), because it is timer
1035          *           guarded now
1036          *
1037         ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1038         ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
1039          */
1040
1041         if (pAC->CheckQueue) {
1042                 pAC->CheckQueue = SK_FALSE;
1043                 spin_lock(&pAC->SlowPathLock);
1044                 SkEventDispatcher(pAC, pAC->IoBase);
1045                 spin_unlock(&pAC->SlowPathLock);
1046         }
1047
1048         /* IRQ is processed - Enable IRQs again*/
1049         SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1050
1051                 return SkIsrRetHandled;
1052 } /* SkGeIsr */
1053
1054
1055 /****************************************************************************
1056  *
1057  *      SkGeIsrOnePort - handle adapter interrupts for single port adapter
1058  *
1059  * Description:
1060  *      The interrupt routine is called when the network adapter
1061  *      generates an interrupt. It may also be called if another device
1062  *      shares this interrupt vector with the driver.
1063  *      This is the same as above, but handles only one port.
1064  *
1065  * Returns: N/A
1066  *
1067  */
1068 static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
1069 {
1070 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
1071 DEV_NET         *pNet;
1072 SK_AC           *pAC;
1073 SK_U32          IntSrc;         /* interrupts source register contents */       
1074
1075         pNet = netdev_priv(dev);
1076         pAC = pNet->pAC;
1077         
1078         /*
1079          * Check and process if its our interrupt
1080          */
1081         SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1082         if (IntSrc == 0) {
1083                 return SkIsrRetNone;
1084         }
1085         
1086         while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1087 #if 0 /* software irq currently not used */
1088                 if (IntSrc & IS_IRQ_SW) {
1089                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1090                                 SK_DBGCAT_DRV_INT_SRC,
1091                                 ("Software IRQ\n"));
1092                 }
1093 #endif
1094                 if (IntSrc & IS_R1_F) {
1095                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1096                                 SK_DBGCAT_DRV_INT_SRC,
1097                                 ("EOF RX1 IRQ\n"));
1098                         ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1099                         SK_PNMI_CNT_RX_INTR(pAC, 0);
1100                 }
1101 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1102                 if (IntSrc & IS_XA1_F) {
1103                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1104                                 SK_DBGCAT_DRV_INT_SRC,
1105                                 ("EOF AS TX1 IRQ\n"));
1106                         SK_PNMI_CNT_TX_INTR(pAC, 0);
1107                         spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1108                         FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1109                         spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1110                 }
1111 #if 0 /* only if sync. queues used */
1112                 if (IntSrc & IS_XS1_F) {
1113                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1114                                 SK_DBGCAT_DRV_INT_SRC,
1115                                 ("EOF SY TX1 IRQ\n"));
1116                         SK_PNMI_CNT_TX_INTR(pAC, 0);
1117                         spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1118                         FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
1119                         spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1120                         ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
1121                 }
1122 #endif
1123 #endif
1124
1125                 /* do all IO at once */
1126                 if (IntSrc & IS_R1_F)
1127                         ClearAndStartRx(pAC, 0);
1128 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1129                 if (IntSrc & IS_XA1_F)
1130                         ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1131 #endif
1132                 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1133         } /* while (IntSrc & IRQ_MASK != 0) */
1134         
1135         IntSrc &= pAC->GIni.GIValIrqMask;
1136         if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1137                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1138                         ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
1139                 pAC->CheckQueue = SK_FALSE;
1140                 spin_lock(&pAC->SlowPathLock);
1141                 if (IntSrc & SPECIAL_IRQS)
1142                         SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1143
1144                 SkEventDispatcher(pAC, pAC->IoBase);
1145                 spin_unlock(&pAC->SlowPathLock);
1146         }
1147         /*
1148          * do it all again is case we cleared an interrupt that
1149          * came in after handling the ring (OUTs may be delayed
1150          * in hardware buffers, but are through after IN)
1151          *
1152          * rroesler: has been commented out and shifted to
1153          *           SkGeDrvEvent(), because it is timer
1154          *           guarded now
1155          *
1156         ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1157          */
1158
1159         /* IRQ is processed - Enable IRQs again*/
1160         SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1161
1162                 return SkIsrRetHandled;
1163 } /* SkGeIsrOnePort */
1164
1165 #ifdef CONFIG_NET_POLL_CONTROLLER
1166 /****************************************************************************
1167  *
1168  *      SkGePollController - polling receive, for netconsole
1169  *
1170  * Description:
1171  *      Polling receive - used by netconsole and other diagnostic tools
1172  *      to allow network i/o with interrupts disabled.
1173  *
1174  * Returns: N/A
1175  */
1176 static void SkGePollController(struct net_device *dev)
1177 {
1178         disable_irq(dev->irq);
1179         SkGeIsr(dev->irq, dev, NULL);
1180         enable_irq(dev->irq);
1181 }
1182 #endif
1183
1184 /****************************************************************************
1185  *
1186  *      SkGeOpen - handle start of initialized adapter
1187  *
1188  * Description:
1189  *      This function starts the initialized adapter.
1190  *      The board level variable is set and the adapter is
1191  *      brought to full functionality.
1192  *      The device flags are set for operation.
1193  *      Do all necessary level 2 initialization, enable interrupts and
1194  *      give start command to RLMT.
1195  *
1196  * Returns:
1197  *      0 on success
1198  *      != 0 on error
1199  */
1200 static int SkGeOpen(
1201 struct SK_NET_DEVICE    *dev)
1202 {
1203         DEV_NET                 *pNet;
1204         SK_AC                   *pAC;
1205         unsigned long   Flags;          /* for spin lock */
1206         int                             i;
1207         SK_EVPARA               EvPara;         /* an event parameter union */
1208
1209         pNet = netdev_priv(dev);
1210         pAC = pNet->pAC;
1211         
1212         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1213                 ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
1214
1215 #ifdef SK_DIAG_SUPPORT
1216         if (pAC->DiagModeActive == DIAG_ACTIVE) {
1217                 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
1218                         return (-1);   /* still in use by diag; deny actions */
1219                 } 
1220         }
1221 #endif
1222
1223         /* Set blink mode */
1224         if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
1225                 pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
1226
1227         if (pAC->BoardLevel == SK_INIT_DATA) {
1228                 /* level 1 init common modules here */
1229                 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
1230                         printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
1231                         return (-1);
1232                 }
1233                 SkI2cInit       (pAC, pAC->IoBase, SK_INIT_IO);
1234                 SkEventInit     (pAC, pAC->IoBase, SK_INIT_IO);
1235                 SkPnmiInit      (pAC, pAC->IoBase, SK_INIT_IO);
1236                 SkAddrInit      (pAC, pAC->IoBase, SK_INIT_IO);
1237                 SkRlmtInit      (pAC, pAC->IoBase, SK_INIT_IO);
1238                 SkTimerInit     (pAC, pAC->IoBase, SK_INIT_IO);
1239                 pAC->BoardLevel = SK_INIT_IO;
1240         }
1241
1242         if (pAC->BoardLevel != SK_INIT_RUN) {
1243                 /* tschilling: Level 2 init modules here, check return value. */
1244                 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
1245                         printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
1246                         return (-1);
1247                 }
1248                 SkI2cInit       (pAC, pAC->IoBase, SK_INIT_RUN);
1249                 SkEventInit     (pAC, pAC->IoBase, SK_INIT_RUN);
1250                 SkPnmiInit      (pAC, pAC->IoBase, SK_INIT_RUN);
1251                 SkAddrInit      (pAC, pAC->IoBase, SK_INIT_RUN);
1252                 SkRlmtInit      (pAC, pAC->IoBase, SK_INIT_RUN);
1253                 SkTimerInit     (pAC, pAC->IoBase, SK_INIT_RUN);
1254                 pAC->BoardLevel = SK_INIT_RUN;
1255         }
1256
1257         for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1258                 /* Enable transmit descriptor polling. */
1259                 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
1260                 FillRxRing(pAC, &pAC->RxPort[i]);
1261         }
1262         SkGeYellowLED(pAC, pAC->IoBase, 1);
1263
1264         StartDrvCleanupTimer(pAC);
1265         SkDimEnableModerationIfNeeded(pAC);     
1266         SkDimDisplayModerationSettings(pAC);
1267
1268         pAC->GIni.GIValIrqMask &= IRQ_MASK;
1269
1270         /* enable Interrupts */
1271         SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1272         SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
1273
1274         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1275
1276         if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
1277                 EvPara.Para32[0] = pAC->RlmtNets;
1278                 EvPara.Para32[1] = -1;
1279                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
1280                         EvPara);
1281                 EvPara.Para32[0] = pAC->RlmtMode;
1282                 EvPara.Para32[1] = 0;
1283                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
1284                         EvPara);
1285         }
1286
1287         EvPara.Para32[0] = pNet->NetNr;
1288         EvPara.Para32[1] = -1;
1289         SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
1290         SkEventDispatcher(pAC, pAC->IoBase);
1291         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1292
1293         pAC->MaxPorts++;
1294         pNet->Up = 1;
1295
1296
1297         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1298                 ("SkGeOpen suceeded\n"));
1299
1300         return (0);
1301 } /* SkGeOpen */
1302
1303
1304 /****************************************************************************
1305  *
1306  *      SkGeClose - Stop initialized adapter
1307  *
1308  * Description:
1309  *      Close initialized adapter.
1310  *
1311  * Returns:
1312  *      0 - on success
1313  *      error code - on error
1314  */
1315 static int SkGeClose(
1316 struct SK_NET_DEVICE    *dev)
1317 {
1318         DEV_NET         *pNet;
1319         DEV_NET         *newPtrNet;
1320         SK_AC           *pAC;
1321
1322         unsigned long   Flags;          /* for spin lock */
1323         int             i;
1324         int             PortIdx;
1325         SK_EVPARA       EvPara;
1326
1327         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1328                 ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
1329
1330         pNet = netdev_priv(dev);
1331         pAC = pNet->pAC;
1332
1333 #ifdef SK_DIAG_SUPPORT
1334         if (pAC->DiagModeActive == DIAG_ACTIVE) {
1335                 if (pAC->DiagFlowCtrl == SK_FALSE) {
1336                         /* 
1337                         ** notify that the interface which has been closed
1338                         ** by operator interaction must not be started up 
1339                         ** again when the DIAG has finished. 
1340                         */
1341                         newPtrNet = netdev_priv(pAC->dev[0]);
1342                         if (newPtrNet == pNet) {
1343                                 pAC->WasIfUp[0] = SK_FALSE;
1344                         } else {
1345                                 pAC->WasIfUp[1] = SK_FALSE;
1346                         }
1347                         return 0; /* return to system everything is fine... */
1348                 } else {
1349                         pAC->DiagFlowCtrl = SK_FALSE;
1350                 }
1351         }
1352 #endif
1353
1354         netif_stop_queue(dev);
1355
1356         if (pAC->RlmtNets == 1)
1357                 PortIdx = pAC->ActivePort;
1358         else
1359                 PortIdx = pNet->NetNr;
1360
1361         StopDrvCleanupTimer(pAC);
1362
1363         /*
1364          * Clear multicast table, promiscuous mode ....
1365          */
1366         SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
1367         SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
1368                 SK_PROM_MODE_NONE);
1369
1370         if (pAC->MaxPorts == 1) {
1371                 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1372                 /* disable interrupts */
1373                 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1374                 EvPara.Para32[0] = pNet->NetNr;
1375                 EvPara.Para32[1] = -1;
1376                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1377                 SkEventDispatcher(pAC, pAC->IoBase);
1378                 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1379                 /* stop the hardware */
1380                 SkGeDeInit(pAC, pAC->IoBase);
1381                 pAC->BoardLevel = SK_INIT_DATA;
1382                 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1383         } else {
1384
1385                 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1386                 EvPara.Para32[0] = pNet->NetNr;
1387                 EvPara.Para32[1] = -1;
1388                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1389                 SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
1390                 SkEventDispatcher(pAC, pAC->IoBase);
1391                 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1392                 
1393                 /* Stop port */
1394                 spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
1395                         [TX_PRIO_LOW].TxDesRingLock, Flags);
1396                 SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
1397                         SK_STOP_ALL, SK_HARD_RST);
1398                 spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
1399                         [TX_PRIO_LOW].TxDesRingLock, Flags);
1400         }
1401
1402         if (pAC->RlmtNets == 1) {
1403                 /* clear all descriptor rings */
1404                 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1405                         ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
1406                         ClearRxRing(pAC, &pAC->RxPort[i]);
1407                         ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
1408                 }
1409         } else {
1410                 /* clear port descriptor rings */
1411                 ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
1412                 ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
1413                 ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
1414         }
1415
1416         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1417                 ("SkGeClose: done "));
1418
1419         SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
1420         SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
1421                         sizeof(SK_PNMI_STRUCT_DATA));
1422
1423         pAC->MaxPorts--;
1424         pNet->Up = 0;
1425
1426         return (0);
1427 } /* SkGeClose */
1428
1429
1430 /*****************************************************************************
1431  *
1432  *      SkGeXmit - Linux frame transmit function
1433  *
1434  * Description:
1435  *      The system calls this function to send frames onto the wire.
1436  *      It puts the frame in the tx descriptor ring. If the ring is
1437  *      full then, the 'tbusy' flag is set.
1438  *
1439  * Returns:
1440  *      0, if everything is ok
1441  *      !=0, on error
1442  * WARNING: returning 1 in 'tbusy' case caused system crashes (double
1443  *      allocated skb's) !!!
1444  */
1445 static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
1446 {
1447 DEV_NET         *pNet;
1448 SK_AC           *pAC;
1449 int                     Rc;     /* return code of XmitFrame */
1450
1451         pNet = netdev_priv(dev);
1452         pAC = pNet->pAC;
1453
1454         if ((!skb_shinfo(skb)->nr_frags) ||
1455                 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
1456                 /* Don't activate scatter-gather and hardware checksum */
1457
1458                 if (pAC->RlmtNets == 2)
1459                         Rc = XmitFrame(
1460                                 pAC,
1461                                 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1462                                 skb);
1463                 else
1464                         Rc = XmitFrame(
1465                                 pAC,
1466                                 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1467                                 skb);
1468         } else {
1469                 /* scatter-gather and hardware TCP checksumming anabled*/
1470                 if (pAC->RlmtNets == 2)
1471                         Rc = XmitFrameSG(
1472                                 pAC,
1473                                 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1474                                 skb);
1475                 else
1476                         Rc = XmitFrameSG(
1477                                 pAC,
1478                                 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1479                                 skb);
1480         }
1481
1482         /* Transmitter out of resources? */
1483         if (Rc <= 0) {
1484                 netif_stop_queue(dev);
1485         }
1486
1487         /* If not taken, give buffer ownership back to the
1488          * queueing layer.
1489          */
1490         if (Rc < 0)
1491                 return (1);
1492
1493         dev->trans_start = jiffies;
1494         return (0);
1495 } /* SkGeXmit */
1496
1497
1498 /*****************************************************************************
1499  *
1500  *      XmitFrame - fill one socket buffer into the transmit ring
1501  *
1502  * Description:
1503  *      This function puts a message into the transmit descriptor ring
1504  *      if there is a descriptors left.
1505  *      Linux skb's consist of only one continuous buffer.
1506  *      The first step locks the ring. It is held locked
1507  *      all time to avoid problems with SWITCH_../PORT_RESET.
1508  *      Then the descriptoris allocated.
1509  *      The second part is linking the buffer to the descriptor.
1510  *      At the very last, the Control field of the descriptor
1511  *      is made valid for the BMU and a start TX command is given
1512  *      if necessary.
1513  *
1514  * Returns:
1515  *      > 0 - on succes: the number of bytes in the message
1516  *      = 0 - on resource shortage: this frame sent or dropped, now
1517  *              the ring is full ( -> set tbusy)
1518  *      < 0 - on failure: other problems ( -> return failure to upper layers)
1519  */
1520 static int XmitFrame(
1521 SK_AC           *pAC,           /* pointer to adapter context           */
1522 TX_PORT         *pTxPort,       /* pointer to struct of port to send to */
1523 struct sk_buff  *pMessage)      /* pointer to send-message              */
1524 {
1525         TXD             *pTxd;          /* the rxd to fill */
1526         TXD             *pOldTxd;
1527         unsigned long    Flags;
1528         SK_U64           PhysAddr;
1529         int              Protocol;
1530         int              IpHeaderLength;
1531         int              BytesSend = pMessage->len;
1532
1533         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
1534
1535         spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1536 #ifndef USE_TX_COMPLETE
1537         FreeTxDescriptors(pAC, pTxPort);
1538 #endif
1539         if (pTxPort->TxdRingFree == 0) {
1540                 /* 
1541                 ** no enough free descriptors in ring at the moment.
1542                 ** Maybe free'ing some old one help?
1543                 */
1544                 FreeTxDescriptors(pAC, pTxPort);
1545                 if (pTxPort->TxdRingFree == 0) {
1546                         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1547                         SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1548                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1549                                 SK_DBGCAT_DRV_TX_PROGRESS,
1550                                 ("XmitFrame failed\n"));
1551                         /* 
1552                         ** the desired message can not be sent
1553                         ** Because tbusy seems to be set, the message 
1554                         ** should not be freed here. It will be used 
1555                         ** by the scheduler of the ethernet handler 
1556                         */
1557                         return (-1);
1558                 }
1559         }
1560
1561         /*
1562         ** If the passed socket buffer is of smaller MTU-size than 60,
1563         ** copy everything into new buffer and fill all bytes between
1564         ** the original packet end and the new packet end of 60 with 0x00.
1565         ** This is to resolve faulty padding by the HW with 0xaa bytes.
1566         */
1567         if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
1568                 if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
1569                         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1570                         return 0;
1571                 }
1572                 pMessage->len = C_LEN_ETHERNET_MINSIZE;
1573         }
1574
1575         /* 
1576         ** advance head counter behind descriptor needed for this frame, 
1577         ** so that needed descriptor is reserved from that on. The next
1578         ** action will be to add the passed buffer to the TX-descriptor
1579         */
1580         pTxd = pTxPort->pTxdRingHead;
1581         pTxPort->pTxdRingHead = pTxd->pNextTxd;
1582         pTxPort->TxdRingFree--;
1583
1584 #ifdef SK_DUMP_TX
1585         DumpMsg(pMessage, "XmitFrame");
1586 #endif
1587
1588         /* 
1589         ** First step is to map the data to be sent via the adapter onto
1590         ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
1591         ** and 2.6 need to use pci_map_page() for that mapping.
1592         */
1593         PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1594                                         virt_to_page(pMessage->data),
1595                                         ((unsigned long) pMessage->data & ~PAGE_MASK),
1596                                         pMessage->len,
1597                                         PCI_DMA_TODEVICE);
1598         pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
1599         pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1600         pTxd->pMBuf     = pMessage;
1601
1602         if (pMessage->ip_summed == CHECKSUM_HW) {
1603                 Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
1604                 if ((Protocol == C_PROTO_ID_UDP) && 
1605                         (pAC->GIni.GIChipRev == 0) &&
1606                         (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1607                         pTxd->TBControl = BMU_TCP_CHECK;
1608                 } else {
1609                         pTxd->TBControl = BMU_UDP_CHECK;
1610                 }
1611
1612                 IpHeaderLength  = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
1613                 IpHeaderLength  = (IpHeaderLength & 0xf) * 4;
1614                 pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */
1615                 pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength + 
1616                                                         (Protocol == C_PROTO_ID_UDP ?
1617                                                         C_OFFSET_UDPHEADER_UDPCS : 
1618                                                         C_OFFSET_TCPHEADER_TCPCS);
1619                 pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
1620
1621                 pTxd->TBControl |= BMU_OWN | BMU_STF | 
1622                                    BMU_SW  | BMU_EOF |
1623 #ifdef USE_TX_COMPLETE
1624                                    BMU_IRQ_EOF |
1625 #endif
1626                                    pMessage->len;
1627         } else {
1628                 pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | 
1629                                   BMU_SW  | BMU_EOF |
1630 #ifdef USE_TX_COMPLETE
1631                                    BMU_IRQ_EOF |
1632 #endif
1633                         pMessage->len;
1634         }
1635
1636         /* 
1637         ** If previous descriptor already done, give TX start cmd 
1638         */
1639         pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
1640         if ((pOldTxd->TBControl & BMU_OWN) == 0) {
1641                 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1642         }       
1643
1644         /* 
1645         ** after releasing the lock, the skb may immediately be free'd 
1646         */
1647         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1648         if (pTxPort->TxdRingFree != 0) {
1649                 return (BytesSend);
1650         } else {
1651                 return (0);
1652         }
1653
1654 } /* XmitFrame */
1655
1656 /*****************************************************************************
1657  *
1658  *      XmitFrameSG - fill one socket buffer into the transmit ring
1659  *                (use SG and TCP/UDP hardware checksumming)
1660  *
1661  * Description:
1662  *      This function puts a message into the transmit descriptor ring
1663  *      if there is a descriptors left.
1664  *
1665  * Returns:
1666  *      > 0 - on succes: the number of bytes in the message
1667  *      = 0 - on resource shortage: this frame sent or dropped, now
1668  *              the ring is full ( -> set tbusy)
1669  *      < 0 - on failure: other problems ( -> return failure to upper layers)
1670  */
1671 static int XmitFrameSG(
1672 SK_AC           *pAC,           /* pointer to adapter context           */
1673 TX_PORT         *pTxPort,       /* pointer to struct of port to send to */
1674 struct sk_buff  *pMessage)      /* pointer to send-message              */
1675 {
1676
1677         TXD             *pTxd;
1678         TXD             *pTxdFst;
1679         TXD             *pTxdLst;
1680         int              CurrFrag;
1681         int              BytesSend;
1682         int              IpHeaderLength; 
1683         int              Protocol;
1684         skb_frag_t      *sk_frag;
1685         SK_U64           PhysAddr;
1686         unsigned long    Flags;
1687
1688         spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1689 #ifndef USE_TX_COMPLETE
1690         FreeTxDescriptors(pAC, pTxPort);
1691 #endif
1692         if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
1693                 FreeTxDescriptors(pAC, pTxPort);
1694                 if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
1695                         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1696                         SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1697                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1698                                 SK_DBGCAT_DRV_TX_PROGRESS,
1699                                 ("XmitFrameSG failed - Ring full\n"));
1700                                 /* this message can not be sent now */
1701                         return(-1);
1702                 }
1703         }
1704
1705         pTxd      = pTxPort->pTxdRingHead;
1706         pTxdFst   = pTxd;
1707         pTxdLst   = pTxd;
1708         BytesSend = 0;
1709         Protocol  = 0;
1710
1711         /* 
1712         ** Map the first fragment (header) into the DMA-space
1713         */
1714         PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1715                         virt_to_page(pMessage->data),
1716                         ((unsigned long) pMessage->data & ~PAGE_MASK),
1717                         skb_headlen(pMessage),
1718                         PCI_DMA_TODEVICE);
1719
1720         pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
1721         pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1722
1723         /* 
1724         ** Does the HW need to evaluate checksum for TCP or UDP packets? 
1725         */
1726         if (pMessage->ip_summed == CHECKSUM_HW) {
1727                 pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage);
1728                 /* 
1729                 ** We have to use the opcode for tcp here,  because the
1730                 ** opcode for udp is not working in the hardware yet 
1731                 ** (Revision 2.0)
1732                 */
1733                 Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
1734                 if ((Protocol == C_PROTO_ID_UDP) && 
1735                         (pAC->GIni.GIChipRev == 0) &&
1736                         (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1737                         pTxd->TBControl |= BMU_TCP_CHECK;
1738                 } else {
1739                         pTxd->TBControl |= BMU_UDP_CHECK;
1740                 }
1741
1742                 IpHeaderLength  = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
1743                 pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
1744                 pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
1745                                                 (Protocol == C_PROTO_ID_UDP ?
1746                                                 C_OFFSET_UDPHEADER_UDPCS :
1747                                                 C_OFFSET_TCPHEADER_TCPCS);
1748                 pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
1749         } else {
1750                 pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF |
1751                                         skb_headlen(pMessage);
1752         }
1753
1754         pTxd = pTxd->pNextTxd;
1755         pTxPort->TxdRingFree--;
1756         BytesSend += skb_headlen(pMessage);
1757
1758         /* 
1759         ** Browse over all SG fragments and map each of them into the DMA space
1760         */
1761         for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
1762                 sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
1763                 /* 
1764                 ** we already have the proper value in entry
1765                 */
1766                 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1767                                                  sk_frag->page,
1768                                                  sk_frag->page_offset,
1769                                                  sk_frag->size,
1770                                                  PCI_DMA_TODEVICE);
1771
1772                 pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
1773                 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1774                 pTxd->pMBuf     = pMessage;
1775                 
1776                 /* 
1777                 ** Does the HW need to evaluate checksum for TCP or UDP packets? 
1778                 */
1779                 if (pMessage->ip_summed == CHECKSUM_HW) {
1780                         pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD;
1781                         /* 
1782                         ** We have to use the opcode for tcp here because the 
1783                         ** opcode for udp is not working in the hardware yet 
1784                         ** (revision 2.0)
1785                         */
1786                         if ((Protocol == C_PROTO_ID_UDP) && 
1787                                 (pAC->GIni.GIChipRev == 0) &&
1788                                 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1789                                 pTxd->TBControl |= BMU_TCP_CHECK;
1790                         } else {
1791                                 pTxd->TBControl |= BMU_UDP_CHECK;
1792                         }
1793                 } else {
1794                         pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
1795                 }
1796
1797                 /* 
1798                 ** Do we have the last fragment? 
1799                 */
1800                 if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags )  {
1801 #ifdef USE_TX_COMPLETE
1802                         pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size;
1803 #else
1804                         pTxd->TBControl |= BMU_EOF | sk_frag->size;
1805 #endif
1806                         pTxdFst->TBControl |= BMU_OWN | BMU_SW;
1807
1808                 } else {
1809                         pTxd->TBControl |= sk_frag->size;
1810                 }
1811                 pTxdLst = pTxd;
1812                 pTxd    = pTxd->pNextTxd;
1813                 pTxPort->TxdRingFree--;
1814                 BytesSend += sk_frag->size;
1815         }
1816
1817         /* 
1818         ** If previous descriptor already done, give TX start cmd 
1819         */
1820         if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
1821                 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1822         }
1823
1824         pTxPort->pTxdRingPrev = pTxdLst;
1825         pTxPort->pTxdRingHead = pTxd;
1826
1827         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1828
1829         if (pTxPort->TxdRingFree > 0) {
1830                 return (BytesSend);
1831         } else {
1832                 return (0);
1833         }
1834 }
1835
1836 /*****************************************************************************
1837  *
1838  *      FreeTxDescriptors - release descriptors from the descriptor ring
1839  *
1840  * Description:
1841  *      This function releases descriptors from a transmit ring if they
1842  *      have been sent by the BMU.
1843  *      If a descriptors is sent, it can be freed and the message can
1844  *      be freed, too.
1845  *      The SOFTWARE controllable bit is used to prevent running around a
1846  *      completely free ring for ever. If this bit is no set in the
1847  *      frame (by XmitFrame), this frame has never been sent or is
1848  *      already freed.
1849  *      The Tx descriptor ring lock must be held while calling this function !!!
1850  *
1851  * Returns:
1852  *      none
1853  */
1854 static void FreeTxDescriptors(
1855 SK_AC   *pAC,           /* pointer to the adapter context */
1856 TX_PORT *pTxPort)       /* pointer to destination port structure */
1857 {
1858 TXD     *pTxd;          /* pointer to the checked descriptor */
1859 TXD     *pNewTail;      /* pointer to 'end' of the ring */
1860 SK_U32  Control;        /* TBControl field of descriptor */
1861 SK_U64  PhysAddr;       /* address of DMA mapping */
1862
1863         pNewTail = pTxPort->pTxdRingTail;
1864         pTxd     = pNewTail;
1865         /*
1866         ** loop forever; exits if BMU_SW bit not set in start frame
1867         ** or BMU_OWN bit set in any frame
1868         */
1869         while (1) {
1870                 Control = pTxd->TBControl;
1871                 if ((Control & BMU_SW) == 0) {
1872                         /*
1873                         ** software controllable bit is set in first
1874                         ** fragment when given to BMU. Not set means that
1875                         ** this fragment was never sent or is already
1876                         ** freed ( -> ring completely free now).
1877                         */
1878                         pTxPort->pTxdRingTail = pTxd;
1879                         netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1880                         return;
1881                 }
1882                 if (Control & BMU_OWN) {
1883                         pTxPort->pTxdRingTail = pTxd;
1884                         if (pTxPort->TxdRingFree > 0) {
1885                                 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1886                         }
1887                         return;
1888                 }
1889                 
1890                 /* 
1891                 ** release the DMA mapping, because until not unmapped
1892                 ** this buffer is considered being under control of the
1893                 ** adapter card!
1894                 */
1895                 PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
1896                 PhysAddr |= (SK_U64) pTxd->VDataLow;
1897                 pci_unmap_page(pAC->PciDev, PhysAddr,
1898                                  pTxd->pMBuf->len,
1899                                  PCI_DMA_TODEVICE);
1900
1901                 if (Control & BMU_EOF)
1902                         DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
1903
1904                 pTxPort->TxdRingFree++;
1905                 pTxd->TBControl &= ~BMU_SW;
1906                 pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
1907         } /* while(forever) */
1908 } /* FreeTxDescriptors */
1909
1910 /*****************************************************************************
1911  *
1912  *      FillRxRing - fill the receive ring with valid descriptors
1913  *
1914  * Description:
1915  *      This function fills the receive ring descriptors with data
1916  *      segments and makes them valid for the BMU.
1917  *      The active ring is filled completely, if possible.
1918  *      The non-active ring is filled only partial to save memory.
1919  *
1920  * Description of rx ring structure:
1921  *      head - points to the descriptor which will be used next by the BMU
1922  *      tail - points to the next descriptor to give to the BMU
1923  *      
1924  * Returns:     N/A
1925  */
1926 static void FillRxRing(
1927 SK_AC           *pAC,           /* pointer to the adapter context */
1928 RX_PORT         *pRxPort)       /* ptr to port struct for which the ring
1929                                    should be filled */
1930 {
1931 unsigned long   Flags;
1932
1933         spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
1934         while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
1935                 if(!FillRxDescriptor(pAC, pRxPort))
1936                         break;
1937         }
1938         spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
1939 } /* FillRxRing */
1940
1941
1942 /*****************************************************************************
1943  *
1944  *      FillRxDescriptor - fill one buffer into the receive ring
1945  *
1946  * Description:
1947  *      The function allocates a new receive buffer and
1948  *      puts it into the next descriptor.
1949  *
1950  * Returns:
1951  *      SK_TRUE - a buffer was added to the ring
1952  *      SK_FALSE - a buffer could not be added
1953  */
1954 static SK_BOOL FillRxDescriptor(
1955 SK_AC           *pAC,           /* pointer to the adapter context struct */
1956 RX_PORT         *pRxPort)       /* ptr to port struct of ring to fill */
1957 {
1958 struct sk_buff  *pMsgBlock;     /* pointer to a new message block */
1959 RXD             *pRxd;          /* the rxd to fill */
1960 SK_U16          Length;         /* data fragment length */
1961 SK_U64          PhysAddr;       /* physical address of a rx buffer */
1962
1963         pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
1964         if (pMsgBlock == NULL) {
1965                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1966                         SK_DBGCAT_DRV_ENTRY,
1967                         ("%s: Allocation of rx buffer failed !\n",
1968                         pAC->dev[pRxPort->PortIndex]->name));
1969                 SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
1970                 return(SK_FALSE);
1971         }
1972         skb_reserve(pMsgBlock, 2); /* to align IP frames */
1973         /* skb allocated ok, so add buffer */
1974         pRxd = pRxPort->pRxdRingTail;
1975         pRxPort->pRxdRingTail = pRxd->pNextRxd;
1976         pRxPort->RxdRingFree--;
1977         Length = pAC->RxBufSize;
1978         PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1979                 virt_to_page(pMsgBlock->data),
1980                 ((unsigned long) pMsgBlock->data &
1981                 ~PAGE_MASK),
1982                 pAC->RxBufSize - 2,
1983                 PCI_DMA_FROMDEVICE);
1984
1985         pRxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
1986         pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1987         pRxd->pMBuf     = pMsgBlock;
1988         pRxd->RBControl = BMU_OWN       | 
1989                           BMU_STF       | 
1990                           BMU_IRQ_EOF   | 
1991                           BMU_TCP_CHECK | 
1992                           Length;
1993         return (SK_TRUE);
1994
1995 } /* FillRxDescriptor */
1996
1997
1998 /*****************************************************************************
1999  *
2000  *      ReQueueRxBuffer - fill one buffer back into the receive ring
2001  *
2002  * Description:
2003  *      Fill a given buffer back into the rx ring. The buffer
2004  *      has been previously allocated and aligned, and its phys.
2005  *      address calculated, so this is no more necessary.
2006  *
2007  * Returns: N/A
2008  */
2009 static void ReQueueRxBuffer(
2010 SK_AC           *pAC,           /* pointer to the adapter context struct */
2011 RX_PORT         *pRxPort,       /* ptr to port struct of ring to fill */
2012 struct sk_buff  *pMsg,          /* pointer to the buffer */
2013 SK_U32          PhysHigh,       /* phys address high dword */
2014 SK_U32          PhysLow)        /* phys address low dword */
2015 {
2016 RXD             *pRxd;          /* the rxd to fill */
2017 SK_U16          Length;         /* data fragment length */
2018
2019         pRxd = pRxPort->pRxdRingTail;
2020         pRxPort->pRxdRingTail = pRxd->pNextRxd;
2021         pRxPort->RxdRingFree--;
2022         Length = pAC->RxBufSize;
2023
2024         pRxd->VDataLow  = PhysLow;
2025         pRxd->VDataHigh = PhysHigh;
2026         pRxd->pMBuf     = pMsg;
2027         pRxd->RBControl = BMU_OWN       | 
2028                           BMU_STF       |
2029                           BMU_IRQ_EOF   | 
2030                           BMU_TCP_CHECK | 
2031                           Length;
2032         return;
2033 } /* ReQueueRxBuffer */
2034
2035 /*****************************************************************************
2036  *
2037  *      ReceiveIrq - handle a receive IRQ
2038  *
2039  * Description:
2040  *      This function is called when a receive IRQ is set.
2041  *      It walks the receive descriptor ring and sends up all
2042  *      frames that are complete.
2043  *
2044  * Returns:     N/A
2045  */
2046 static void ReceiveIrq(
2047         SK_AC           *pAC,                   /* pointer to adapter context */
2048         RX_PORT         *pRxPort,               /* pointer to receive port struct */
2049         SK_BOOL         SlowPathLock)   /* indicates if SlowPathLock is needed */
2050 {
2051 RXD                             *pRxd;                  /* pointer to receive descriptors */
2052 SK_U32                  Control;                /* control field of descriptor */
2053 struct sk_buff  *pMsg;                  /* pointer to message holding frame */
2054 struct sk_buff  *pNewMsg;               /* pointer to a new message for copying frame */
2055 int                             FrameLength;    /* total length of received frame */
2056 int                             IpFrameLength;
2057 SK_MBUF                 *pRlmtMbuf;             /* ptr to a buffer for giving a frame to rlmt */
2058 SK_EVPARA               EvPara;                 /* an event parameter union */  
2059 unsigned long   Flags;                  /* for spin lock */
2060 int                             PortIndex = pRxPort->PortIndex;
2061 unsigned int    Offset;
2062 unsigned int    NumBytes;
2063 unsigned int    ForRlmt;
2064 SK_BOOL                 IsBc;
2065 SK_BOOL                 IsMc;
2066 SK_BOOL  IsBadFrame;                    /* Bad frame */
2067
2068 SK_U32                  FrameStat;
2069 unsigned short  Csum1;
2070 unsigned short  Csum2;
2071 unsigned short  Type;
2072 int                             Result;
2073 SK_U64                  PhysAddr;
2074
2075 rx_start:       
2076         /* do forever; exit if BMU_OWN found */
2077         for ( pRxd = pRxPort->pRxdRingHead ;
2078                   pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
2079                   pRxd = pRxd->pNextRxd,
2080                   pRxPort->pRxdRingHead = pRxd,
2081                   pRxPort->RxdRingFree ++) {
2082
2083                 /*
2084                  * For a better understanding of this loop
2085                  * Go through every descriptor beginning at the head
2086                  * Please note: the ring might be completely received so the OWN bit
2087                  * set is not a good crirteria to leave that loop.
2088                  * Therefore the RingFree counter is used.
2089                  * On entry of this loop pRxd is a pointer to the Rxd that needs
2090                  * to be checked next.
2091                  */
2092
2093                 Control = pRxd->RBControl;
2094         
2095                 /* check if this descriptor is ready */
2096                 if ((Control & BMU_OWN) != 0) {
2097                         /* this descriptor is not yet ready */
2098                         /* This is the usual end of the loop */
2099                         /* We don't need to start the ring again */
2100                         FillRxRing(pAC, pRxPort);
2101                         return;
2102                 }
2103                 pAC->DynIrqModInfo.NbrProcessedDescr++;
2104
2105                 /* get length of frame and check it */
2106                 FrameLength = Control & BMU_BBC;
2107                 if (FrameLength > pAC->RxBufSize) {
2108                         goto rx_failed;
2109                 }
2110
2111                 /* check for STF and EOF */
2112                 if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
2113                         goto rx_failed;
2114                 }
2115
2116                 /* here we have a complete frame in the ring */
2117                 pMsg = pRxd->pMBuf;
2118
2119                 FrameStat = pRxd->FrameStat;
2120
2121                 /* check for frame length mismatch */
2122 #define XMR_FS_LEN_SHIFT        18
2123 #define GMR_FS_LEN_SHIFT        16
2124                 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2125                         if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
2126                                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2127                                         SK_DBGCAT_DRV_RX_PROGRESS,
2128                                         ("skge: Frame length mismatch (%u/%u).\n",
2129                                         FrameLength,
2130                                         (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2131                                 goto rx_failed;
2132                         }
2133                 }
2134                 else {
2135                         if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
2136                                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2137                                         SK_DBGCAT_DRV_RX_PROGRESS,
2138                                         ("skge: Frame length mismatch (%u/%u).\n",
2139                                         FrameLength,
2140                                         (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2141                                 goto rx_failed;
2142                         }
2143                 }
2144
2145                 /* Set Rx Status */
2146                 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2147                         IsBc = (FrameStat & XMR_FS_BC) != 0;
2148                         IsMc = (FrameStat & XMR_FS_MC) != 0;
2149                         IsBadFrame = (FrameStat &
2150                                 (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
2151                 } else {
2152                         IsBc = (FrameStat & GMR_FS_BC) != 0;
2153                         IsMc = (FrameStat & GMR_FS_MC) != 0;
2154                         IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
2155                                                         ((FrameStat & GMR_FS_RX_OK) == 0));
2156                 }
2157
2158                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2159                         ("Received frame of length %d on port %d\n",
2160                         FrameLength, PortIndex));
2161                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2162                         ("Number of free rx descriptors: %d\n",
2163                         pRxPort->RxdRingFree));
2164 /* DumpMsg(pMsg, "Rx"); */
2165
2166                 if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
2167 #if 0
2168                         (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
2169 #endif
2170                         /* there is a receive error in this frame */
2171                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2172                                 SK_DBGCAT_DRV_RX_PROGRESS,
2173                                 ("skge: Error in received frame, dropped!\n"
2174                                 "Control: %x\nRxStat: %x\n",
2175                                 Control, FrameStat));
2176
2177                         ReQueueRxBuffer(pAC, pRxPort, pMsg,
2178                                 pRxd->VDataHigh, pRxd->VDataLow);
2179
2180                         continue;
2181                 }
2182
2183                 /*
2184                  * if short frame then copy data to reduce memory waste
2185                  */
2186                 if ((FrameLength < SK_COPY_THRESHOLD) &&
2187                         ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
2188                         /*
2189                          * Short frame detected and allocation successfull
2190                          */
2191                         /* use new skb and copy data */
2192                         skb_reserve(pNewMsg, 2);
2193                         skb_put(pNewMsg, FrameLength);
2194                         PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2195                         PhysAddr |= (SK_U64) pRxd->VDataLow;
2196
2197                         pci_dma_sync_single_for_cpu(pAC->PciDev,
2198                                                     (dma_addr_t) PhysAddr,
2199                                                     FrameLength,
2200                                                     PCI_DMA_FROMDEVICE);
2201                         eth_copy_and_sum(pNewMsg, pMsg->data,
2202                                 FrameLength, 0);
2203                         pci_dma_sync_single_for_device(pAC->PciDev,
2204                                                        (dma_addr_t) PhysAddr,
2205                                                        FrameLength,
2206                                                        PCI_DMA_FROMDEVICE);
2207                         ReQueueRxBuffer(pAC, pRxPort, pMsg,
2208                                 pRxd->VDataHigh, pRxd->VDataLow);
2209
2210                         pMsg = pNewMsg;
2211
2212                 }
2213                 else {
2214                         /*
2215                          * if large frame, or SKB allocation failed, pass
2216                          * the SKB directly to the networking
2217                          */
2218
2219                         PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2220                         PhysAddr |= (SK_U64) pRxd->VDataLow;
2221
2222                         /* release the DMA mapping */
2223                         pci_unmap_single(pAC->PciDev,
2224                                          PhysAddr,
2225                                          pAC->RxBufSize - 2,
2226                                          PCI_DMA_FROMDEVICE);
2227
2228                         /* set length in message */
2229                         skb_put(pMsg, FrameLength);
2230                         /* hardware checksum */
2231                         Type = ntohs(*((short*)&pMsg->data[12]));
2232
2233 #ifdef USE_SK_RX_CHECKSUM
2234                         if (Type == 0x800) {
2235                                 Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
2236                                 Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
2237                                 IpFrameLength = (int) ntohs((unsigned short)
2238                                                                 ((unsigned short *) pMsg->data)[8]);
2239
2240                                 /*
2241                                  * Test: If frame is padded, a check is not possible!
2242                                  * Frame not padded? Length difference must be 14 (0xe)!
2243                                  */
2244                                 if ((FrameLength - IpFrameLength) != 0xe) {
2245                                 /* Frame padded => TCP offload not possible! */
2246                                         pMsg->ip_summed = CHECKSUM_NONE;
2247                                 } else {
2248                                 /* Frame not padded => TCP offload! */
2249                                         if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
2250                                                 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
2251                                                 (pAC->ChipsetType)) {
2252                                                 Result = SkCsGetReceiveInfo(pAC,
2253                                                         &pMsg->data[14],
2254                                                         Csum1, Csum2, pRxPort->PortIndex);
2255                                                 if (Result ==
2256                                                         SKCS_STATUS_IP_FRAGMENT ||
2257                                                         Result ==
2258                                                         SKCS_STATUS_IP_CSUM_OK ||
2259                                                         Result ==
2260                                                         SKCS_STATUS_TCP_CSUM_OK ||
2261                                                         Result ==
2262                                                         SKCS_STATUS_UDP_CSUM_OK) {
2263                                                                 pMsg->ip_summed =
2264                                                                 CHECKSUM_UNNECESSARY;
2265                                                 }
2266                                                 else if (Result ==
2267                                                         SKCS_STATUS_TCP_CSUM_ERROR ||
2268                                                         Result ==
2269                                                         SKCS_STATUS_UDP_CSUM_ERROR ||
2270                                                         Result ==
2271                                                         SKCS_STATUS_IP_CSUM_ERROR_UDP ||
2272                                                         Result ==
2273                                                         SKCS_STATUS_IP_CSUM_ERROR_TCP ||
2274                                                         Result ==
2275                                                         SKCS_STATUS_IP_CSUM_ERROR ) {
2276                                                         /* HW Checksum error */
2277                                                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2278                                                         SK_DBGCAT_DRV_RX_PROGRESS,
2279                                                         ("skge: CRC error. Frame dropped!\n"));
2280                                                         goto rx_failed;
2281                                                 } else {
2282                                                                 pMsg->ip_summed =
2283                                                                 CHECKSUM_NONE;
2284                                                 }
2285                                         }/* checksumControl calculation valid */
2286                                 } /* Frame length check */
2287                         } /* IP frame */
2288 #else
2289                         pMsg->ip_summed = CHECKSUM_NONE;        
2290 #endif
2291                 } /* frame > SK_COPY_TRESHOLD */
2292                 
2293                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
2294                 ForRlmt = SK_RLMT_RX_PROTOCOL;
2295 #if 0
2296                 IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
2297 #endif
2298                 SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
2299                         IsBc, &Offset, &NumBytes);
2300                 if (NumBytes != 0) {
2301 #if 0
2302                         IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
2303 #endif
2304                         SK_RLMT_LOOKAHEAD(pAC, PortIndex,
2305                                 &pMsg->data[Offset],
2306                                 IsBc, IsMc, &ForRlmt);
2307                 }
2308                 if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
2309                                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
2310                         /* send up only frames from active port */
2311                         if ((PortIndex == pAC->ActivePort) ||
2312                                 (pAC->RlmtNets == 2)) {
2313                                 /* frame for upper layer */
2314                                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
2315 #ifdef xDEBUG
2316                                 DumpMsg(pMsg, "Rx");
2317 #endif
2318                                 SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
2319                                         FrameLength, pRxPort->PortIndex);
2320
2321                                 pMsg->dev = pAC->dev[pRxPort->PortIndex];
2322                                 pMsg->protocol = eth_type_trans(pMsg,
2323                                         pAC->dev[pRxPort->PortIndex]);
2324                                 netif_rx(pMsg);
2325                                 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2326                         }
2327                         else {
2328                                 /* drop frame */
2329                                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2330                                         SK_DBGCAT_DRV_RX_PROGRESS,
2331                                         ("D"));
2332                                 DEV_KFREE_SKB(pMsg);
2333                         }
2334                         
2335                 } /* if not for rlmt */
2336                 else {
2337                         /* packet for rlmt */
2338                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2339                                 SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
2340                         pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
2341                                 pAC->IoBase, FrameLength);
2342                         if (pRlmtMbuf != NULL) {
2343                                 pRlmtMbuf->pNext = NULL;
2344                                 pRlmtMbuf->Length = FrameLength;
2345                                 pRlmtMbuf->PortIdx = PortIndex;
2346                                 EvPara.pParaPtr = pRlmtMbuf;
2347                                 memcpy((char*)(pRlmtMbuf->pData),
2348                                            (char*)(pMsg->data),
2349                                            FrameLength);
2350
2351                                 /* SlowPathLock needed? */
2352                                 if (SlowPathLock == SK_TRUE) {
2353                                         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2354                                         SkEventQueue(pAC, SKGE_RLMT,
2355                                                 SK_RLMT_PACKET_RECEIVED,
2356                                                 EvPara);
2357                                         pAC->CheckQueue = SK_TRUE;
2358                                         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2359                                 } else {
2360                                         SkEventQueue(pAC, SKGE_RLMT,
2361                                                 SK_RLMT_PACKET_RECEIVED,
2362                                                 EvPara);
2363                                         pAC->CheckQueue = SK_TRUE;
2364                                 }
2365
2366                                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2367                                         SK_DBGCAT_DRV_RX_PROGRESS,
2368                                         ("Q"));
2369                         }
2370                         if ((pAC->dev[pRxPort->PortIndex]->flags &
2371                                 (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
2372                                 (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
2373                                 SK_RLMT_RX_PROTOCOL) {
2374                                 pMsg->dev = pAC->dev[pRxPort->PortIndex];
2375                                 pMsg->protocol = eth_type_trans(pMsg,
2376                                         pAC->dev[pRxPort->PortIndex]);
2377                                 netif_rx(pMsg);
2378                                 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2379                         }
2380                         else {
2381                                 DEV_KFREE_SKB(pMsg);
2382                         }
2383
2384                 } /* if packet for rlmt */
2385         } /* for ... scanning the RXD ring */
2386
2387         /* RXD ring is empty -> fill and restart */
2388         FillRxRing(pAC, pRxPort);
2389         /* do not start if called from Close */
2390         if (pAC->BoardLevel > SK_INIT_DATA) {
2391                 ClearAndStartRx(pAC, PortIndex);
2392         }
2393         return;
2394
2395 rx_failed:
2396         /* remove error frame */
2397         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
2398                 ("Schrottdescriptor, length: 0x%x\n", FrameLength));
2399
2400         /* release the DMA mapping */
2401
2402         PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2403         PhysAddr |= (SK_U64) pRxd->VDataLow;
2404         pci_unmap_page(pAC->PciDev,
2405                          PhysAddr,
2406                          pAC->RxBufSize - 2,
2407                          PCI_DMA_FROMDEVICE);
2408         DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
2409         pRxd->pMBuf = NULL;
2410         pRxPort->RxdRingFree++;
2411         pRxPort->pRxdRingHead = pRxd->pNextRxd;
2412         goto rx_start;
2413
2414 } /* ReceiveIrq */
2415
2416
2417 /*****************************************************************************
2418  *
2419  *      ClearAndStartRx - give a start receive command to BMU, clear IRQ
2420  *
2421  * Description:
2422  *      This function sends a start command and a clear interrupt
2423  *      command for one receive queue to the BMU.
2424  *
2425  * Returns: N/A
2426  *      none
2427  */
2428 static void ClearAndStartRx(
2429 SK_AC   *pAC,           /* pointer to the adapter context */
2430 int     PortIndex)      /* index of the receive port (XMAC) */
2431 {
2432         SK_OUT8(pAC->IoBase,
2433                 RxQueueAddr[PortIndex]+Q_CSR,
2434                 CSR_START | CSR_IRQ_CL_F);
2435 } /* ClearAndStartRx */
2436
2437
2438 /*****************************************************************************
2439  *
2440  *      ClearTxIrq - give a clear transmit IRQ command to BMU
2441  *
2442  * Description:
2443  *      This function sends a clear tx IRQ command for one
2444  *      transmit queue to the BMU.
2445  *
2446  * Returns: N/A
2447  */
2448 static void ClearTxIrq(
2449 SK_AC   *pAC,           /* pointer to the adapter context */
2450 int     PortIndex,      /* index of the transmit port (XMAC) */
2451 int     Prio)           /* priority or normal queue */
2452 {
2453         SK_OUT8(pAC->IoBase, 
2454                 TxQueueAddr[PortIndex][Prio]+Q_CSR,
2455                 CSR_IRQ_CL_F);
2456 } /* ClearTxIrq */
2457
2458
2459 /*****************************************************************************
2460  *
2461  *      ClearRxRing - remove all buffers from the receive ring
2462  *
2463  * Description:
2464  *      This function removes all receive buffers from the ring.
2465  *      The receive BMU must be stopped before calling this function.
2466  *
2467  * Returns: N/A
2468  */
2469 static void ClearRxRing(
2470 SK_AC   *pAC,           /* pointer to adapter context */
2471 RX_PORT *pRxPort)       /* pointer to rx port struct */
2472 {
2473 RXD             *pRxd;  /* pointer to the current descriptor */
2474 unsigned long   Flags;
2475 SK_U64          PhysAddr;
2476
2477         if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
2478                 return;
2479         }
2480         spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
2481         pRxd = pRxPort->pRxdRingHead;
2482         do {
2483                 if (pRxd->pMBuf != NULL) {
2484
2485                         PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2486                         PhysAddr |= (SK_U64) pRxd->VDataLow;
2487                         pci_unmap_page(pAC->PciDev,
2488                                          PhysAddr,
2489                                          pAC->RxBufSize - 2,
2490                                          PCI_DMA_FROMDEVICE);
2491                         DEV_KFREE_SKB(pRxd->pMBuf);
2492                         pRxd->pMBuf = NULL;
2493                 }
2494                 pRxd->RBControl &= BMU_OWN;
2495                 pRxd = pRxd->pNextRxd;
2496                 pRxPort->RxdRingFree++;
2497         } while (pRxd != pRxPort->pRxdRingTail);
2498         pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
2499         spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
2500 } /* ClearRxRing */
2501
2502 /*****************************************************************************
2503  *
2504  *      ClearTxRing - remove all buffers from the transmit ring
2505  *
2506  * Description:
2507  *      This function removes all transmit buffers from the ring.
2508  *      The transmit BMU must be stopped before calling this function
2509  *      and transmitting at the upper level must be disabled.
2510  *      The BMU own bit of all descriptors is cleared, the rest is
2511  *      done by calling FreeTxDescriptors.
2512  *
2513  * Returns: N/A
2514  */
2515 static void ClearTxRing(
2516 SK_AC   *pAC,           /* pointer to adapter context */
2517 TX_PORT *pTxPort)       /* pointer to tx prt struct */
2518 {
2519 TXD             *pTxd;          /* pointer to the current descriptor */
2520 int             i;
2521 unsigned long   Flags;
2522
2523         spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
2524         pTxd = pTxPort->pTxdRingHead;
2525         for (i=0; i<pAC->TxDescrPerRing; i++) {
2526                 pTxd->TBControl &= ~BMU_OWN;
2527                 pTxd = pTxd->pNextTxd;
2528         }
2529         FreeTxDescriptors(pAC, pTxPort);
2530         spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
2531 } /* ClearTxRing */
2532
2533 /*****************************************************************************
2534  *
2535  *      SkGeSetMacAddr - Set the hardware MAC address
2536  *
2537  * Description:
2538  *      This function sets the MAC address used by the adapter.
2539  *
2540  * Returns:
2541  *      0, if everything is ok
2542  *      !=0, on error
2543  */
2544 static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
2545 {
2546
2547 DEV_NET *pNet = netdev_priv(dev);
2548 SK_AC   *pAC = pNet->pAC;
2549
2550 struct sockaddr *addr = p;
2551 unsigned long   Flags;
2552         
2553         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2554                 ("SkGeSetMacAddr starts now...\n"));
2555         if(netif_running(dev))
2556                 return -EBUSY;
2557
2558         memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
2559         
2560         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2561
2562         if (pAC->RlmtNets == 2)
2563                 SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
2564                         (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2565         else
2566                 SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
2567                         (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2568
2569         
2570         
2571         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2572         return 0;
2573 } /* SkGeSetMacAddr */
2574
2575
2576 /*****************************************************************************
2577  *
2578  *      SkGeSetRxMode - set receive mode
2579  *
2580  * Description:
2581  *      This function sets the receive mode of an adapter. The adapter
2582  *      supports promiscuous mode, allmulticast mode and a number of
2583  *      multicast addresses. If more multicast addresses the available
2584  *      are selected, a hash function in the hardware is used.
2585  *
2586  * Returns:
2587  *      0, if everything is ok
2588  *      !=0, on error
2589  */
2590 static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
2591 {
2592
2593 DEV_NET         *pNet;
2594 SK_AC           *pAC;
2595
2596 struct dev_mc_list      *pMcList;
2597 int                     i;
2598 int                     PortIdx;
2599 unsigned long           Flags;
2600
2601         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2602                 ("SkGeSetRxMode starts now... "));
2603
2604         pNet = netdev_priv(dev);
2605         pAC = pNet->pAC;
2606         if (pAC->RlmtNets == 1)
2607                 PortIdx = pAC->ActivePort;
2608         else
2609                 PortIdx = pNet->NetNr;
2610
2611         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2612         if (dev->flags & IFF_PROMISC) {
2613                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2614                         ("PROMISCUOUS mode\n"));
2615                 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2616                         SK_PROM_MODE_LLC);
2617         } else if (dev->flags & IFF_ALLMULTI) {
2618                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2619                         ("ALLMULTI mode\n"));
2620                 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2621                         SK_PROM_MODE_ALL_MC);
2622         } else {
2623                 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2624                         SK_PROM_MODE_NONE);
2625                 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
2626
2627                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2628                         ("Number of MC entries: %d ", dev->mc_count));
2629                 
2630                 pMcList = dev->mc_list;
2631                 for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
2632                         SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
2633                                 (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
2634                         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
2635                                 ("%02x:%02x:%02x:%02x:%02x:%02x\n",
2636                                 pMcList->dmi_addr[0],
2637                                 pMcList->dmi_addr[1],
2638                                 pMcList->dmi_addr[2],
2639                                 pMcList->dmi_addr[3],
2640                                 pMcList->dmi_addr[4],
2641                                 pMcList->dmi_addr[5]));
2642                 }
2643                 SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
2644         }
2645         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2646         
2647         return;
2648 } /* SkGeSetRxMode */
2649
2650
2651 /*****************************************************************************
2652  *
2653  *      SkGeChangeMtu - set the MTU to another value
2654  *
2655  * Description:
2656  *      This function sets is called whenever the MTU size is changed
2657  *      (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
2658  *      ethernet MTU size, long frame support is activated.
2659  *
2660  * Returns:
2661  *      0, if everything is ok
2662  *      !=0, on error
2663  */
2664 static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
2665 {
2666 DEV_NET         *pNet;
2667 DEV_NET         *pOtherNet;
2668 SK_AC           *pAC;
2669 unsigned long   Flags;
2670 int             i;
2671 SK_EVPARA       EvPara;
2672
2673         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2674                 ("SkGeChangeMtu starts now...\n"));
2675
2676         pNet = netdev_priv(dev);
2677         pAC  = pNet->pAC;
2678
2679         if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
2680                 return -EINVAL;
2681         }
2682
2683         if(pAC->BoardLevel != SK_INIT_RUN) {
2684                 return -EINVAL;
2685         }
2686
2687 #ifdef SK_DIAG_SUPPORT
2688         if (pAC->DiagModeActive == DIAG_ACTIVE) {
2689                 if (pAC->DiagFlowCtrl == SK_FALSE) {
2690                         return -1; /* still in use, deny any actions of MTU */
2691                 } else {
2692                         pAC->DiagFlowCtrl = SK_FALSE;
2693                 }
2694         }
2695 #endif
2696
2697         pNet->Mtu = NewMtu;
2698         pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
2699         if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
2700                 return(0);
2701         }
2702
2703         pAC->RxBufSize = NewMtu + 32;
2704         dev->mtu = NewMtu;
2705
2706         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2707                 ("New MTU: %d\n", NewMtu));
2708
2709         /* 
2710         ** Prevent any reconfiguration while changing the MTU 
2711         ** by disabling any interrupts 
2712         */
2713         SK_OUT32(pAC->IoBase, B0_IMSK, 0);
2714         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2715
2716         /* 
2717         ** Notify RLMT that any ports are to be stopped
2718         */
2719         EvPara.Para32[0] =  0;
2720         EvPara.Para32[1] = -1;
2721         if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2722                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2723                 EvPara.Para32[0] =  1;
2724                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2725         } else {
2726                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2727         }
2728
2729         /*
2730         ** After calling the SkEventDispatcher(), RLMT is aware about
2731         ** the stopped ports -> configuration can take place!
2732         */
2733         SkEventDispatcher(pAC, pAC->IoBase);
2734
2735         for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2736                 spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2737                 netif_stop_queue(pAC->dev[i]);
2738
2739         }
2740
2741         /*
2742         ** Depending on the desired MTU size change, a different number of 
2743         ** RX buffers need to be allocated
2744         */
2745         if (NewMtu > 1500) {
2746             /* 
2747             ** Use less rx buffers 
2748             */
2749             for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2750                 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2751                     pAC->RxPort[i].RxFillLimit =  pAC->RxDescrPerRing -
2752                                                  (pAC->RxDescrPerRing / 4);
2753                 } else {
2754                     if (i == pAC->ActivePort) {
2755                         pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
2756                                                     (pAC->RxDescrPerRing / 4);
2757                     } else {
2758                         pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
2759                                                     (pAC->RxDescrPerRing / 10);
2760                     }
2761                 }
2762             }
2763         } else {
2764             /* 
2765             ** Use the normal amount of rx buffers 
2766             */
2767             for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2768                 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2769                     pAC->RxPort[i].RxFillLimit = 1;
2770                 } else {
2771                     if (i == pAC->ActivePort) {
2772                         pAC->RxPort[i].RxFillLimit = 1;
2773                     } else {
2774                         pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2775                                                     (pAC->RxDescrPerRing / 4);
2776                     }
2777                 }
2778             }
2779         }
2780         
2781         SkGeDeInit(pAC, pAC->IoBase);
2782
2783         /*
2784         ** enable/disable hardware support for long frames
2785         */
2786         if (NewMtu > 1500) {
2787 // pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
2788                 pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
2789         } else {
2790             if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2791                 pAC->GIni.GIPortUsage = SK_MUL_LINK;
2792             } else {
2793                 pAC->GIni.GIPortUsage = SK_RED_LINK;
2794             }
2795         }
2796
2797         SkGeInit(   pAC, pAC->IoBase, SK_INIT_IO);
2798         SkI2cInit(  pAC, pAC->IoBase, SK_INIT_IO);
2799         SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
2800         SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
2801         SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
2802         SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
2803         SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
2804         
2805         /*
2806         ** tschilling:
2807         ** Speed and others are set back to default in level 1 init!
2808         */
2809         GetConfiguration(pAC);
2810         
2811         SkGeInit(   pAC, pAC->IoBase, SK_INIT_RUN);
2812         SkI2cInit(  pAC, pAC->IoBase, SK_INIT_RUN);
2813         SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
2814         SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
2815         SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
2816         SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
2817         SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
2818
2819         /*
2820         ** clear and reinit the rx rings here
2821         */
2822         for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2823                 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
2824                 ClearRxRing(pAC, &pAC->RxPort[i]);
2825                 FillRxRing(pAC, &pAC->RxPort[i]);
2826
2827                 /* 
2828                 ** Enable transmit descriptor polling
2829                 */
2830                 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
2831                 FillRxRing(pAC, &pAC->RxPort[i]);
2832         };
2833
2834         SkGeYellowLED(pAC, pAC->IoBase, 1);
2835         SkDimEnableModerationIfNeeded(pAC);     
2836         SkDimDisplayModerationSettings(pAC);
2837
2838         netif_start_queue(pAC->dev[pNet->PortNr]);
2839         for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
2840                 spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2841         }
2842
2843         /* 
2844         ** Enable Interrupts again 
2845         */
2846         SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
2847         SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
2848
2849         SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2850         SkEventDispatcher(pAC, pAC->IoBase);
2851
2852         /* 
2853         ** Notify RLMT about the changing and restarting one (or more) ports
2854         */
2855         if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2856                 EvPara.Para32[0] = pAC->RlmtNets;
2857                 EvPara.Para32[1] = -1;
2858                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
2859                 EvPara.Para32[0] = pNet->PortNr;
2860                 EvPara.Para32[1] = -1;
2861                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2862                         
2863                 if (pOtherNet->Up) {
2864                         EvPara.Para32[0] = pOtherNet->PortNr;
2865                         SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2866                 }
2867         } else {
2868                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2869         }
2870
2871         SkEventDispatcher(pAC, pAC->IoBase);
2872         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2873         
2874         /*
2875         ** While testing this driver with latest kernel 2.5 (2.5.70), it 
2876         ** seems as if upper layers have a problem to handle a successful
2877         ** return value of '0'. If such a zero is returned, the complete 
2878         ** system hangs for several minutes (!), which is in acceptable.
2879         **
2880         ** Currently it is not clear, what the exact reason for this problem
2881         ** is. The implemented workaround for 2.5 is to return the desired 
2882         ** new MTU size if all needed changes for the new MTU size where 
2883         ** performed. In kernels 2.2 and 2.4, a zero value is returned,
2884         ** which indicates the successful change of the mtu-size.
2885         */
2886         return NewMtu;
2887
2888 } /* SkGeChangeMtu */
2889
2890
2891 /*****************************************************************************
2892  *
2893  *      SkGeStats - return ethernet device statistics
2894  *
2895  * Description:
2896  *      This function return statistic data about the ethernet device
2897  *      to the operating system.
2898  *
2899  * Returns:
2900  *      pointer to the statistic structure.
2901  */
2902 static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
2903 {
2904 DEV_NET *pNet = netdev_priv(dev);
2905 SK_AC   *pAC = pNet->pAC;
2906 SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
2907 SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
2908 SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
2909 unsigned int    Size;                   /* size of pnmi struct */
2910 unsigned long   Flags;                  /* for spin lock */
2911
2912         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2913                 ("SkGeStats starts now...\n"));
2914         pPnmiStruct = &pAC->PnmiStruct;
2915
2916 #ifdef SK_DIAG_SUPPORT
2917         if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
2918                 (pAC->BoardLevel == SK_INIT_RUN)) {
2919 #endif
2920         SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
2921         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2922         Size = SK_PNMI_STRUCT_SIZE;
2923                 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
2924         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2925 #ifdef SK_DIAG_SUPPORT
2926         }
2927 #endif
2928
2929         pPnmiStat = &pPnmiStruct->Stat[0];
2930         pPnmiConf = &pPnmiStruct->Conf[0];
2931
2932         pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
2933         pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
2934         pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
2935         pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
2936         
2937         if (pNet->Mtu <= 1500) {
2938                 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
2939         } else {
2940                 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
2941                         pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
2942         }
2943
2944
2945         if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
2946                 pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
2947
2948         pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2949         pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
2950         pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
2951         pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
2952         pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2953
2954         /* detailed rx_errors: */
2955         pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
2956         pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2957         pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
2958         pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
2959         pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2960         pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
2961
2962         /* detailed tx_errors */
2963         pAC->stats.tx_aborted_errors = (SK_U32) 0;
2964         pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2965         pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
2966         pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2967         pAC->stats.tx_window_errors = (SK_U32) 0;
2968
2969         return(&pAC->stats);
2970 } /* SkGeStats */
2971
2972
2973 /*****************************************************************************
2974  *
2975  *      SkGeIoctl - IO-control function
2976  *
2977  * Description:
2978  *      This function is called if an ioctl is issued on the device.
2979  *      There are three subfunction for reading, writing and test-writing
2980  *      the private MIB data structure (usefull for SysKonnect-internal tools).
2981  *
2982  * Returns:
2983  *      0, if everything is ok
2984  *      !=0, on error
2985  */
2986 static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
2987 {
2988 DEV_NET         *pNet;
2989 SK_AC           *pAC;
2990 void            *pMemBuf;
2991 struct pci_dev  *pdev = NULL;
2992 SK_GE_IOCTL     Ioctl;
2993 unsigned int    Err = 0;
2994 int             Size = 0;
2995 int             Ret = 0;
2996 unsigned int    Length = 0;
2997 int             HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
2998
2999         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3000                 ("SkGeIoctl starts now...\n"));
3001
3002         pNet = netdev_priv(dev);
3003         pAC = pNet->pAC;
3004         
3005         if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
3006                 return -EFAULT;
3007         }
3008
3009         switch(cmd) {
3010         case SK_IOCTL_SETMIB:
3011         case SK_IOCTL_PRESETMIB:
3012                 if (!capable(CAP_NET_ADMIN)) return -EPERM;
3013         case SK_IOCTL_GETMIB:
3014                 if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
3015                         Ioctl.Len<sizeof(pAC->PnmiStruct)?
3016                         Ioctl.Len : sizeof(pAC->PnmiStruct))) {
3017                         return -EFAULT;
3018                 }
3019                 Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
3020                 if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
3021                         Ioctl.Len<Size? Ioctl.Len : Size)) {
3022                         return -EFAULT;
3023                 }
3024                 Ioctl.Len = Size;
3025                 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3026                         return -EFAULT;
3027                 }
3028                 break;
3029         case SK_IOCTL_GEN:
3030                 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
3031                         Length = Ioctl.Len;
3032                 } else {
3033                         Length = sizeof(pAC->PnmiStruct) + HeaderLength;
3034                 }
3035                 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
3036                         return -ENOMEM;
3037                 }
3038                 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
3039                         Err = -EFAULT;
3040                         goto fault_gen;
3041                 }
3042                 if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
3043                         Err = -EFAULT;
3044                         goto fault_gen;
3045                 }
3046                 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3047                         Err = -EFAULT;
3048                         goto fault_gen;
3049                 }
3050                 Ioctl.Len = Length;
3051                 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3052                         Err = -EFAULT;
3053                         goto fault_gen;
3054                 }
3055 fault_gen:
3056                 kfree(pMemBuf); /* cleanup everything */
3057                 break;
3058 #ifdef SK_DIAG_SUPPORT
3059        case SK_IOCTL_DIAG:
3060                 if (!capable(CAP_NET_ADMIN)) return -EPERM;
3061                 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
3062                         Length = Ioctl.Len;
3063                 } else {
3064                         Length = sizeof(pAC->PnmiStruct) + HeaderLength;
3065                 }
3066                 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
3067                         return -ENOMEM;
3068                 }
3069                 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
3070                         Err = -EFAULT;
3071                         goto fault_diag;
3072                 }
3073                 pdev = pAC->PciDev;
3074                 Length = 3 * sizeof(SK_U32);  /* Error, Bus and Device */
3075                 /* 
3076                 ** While coding this new IOCTL interface, only a few lines of code
3077                 ** are to to be added. Therefore no dedicated function has been 
3078                 ** added. If more functionality is added, a separate function 
3079                 ** should be used...
3080                 */
3081                 * ((SK_U32 *)pMemBuf) = 0;
3082                 * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
3083                 * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
3084                 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3085                         Err = -EFAULT;
3086                         goto fault_diag;
3087                 }
3088                 Ioctl.Len = Length;
3089                 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3090                         Err = -EFAULT;
3091                         goto fault_diag;
3092                 }
3093 fault_diag:
3094                 kfree(pMemBuf); /* cleanup everything */
3095                 break;
3096 #endif
3097         default:
3098                 Err = -EOPNOTSUPP;
3099         }
3100
3101         return(Err);
3102
3103 } /* SkGeIoctl */
3104
3105
3106 /*****************************************************************************
3107  *
3108  *      SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
3109  *
3110  * Description:
3111  *      This function reads/writes the MIB data using PNMI (Private Network
3112  *      Management Interface).
3113  *      The destination for the data must be provided with the
3114  *      ioctl call and is given to the driver in the form of
3115  *      a user space address.
3116  *      Copying from the user-provided data area into kernel messages
3117  *      and back is done by copy_from_user and copy_to_user calls in
3118  *      SkGeIoctl.
3119  *
3120  * Returns:
3121  *      returned size from PNMI call
3122  */
3123 static int SkGeIocMib(
3124 DEV_NET         *pNet,  /* pointer to the adapter context */
3125 unsigned int    Size,   /* length of ioctl data */
3126 int             mode)   /* flag for set/preset */
3127 {
3128 unsigned long   Flags;  /* for spin lock */
3129 SK_AC           *pAC;
3130
3131         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3132                 ("SkGeIocMib starts now...\n"));
3133         pAC = pNet->pAC;
3134         /* access MIB */
3135         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3136         switch(mode) {
3137         case SK_IOCTL_GETMIB:
3138                 SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3139                         pNet->NetNr);
3140                 break;
3141         case SK_IOCTL_PRESETMIB:
3142                 SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3143                         pNet->NetNr);
3144                 break;
3145         case SK_IOCTL_SETMIB:
3146                 SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3147                         pNet->NetNr);
3148                 break;
3149         default:
3150                 break;
3151         }
3152         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3153         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3154                 ("MIB data access succeeded\n"));
3155         return (Size);
3156 } /* SkGeIocMib */
3157
3158
3159 /*****************************************************************************
3160  *
3161  *      GetConfiguration - read configuration information
3162  *
3163  * Description:
3164  *      This function reads per-adapter configuration information from
3165  *      the options provided on the command line.
3166  *
3167  * Returns:
3168  *      none
3169  */
3170 static void GetConfiguration(
3171 SK_AC   *pAC)   /* pointer to the adapter context structure */
3172 {
3173 SK_I32  Port;           /* preferred port */
3174 SK_BOOL AutoSet;
3175 SK_BOOL DupSet;
3176 int     LinkSpeed          = SK_LSPEED_AUTO;    /* Link speed */
3177 int     AutoNeg            = 1;                 /* autoneg off (0) or on (1) */
3178 int     DuplexCap          = 0;                 /* 0=both,1=full,2=half */
3179 int     FlowCtrl           = SK_FLOW_MODE_SYM_OR_REM;   /* FlowControl  */
3180 int     MSMode             = SK_MS_MODE_AUTO;   /* master/slave mode    */
3181
3182 SK_BOOL IsConTypeDefined   = SK_TRUE;
3183 SK_BOOL IsLinkSpeedDefined = SK_TRUE;
3184 SK_BOOL IsFlowCtrlDefined  = SK_TRUE;
3185 SK_BOOL IsRoleDefined      = SK_TRUE;
3186 SK_BOOL IsModeDefined      = SK_TRUE;
3187 /*
3188  *      The two parameters AutoNeg. and DuplexCap. map to one configuration
3189  *      parameter. The mapping is described by this table:
3190  *      DuplexCap ->    |       both    |       full    |       half    |
3191  *      AutoNeg         |               |               |               |
3192  *      -----------------------------------------------------------------
3193  *      Off             |    illegal    |       Full    |       Half    |
3194  *      -----------------------------------------------------------------
3195  *      On              |   AutoBoth    |   AutoFull    |   AutoHalf    |
3196  *      -----------------------------------------------------------------
3197  *      Sense           |   AutoSense   |   AutoSense   |   AutoSense   |
3198  */
3199 int     Capabilities[3][3] =
3200                 { {                -1, SK_LMODE_FULL     , SK_LMODE_HALF     },
3201                   {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
3202                   {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
3203
3204 #define DC_BOTH 0
3205 #define DC_FULL 1
3206 #define DC_HALF 2
3207 #define AN_OFF  0
3208 #define AN_ON   1
3209 #define AN_SENS 2
3210 #define M_CurrPort pAC->GIni.GP[Port]
3211
3212
3213         /*
3214         ** Set the default values first for both ports!
3215         */
3216         for (Port = 0; Port < SK_MAX_MACS; Port++) {
3217                 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3218                 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3219                 M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3220                 M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
3221         }
3222
3223         /*
3224         ** Check merged parameter ConType. If it has not been used,
3225         ** verify any other parameter (e.g. AutoNeg) and use default values. 
3226         **
3227         ** Stating both ConType and other lowlevel link parameters is also
3228         ** possible. If this is the case, the passed ConType-parameter is 
3229         ** overwritten by the lowlevel link parameter.
3230         **
3231         ** The following settings are used for a merged ConType-parameter:
3232         **
3233         ** ConType   DupCap   AutoNeg   FlowCtrl      Role      Speed
3234         ** -------   ------   -------   --------   ----------   -----
3235         **  Auto      Both      On      SymOrRem      Auto       Auto
3236         **  100FD     Full      Off       None      <ignored>    100
3237         **  100HD     Half      Off       None      <ignored>    100
3238         **  10FD      Full      Off       None      <ignored>    10
3239         **  10HD      Half      Off       None      <ignored>    10
3240         ** 
3241         ** This ConType parameter is used for all ports of the adapter!
3242         */
3243         if ( (ConType != NULL)                && 
3244              (pAC->Index < SK_MAX_CARD_PARAM) &&
3245              (ConType[pAC->Index] != NULL) ) {
3246
3247                         /* Check chipset family */
3248                         if ((!pAC->ChipsetType) && 
3249                                 (strcmp(ConType[pAC->Index],"Auto")!=0) &&
3250                                 (strcmp(ConType[pAC->Index],"")!=0)) {
3251                                 /* Set the speed parameter back */
3252                                         printk("sk98lin: Illegal value \"%s\" " 
3253                                                         "for ConType."
3254                                                         " Using Auto.\n", 
3255                                                         ConType[pAC->Index]);
3256
3257                                         sprintf(ConType[pAC->Index], "Auto");   
3258                         }
3259
3260                                 if (strcmp(ConType[pAC->Index],"")==0) {
3261                         IsConTypeDefined = SK_FALSE; /* No ConType defined */
3262                                 } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
3263                     for (Port = 0; Port < SK_MAX_MACS; Port++) {
3264                         M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3265                         M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3266                         M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3267                         M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
3268                     }
3269                 } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
3270                     for (Port = 0; Port < SK_MAX_MACS; Port++) {
3271                         M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3272                         M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3273                         M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3274                         M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
3275                     }
3276                 } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
3277                     for (Port = 0; Port < SK_MAX_MACS; Port++) {
3278                         M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3279                         M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3280                         M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3281                         M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
3282                     }
3283                 } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
3284                     for (Port = 0; Port < SK_MAX_MACS; Port++) {
3285                         M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3286                         M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3287                         M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3288                         M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
3289                     }
3290                 } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
3291                     for (Port = 0; Port < SK_MAX_MACS; Port++) {
3292                         M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3293                         M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3294                         M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
3295                         M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
3296                     }
3297                 } else { 
3298                     printk("sk98lin: Illegal value \"%s\" for ConType\n", 
3299                         ConType[pAC->Index]);
3300                     IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
3301                 }
3302         } else {
3303             IsConTypeDefined = SK_FALSE; /* No ConType defined */
3304         }
3305
3306         /*
3307         ** Parse any parameter settings for port A:
3308         ** a) any LinkSpeed stated?
3309         */
3310         if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3311                 Speed_A[pAC->Index] != NULL) {
3312                 if (strcmp(Speed_A[pAC->Index],"")==0) {
3313                     IsLinkSpeedDefined = SK_FALSE;
3314                 } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
3315                     LinkSpeed = SK_LSPEED_AUTO;
3316                 } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
3317                     LinkSpeed = SK_LSPEED_10MBPS;
3318                 } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
3319                     LinkSpeed = SK_LSPEED_100MBPS;
3320                 } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
3321                     LinkSpeed = SK_LSPEED_1000MBPS;
3322                 } else {
3323                     printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
3324                         Speed_A[pAC->Index]);
3325                     IsLinkSpeedDefined = SK_FALSE;
3326                 }
3327         } else {
3328             IsLinkSpeedDefined = SK_FALSE;
3329         }
3330
3331         /* 
3332         ** Check speed parameter: 
3333         **    Only copper type adapter and GE V2 cards 
3334         */
3335         if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3336                 ((LinkSpeed != SK_LSPEED_AUTO) &&
3337                 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3338                 printk("sk98lin: Illegal value for Speed_A. "
3339                         "Not a copper card or GE V2 card\n    Using "
3340                         "speed 1000\n");
3341                 LinkSpeed = SK_LSPEED_1000MBPS;
3342         }
3343         
3344         /*      
3345         ** Decide whether to set new config value if somethig valid has
3346         ** been received.
3347         */
3348         if (IsLinkSpeedDefined) {
3349                 pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
3350         } 
3351
3352         /* 
3353         ** b) Any Autonegotiation and DuplexCapabilities set?
3354         **    Please note that both belong together...
3355         */
3356         AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
3357         AutoSet = SK_FALSE;
3358         if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3359                 AutoNeg_A[pAC->Index] != NULL) {
3360                 AutoSet = SK_TRUE;
3361                 if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
3362                     AutoSet = SK_FALSE;
3363                 } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
3364                     AutoNeg = AN_ON;
3365                 } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
3366                     AutoNeg = AN_OFF;
3367                 } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
3368                     AutoNeg = AN_SENS;
3369                 } else {
3370                     printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
3371                         AutoNeg_A[pAC->Index]);
3372                 }
3373         }
3374
3375         DuplexCap = DC_BOTH;
3376         DupSet    = SK_FALSE;
3377         if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3378                 DupCap_A[pAC->Index] != NULL) {
3379                 DupSet = SK_TRUE;
3380                 if (strcmp(DupCap_A[pAC->Index],"")==0) {
3381                     DupSet = SK_FALSE;
3382                 } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
3383                     DuplexCap = DC_BOTH;
3384                 } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
3385                     DuplexCap = DC_FULL;
3386                 } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
3387                     DuplexCap = DC_HALF;
3388                 } else {
3389                     printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
3390                         DupCap_A[pAC->Index]);
3391                 }
3392         }
3393
3394         /* 
3395         ** Check for illegal combinations 
3396         */
3397         if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3398                 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3399                 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3400                 (pAC->ChipsetType)) {
3401                     printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3402                                         "    Using Full Duplex.\n");
3403                                 DuplexCap = DC_FULL;
3404         }
3405
3406         if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
3407                 printk("sk98lin, Port A: DuplexCapabilities"
3408                         " ignored using Sense mode\n");
3409         }
3410
3411         if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3412                 printk("sk98lin: Port A: Illegal combination"
3413                         " of values AutoNeg. and DuplexCap.\n    Using "
3414                         "Full Duplex\n");
3415                 DuplexCap = DC_FULL;
3416         }
3417
3418         if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3419                 DuplexCap = DC_FULL;
3420         }
3421         
3422         if (!AutoSet && DupSet) {
3423                 printk("sk98lin: Port A: Duplex setting not"
3424                         " possible in\n    default AutoNegotiation mode"
3425                         " (Sense).\n    Using AutoNegotiation On\n");
3426                 AutoNeg = AN_ON;
3427         }
3428         
3429         /* 
3430         ** set the desired mode 
3431         */
3432         if (AutoSet || DupSet) {
3433             pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3434         }
3435         
3436         /* 
3437         ** c) Any Flowcontrol-parameter set?
3438         */
3439         if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3440                 FlowCtrl_A[pAC->Index] != NULL) {
3441                 if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
3442                     IsFlowCtrlDefined = SK_FALSE;
3443                 } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
3444                     FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3445                 } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
3446                     FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3447                 } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
3448                     FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3449                 } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
3450                     FlowCtrl = SK_FLOW_MODE_NONE;
3451                 } else {
3452                     printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
3453                         FlowCtrl_A[pAC->Index]);
3454                     IsFlowCtrlDefined = SK_FALSE;
3455                 }
3456         } else {
3457            IsFlowCtrlDefined = SK_FALSE;
3458         }
3459
3460         if (IsFlowCtrlDefined) {
3461             if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3462                 printk("sk98lin: Port A: FlowControl"
3463                         " impossible without AutoNegotiation,"
3464                         " disabled\n");
3465                 FlowCtrl = SK_FLOW_MODE_NONE;
3466             }
3467             pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
3468         }
3469
3470         /*
3471         ** d) What is with the RoleParameter?
3472         */
3473         if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3474                 Role_A[pAC->Index] != NULL) {
3475                 if (strcmp(Role_A[pAC->Index],"")==0) {
3476                    IsRoleDefined = SK_FALSE;
3477                 } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
3478                     MSMode = SK_MS_MODE_AUTO;
3479                 } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
3480                     MSMode = SK_MS_MODE_MASTER;
3481                 } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
3482                     MSMode = SK_MS_MODE_SLAVE;
3483                 } else {
3484                     printk("sk98lin: Illegal value \"%s\" for Role_A\n",
3485                         Role_A[pAC->Index]);
3486                     IsRoleDefined = SK_FALSE;
3487                 }
3488         } else {
3489            IsRoleDefined = SK_FALSE;
3490         }
3491
3492         if (IsRoleDefined == SK_TRUE) {
3493             pAC->GIni.GP[0].PMSMode = MSMode;
3494         }
3495         
3496
3497         
3498         /* 
3499         ** Parse any parameter settings for port B:
3500         ** a) any LinkSpeed stated?
3501         */
3502         IsConTypeDefined   = SK_TRUE;
3503         IsLinkSpeedDefined = SK_TRUE;
3504         IsFlowCtrlDefined  = SK_TRUE;
3505         IsModeDefined      = SK_TRUE;
3506
3507         if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3508                 Speed_B[pAC->Index] != NULL) {
3509                 if (strcmp(Speed_B[pAC->Index],"")==0) {
3510                     IsLinkSpeedDefined = SK_FALSE;
3511                 } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
3512                     LinkSpeed = SK_LSPEED_AUTO;
3513                 } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
3514                     LinkSpeed = SK_LSPEED_10MBPS;
3515                 } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
3516                     LinkSpeed = SK_LSPEED_100MBPS;
3517                 } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
3518                     LinkSpeed = SK_LSPEED_1000MBPS;
3519                 } else {
3520                     printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
3521                         Speed_B[pAC->Index]);
3522                     IsLinkSpeedDefined = SK_FALSE;
3523                 }
3524         } else {
3525             IsLinkSpeedDefined = SK_FALSE;
3526         }
3527
3528         /* 
3529         ** Check speed parameter:
3530         **    Only copper type adapter and GE V2 cards 
3531         */
3532         if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3533                 ((LinkSpeed != SK_LSPEED_AUTO) &&
3534                 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3535                 printk("sk98lin: Illegal value for Speed_B. "
3536                         "Not a copper card or GE V2 card\n    Using "
3537                         "speed 1000\n");
3538                 LinkSpeed = SK_LSPEED_1000MBPS;
3539         }
3540
3541         /*      
3542         ** Decide whether to set new config value if somethig valid has
3543         ** been received.
3544         */
3545         if (IsLinkSpeedDefined) {
3546             pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
3547         }
3548
3549         /* 
3550         ** b) Any Autonegotiation and DuplexCapabilities set?
3551         **    Please note that both belong together...
3552         */
3553         AutoNeg = AN_SENS; /* default: do auto Sense */
3554         AutoSet = SK_FALSE;
3555         if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3556                 AutoNeg_B[pAC->Index] != NULL) {
3557                 AutoSet = SK_TRUE;
3558                 if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
3559                     AutoSet = SK_FALSE;
3560                 } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
3561                     AutoNeg = AN_ON;
3562                 } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
3563                     AutoNeg = AN_OFF;
3564                 } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
3565                     AutoNeg = AN_SENS;
3566                 } else {
3567                     printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
3568                         AutoNeg_B[pAC->Index]);
3569                 }
3570         }
3571
3572         DuplexCap = DC_BOTH;
3573         DupSet    = SK_FALSE;
3574         if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3575                 DupCap_B[pAC->Index] != NULL) {
3576                 DupSet = SK_TRUE;
3577                 if (strcmp(DupCap_B[pAC->Index],"")==0) {
3578                     DupSet = SK_FALSE;
3579                 } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
3580                     DuplexCap = DC_BOTH;
3581                 } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
3582                     DuplexCap = DC_FULL;
3583                 } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
3584                     DuplexCap = DC_HALF;
3585                 } else {
3586                     printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
3587                         DupCap_B[pAC->Index]);
3588                 }
3589         }
3590
3591         
3592         /* 
3593         ** Check for illegal combinations 
3594         */
3595         if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3596                 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3597                 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3598                 (pAC->ChipsetType)) {
3599                     printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3600                                         "    Using Full Duplex.\n");
3601                                 DuplexCap = DC_FULL;
3602         }
3603
3604         if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3605                 printk("sk98lin, Port B: DuplexCapabilities"
3606                         " ignored using Sense mode\n");
3607         }
3608
3609         if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3610                 printk("sk98lin: Port B: Illegal combination"
3611                         " of values AutoNeg. and DuplexCap.\n    Using "
3612                         "Full Duplex\n");
3613                 DuplexCap = DC_FULL;
3614         }
3615
3616         if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3617                 DuplexCap = DC_FULL;
3618         }
3619         
3620         if (!AutoSet && DupSet) {
3621                 printk("sk98lin: Port B: Duplex setting not"
3622                         " possible in\n    default AutoNegotiation mode"
3623                         " (Sense).\n    Using AutoNegotiation On\n");
3624                 AutoNeg = AN_ON;
3625         }
3626
3627         /* 
3628         ** set the desired mode 
3629         */
3630         if (AutoSet || DupSet) {
3631             pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3632         }
3633
3634         /*
3635         ** c) Any FlowCtrl parameter set?
3636         */
3637         if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3638                 FlowCtrl_B[pAC->Index] != NULL) {
3639                 if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
3640                     IsFlowCtrlDefined = SK_FALSE;
3641                 } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
3642                     FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3643                 } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
3644                     FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3645                 } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
3646                     FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3647                 } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
3648                     FlowCtrl = SK_FLOW_MODE_NONE;
3649                 } else {
3650                     printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
3651                         FlowCtrl_B[pAC->Index]);
3652                     IsFlowCtrlDefined = SK_FALSE;
3653                 }
3654         } else {
3655                 IsFlowCtrlDefined = SK_FALSE;
3656         }
3657
3658         if (IsFlowCtrlDefined) {
3659             if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3660                 printk("sk98lin: Port B: FlowControl"
3661                         " impossible without AutoNegotiation,"
3662                         " disabled\n");
3663                 FlowCtrl = SK_FLOW_MODE_NONE;
3664             }
3665             pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
3666         }
3667
3668         /*
3669         ** d) What is the RoleParameter?
3670         */
3671         if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3672                 Role_B[pAC->Index] != NULL) {
3673                 if (strcmp(Role_B[pAC->Index],"")==0) {
3674                     IsRoleDefined = SK_FALSE;
3675                 } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
3676                     MSMode = SK_MS_MODE_AUTO;
3677                 } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
3678                     MSMode = SK_MS_MODE_MASTER;
3679                 } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
3680                     MSMode = SK_MS_MODE_SLAVE;
3681                 } else {
3682                     printk("sk98lin: Illegal value \"%s\" for Role_B\n",
3683                         Role_B[pAC->Index]);
3684                     IsRoleDefined = SK_FALSE;
3685                 }
3686         } else {
3687             IsRoleDefined = SK_FALSE;
3688         }
3689
3690         if (IsRoleDefined) {
3691             pAC->GIni.GP[1].PMSMode = MSMode;
3692         }
3693         
3694         /*
3695         ** Evaluate settings for both ports
3696         */
3697         pAC->ActivePort = 0;
3698         if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3699                 PrefPort[pAC->Index] != NULL) {
3700                 if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
3701                         pAC->ActivePort             =  0;
3702                         pAC->Rlmt.Net[0].Preference = -1; /* auto */
3703                         pAC->Rlmt.Net[0].PrefPort   =  0;
3704                 } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
3705                         /*
3706                         ** do not set ActivePort here, thus a port
3707                         ** switch is issued after net up.
3708                         */
3709                         Port                        = 0;
3710                         pAC->Rlmt.Net[0].Preference = Port;
3711                         pAC->Rlmt.Net[0].PrefPort   = Port;
3712                 } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
3713                         /*
3714                         ** do not set ActivePort here, thus a port
3715                         ** switch is issued after net up.
3716                         */
3717                         if (pAC->GIni.GIMacsFound == 1) {
3718                                 printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
3719                                         "      Port B not available on single port adapters.\n");
3720
3721                                 pAC->ActivePort             =  0;
3722                                 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3723                                 pAC->Rlmt.Net[0].PrefPort   =  0;
3724                         } else {
3725                                 Port                        = 1;
3726                                 pAC->Rlmt.Net[0].Preference = Port;
3727                                 pAC->Rlmt.Net[0].PrefPort   = Port;
3728                         }
3729                 } else {
3730                     printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
3731                         PrefPort[pAC->Index]);
3732                 }
3733         }
3734
3735         pAC->RlmtNets = 1;
3736
3737         if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3738                 RlmtMode[pAC->Index] != NULL) {
3739                 if (strcmp(RlmtMode[pAC->Index], "") == 0) {
3740                         pAC->RlmtMode = 0;
3741                 } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
3742                         pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3743                 } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
3744                         pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3745                                         SK_RLMT_CHECK_LOC_LINK;
3746                 } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
3747                         pAC->RlmtMode = SK_RLMT_CHECK_LINK     |
3748                                         SK_RLMT_CHECK_LOC_LINK |
3749                                         SK_RLMT_CHECK_SEG;
3750                 } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
3751                         (pAC->GIni.GIMacsFound == 2)) {
3752                         pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3753                         pAC->RlmtNets = 2;
3754                 } else {
3755                     printk("sk98lin: Illegal value \"%s\" for"
3756                         " RlmtMode, using default\n", 
3757                         RlmtMode[pAC->Index]);
3758                         pAC->RlmtMode = 0;
3759                 }
3760         } else {
3761                 pAC->RlmtMode = 0;
3762         }
3763         
3764         /*
3765         ** Check the interrupt moderation parameters
3766         */
3767         if (Moderation[pAC->Index] != NULL) {
3768                 if (strcmp(Moderation[pAC->Index], "") == 0) {
3769                         pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3770                 } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
3771                         pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
3772                 } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
3773                         pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
3774                 } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
3775                         pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3776                 } else {
3777                         printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
3778                                 "      Disable interrupt moderation.\n",
3779                                 Moderation[pAC->Index]);
3780                         pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3781                 }
3782         } else {
3783                 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3784         }
3785
3786         if (Stats[pAC->Index] != NULL) {
3787                 if (strcmp(Stats[pAC->Index], "Yes") == 0) {
3788                         pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
3789                 } else {
3790                         pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3791                 }
3792         } else {
3793                 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3794         }
3795
3796         if (ModerationMask[pAC->Index] != NULL) {
3797                 if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
3798                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3799                 } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
3800                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
3801                 } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
3802                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
3803                 } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
3804                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3805                 } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
3806                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3807                 } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
3808                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3809                 } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
3810                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3811                 } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
3812                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3813                 } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
3814                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3815                 } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
3816                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3817                 } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
3818                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3819                 } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
3820                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3821                 } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
3822                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3823                 } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
3824                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3825                 } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
3826                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3827                 } else { /* some rubbish */
3828                         pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3829                 }
3830         } else {  /* operator has stated nothing */
3831                 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3832         }
3833
3834         if (AutoSizing[pAC->Index] != NULL) {
3835                 if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
3836                         pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3837                 } else {
3838                         pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3839                 }
3840         } else {  /* operator has stated nothing */
3841                 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3842         }
3843
3844         if (IntsPerSec[pAC->Index] != 0) {
3845                 if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
3846                         (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
3847                         printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
3848                                 "      Using default value of %i.\n", 
3849                                 IntsPerSec[pAC->Index],
3850                                 C_INT_MOD_IPS_LOWER_RANGE,
3851                                 C_INT_MOD_IPS_UPPER_RANGE,
3852                                 C_INTS_PER_SEC_DEFAULT);
3853                         pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3854                 } else {
3855                         pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
3856                 }
3857         } else {
3858                 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3859         }
3860
3861         /*
3862         ** Evaluate upper and lower moderation threshold
3863         */
3864         pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
3865                 pAC->DynIrqModInfo.MaxModIntsPerSec +
3866                 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3867
3868         pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
3869                 pAC->DynIrqModInfo.MaxModIntsPerSec -
3870                 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3871
3872         pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
3873
3874
3875 } /* GetConfiguration */
3876
3877
3878 /*****************************************************************************
3879  *
3880  *      ProductStr - return a adapter identification string from vpd
3881  *
3882  * Description:
3883  *      This function reads the product name string from the vpd area
3884  *      and puts it the field pAC->DeviceString.
3885  *
3886  * Returns: N/A
3887  */
3888 static void ProductStr(
3889 SK_AC   *pAC            /* pointer to adapter context */
3890 )
3891 {
3892 int     StrLen = 80;            /* length of the string, defined in SK_AC */
3893 char    Keyword[] = VPD_NAME;   /* vpd productname identifier */
3894 int     ReturnCode;             /* return code from vpd_read */
3895 unsigned long Flags;
3896
3897         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3898         ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
3899                 &StrLen);
3900         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3901         if (ReturnCode != 0) {
3902                 /* there was an error reading the vpd data */
3903                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
3904                         ("Error reading VPD data: %d\n", ReturnCode));
3905                 pAC->DeviceStr[0] = '\0';
3906         }
3907 } /* ProductStr */
3908
3909 /*****************************************************************************
3910  *
3911  *      StartDrvCleanupTimer - Start timer to check for descriptors which
3912  *                             might be placed in descriptor ring, but
3913  *                             havent been handled up to now
3914  *
3915  * Description:
3916  *      This function requests a HW-timer fo the Yukon card. The actions to
3917  *      perform when this timer expires, are located in the SkDrvEvent().
3918  *
3919  * Returns: N/A
3920  */
3921 static void
3922 StartDrvCleanupTimer(SK_AC *pAC) {
3923     SK_EVPARA    EventParam;   /* Event struct for timer event */
3924
3925     SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
3926     EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
3927     SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
3928                  SK_DRV_RX_CLEANUP_TIMER_LENGTH,
3929                  SKGE_DRV, SK_DRV_TIMER, EventParam);
3930 }
3931
3932 /*****************************************************************************
3933  *
3934  *      StopDrvCleanupTimer - Stop timer to check for descriptors
3935  *
3936  * Description:
3937  *      This function requests a HW-timer fo the Yukon card. The actions to
3938  *      perform when this timer expires, are located in the SkDrvEvent().
3939  *
3940  * Returns: N/A
3941  */
3942 static void
3943 StopDrvCleanupTimer(SK_AC *pAC) {
3944     SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
3945     SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
3946 }
3947
3948 /****************************************************************************/
3949 /* functions for common modules *********************************************/
3950 /****************************************************************************/
3951
3952
3953 /*****************************************************************************
3954  *
3955  *      SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
3956  *
3957  * Description:
3958  *      This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
3959  *      is embedded into a socket buff data area.
3960  *
3961  * Context:
3962  *      runtime
3963  *
3964  * Returns:
3965  *      NULL or pointer to Mbuf.
3966  */
3967 SK_MBUF *SkDrvAllocRlmtMbuf(
3968 SK_AC           *pAC,           /* pointer to adapter context */
3969 SK_IOC          IoC,            /* the IO-context */
3970 unsigned        BufferSize)     /* size of the requested buffer */
3971 {
3972 SK_MBUF         *pRlmtMbuf;     /* pointer to a new rlmt-mbuf structure */
3973 struct sk_buff  *pMsgBlock;     /* pointer to a new message block */
3974
3975         pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
3976         if (pMsgBlock == NULL) {
3977                 return (NULL);
3978         }
3979         pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
3980         skb_reserve(pMsgBlock, sizeof(SK_MBUF));
3981         pRlmtMbuf->pNext = NULL;
3982         pRlmtMbuf->pOs = pMsgBlock;
3983         pRlmtMbuf->pData = pMsgBlock->data;     /* Data buffer. */
3984         pRlmtMbuf->Size = BufferSize;           /* Data buffer size. */
3985         pRlmtMbuf->Length = 0;          /* Length of packet (<= Size). */
3986         return (pRlmtMbuf);
3987
3988 } /* SkDrvAllocRlmtMbuf */
3989
3990
3991 /*****************************************************************************
3992  *
3993  *      SkDrvFreeRlmtMbuf - free an RLMT mbuf
3994  *
3995  * Description:
3996  *      This routine frees one or more RLMT mbuf(s).
3997  *
3998  * Context:
3999  *      runtime
4000  *
4001  * Returns:
4002  *      Nothing
4003  */
4004 void  SkDrvFreeRlmtMbuf(
4005 SK_AC           *pAC,           /* pointer to adapter context */
4006 SK_IOC          IoC,            /* the IO-context */
4007 SK_MBUF         *pMbuf)         /* size of the requested buffer */
4008 {
4009 SK_MBUF         *pFreeMbuf;
4010 SK_MBUF         *pNextMbuf;
4011
4012         pFreeMbuf = pMbuf;
4013         do {
4014                 pNextMbuf = pFreeMbuf->pNext;
4015                 DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
4016                 pFreeMbuf = pNextMbuf;
4017         } while ( pFreeMbuf != NULL );
4018 } /* SkDrvFreeRlmtMbuf */
4019
4020
4021 /*****************************************************************************
4022  *
4023  *      SkOsGetTime - provide a time value
4024  *
4025  * Description:
4026  *      This routine provides a time value. The unit is 1/HZ (defined by Linux).
4027  *      It is not used for absolute time, but only for time differences.
4028  *
4029  *
4030  * Returns:
4031  *      Time value
4032  */
4033 SK_U64 SkOsGetTime(SK_AC *pAC)
4034 {
4035         SK_U64  PrivateJiffies;
4036         SkOsGetTimeCurrent(pAC, &PrivateJiffies);
4037         return PrivateJiffies;
4038 } /* SkOsGetTime */
4039
4040
4041 /*****************************************************************************
4042  *
4043  *      SkPciReadCfgDWord - read a 32 bit value from pci config space
4044  *
4045  * Description:
4046  *      This routine reads a 32 bit value from the pci configuration
4047  *      space.
4048  *
4049  * Returns:
4050  *      0 - indicate everything worked ok.
4051  *      != 0 - error indication
4052  */
4053 int SkPciReadCfgDWord(
4054 SK_AC *pAC,             /* Adapter Control structure pointer */
4055 int PciAddr,            /* PCI register address */
4056 SK_U32 *pVal)           /* pointer to store the read value */
4057 {
4058         pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
4059         return(0);
4060 } /* SkPciReadCfgDWord */
4061
4062
4063 /*****************************************************************************
4064  *
4065  *      SkPciReadCfgWord - read a 16 bit value from pci config space
4066  *
4067  * Description:
4068  *      This routine reads a 16 bit value from the pci configuration
4069  *      space.
4070  *
4071  * Returns:
4072  *      0 - indicate everything worked ok.
4073  *      != 0 - error indication
4074  */
4075 int SkPciReadCfgWord(
4076 SK_AC *pAC,     /* Adapter Control structure pointer */
4077 int PciAddr,            /* PCI register address */
4078 SK_U16 *pVal)           /* pointer to store the read value */
4079 {
4080         pci_read_config_word(pAC->PciDev, PciAddr, pVal);
4081         return(0);
4082 } /* SkPciReadCfgWord */
4083
4084
4085 /*****************************************************************************
4086  *
4087  *      SkPciReadCfgByte - read a 8 bit value from pci config space
4088  *
4089  * Description:
4090  *      This routine reads a 8 bit value from the pci configuration
4091  *      space.
4092  *
4093  * Returns:
4094  *      0 - indicate everything worked ok.
4095  *      != 0 - error indication
4096  */
4097 int SkPciReadCfgByte(
4098 SK_AC *pAC,     /* Adapter Control structure pointer */
4099 int PciAddr,            /* PCI register address */
4100 SK_U8 *pVal)            /* pointer to store the read value */
4101 {
4102         pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
4103         return(0);
4104 } /* SkPciReadCfgByte */
4105
4106
4107 /*****************************************************************************
4108  *
4109  *      SkPciWriteCfgWord - write a 16 bit value to pci config space
4110  *
4111  * Description:
4112  *      This routine writes a 16 bit value to the pci configuration
4113  *      space. The flag PciConfigUp indicates whether the config space
4114  *      is accesible or must be set up first.
4115  *
4116  * Returns:
4117  *      0 - indicate everything worked ok.
4118  *      != 0 - error indication
4119  */
4120 int SkPciWriteCfgWord(
4121 SK_AC *pAC,     /* Adapter Control structure pointer */
4122 int PciAddr,            /* PCI register address */
4123 SK_U16 Val)             /* pointer to store the read value */
4124 {
4125         pci_write_config_word(pAC->PciDev, PciAddr, Val);
4126         return(0);
4127 } /* SkPciWriteCfgWord */
4128
4129
4130 /*****************************************************************************
4131  *
4132  *      SkPciWriteCfgWord - write a 8 bit value to pci config space
4133  *
4134  * Description:
4135  *      This routine writes a 8 bit value to the pci configuration
4136  *      space. The flag PciConfigUp indicates whether the config space
4137  *      is accesible or must be set up first.
4138  *
4139  * Returns:
4140  *      0 - indicate everything worked ok.
4141  *      != 0 - error indication
4142  */
4143 int SkPciWriteCfgByte(
4144 SK_AC *pAC,     /* Adapter Control structure pointer */
4145 int PciAddr,            /* PCI register address */
4146 SK_U8 Val)              /* pointer to store the read value */
4147 {
4148         pci_write_config_byte(pAC->PciDev, PciAddr, Val);
4149         return(0);
4150 } /* SkPciWriteCfgByte */
4151
4152
4153 /*****************************************************************************
4154  *
4155  *      SkDrvEvent - handle driver events
4156  *
4157  * Description:
4158  *      This function handles events from all modules directed to the driver
4159  *
4160  * Context:
4161  *      Is called under protection of slow path lock.
4162  *
4163  * Returns:
4164  *      0 if everything ok
4165  *      < 0  on error
4166  *      
4167  */
4168 int SkDrvEvent(
4169 SK_AC *pAC,             /* pointer to adapter context */
4170 SK_IOC IoC,             /* io-context */
4171 SK_U32 Event,           /* event-id */
4172 SK_EVPARA Param)        /* event-parameter */
4173 {
4174 SK_MBUF         *pRlmtMbuf;     /* pointer to a rlmt-mbuf structure */
4175 struct sk_buff  *pMsg;          /* pointer to a message block */
4176 int             FromPort;       /* the port from which we switch away */
4177 int             ToPort;         /* the port we switch to */
4178 SK_EVPARA       NewPara;        /* parameter for further events */
4179 int             Stat;
4180 unsigned long   Flags;
4181 SK_BOOL         DualNet;
4182
4183         switch (Event) {
4184         case SK_DRV_ADAP_FAIL:
4185                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4186                         ("ADAPTER FAIL EVENT\n"));
4187                 printk("%s: Adapter failed.\n", pAC->dev[0]->name);
4188                 /* disable interrupts */
4189                 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
4190                 /* cgoos */
4191                 break;
4192         case SK_DRV_PORT_FAIL:
4193                 FromPort = Param.Para32[0];
4194                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4195                         ("PORT FAIL EVENT, Port: %d\n", FromPort));
4196                 if (FromPort == 0) {
4197                         printk("%s: Port A failed.\n", pAC->dev[0]->name);
4198                 } else {
4199                         printk("%s: Port B failed.\n", pAC->dev[1]->name);
4200                 }
4201                 /* cgoos */
4202                 break;
4203         case SK_DRV_PORT_RESET:  /* SK_U32 PortIdx */
4204                 /* action list 4 */
4205                 FromPort = Param.Para32[0];
4206                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4207                         ("PORT RESET EVENT, Port: %d ", FromPort));
4208                 NewPara.Para64 = FromPort;
4209                 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4210                 spin_lock_irqsave(
4211                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4212                         Flags);
4213
4214                 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
4215                 netif_carrier_off(pAC->dev[Param.Para32[0]]);
4216                 spin_unlock_irqrestore(
4217                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4218                         Flags);
4219                 
4220                 /* clear rx ring from received frames */
4221                 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
4222                 
4223                 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4224                 spin_lock_irqsave(
4225                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4226                         Flags);
4227                 
4228                 /* tschilling: Handling of return value inserted. */
4229                 if (SkGeInitPort(pAC, IoC, FromPort)) {
4230                         if (FromPort == 0) {
4231                                 printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
4232                         } else {
4233                                 printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
4234                         }
4235                 }
4236                 SkAddrMcUpdate(pAC,IoC, FromPort);
4237                 PortReInitBmu(pAC, FromPort);
4238                 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4239                 ClearAndStartRx(pAC, FromPort);
4240                 spin_unlock_irqrestore(
4241                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4242                         Flags);
4243                 break;
4244         case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
4245                 /* action list 5 */
4246                 FromPort = Param.Para32[0];
4247                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4248                         ("NET UP EVENT, Port: %d ", Param.Para32[0]));
4249                 /* Mac update */
4250                 SkAddrMcUpdate(pAC,IoC, FromPort);
4251
4252                 if (DoPrintInterfaceChange) {
4253                 printk("%s: network connection up using"
4254                         " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
4255
4256                 /* tschilling: Values changed according to LinkSpeedUsed. */
4257                 Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
4258                 if (Stat == SK_LSPEED_STAT_10MBPS) {
4259                         printk("    speed:           10\n");
4260                 } else if (Stat == SK_LSPEED_STAT_100MBPS) {
4261                         printk("    speed:           100\n");
4262                 } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
4263                         printk("    speed:           1000\n");
4264                 } else {
4265                         printk("    speed:           unknown\n");
4266                 }
4267
4268
4269                 Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
4270                 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4271                         Stat == SK_LMODE_STAT_AUTOFULL) {
4272                         printk("    autonegotiation: yes\n");
4273                 }
4274                 else {
4275                         printk("    autonegotiation: no\n");
4276                 }
4277                 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4278                         Stat == SK_LMODE_STAT_HALF) {
4279                         printk("    duplex mode:     half\n");
4280                 }
4281                 else {
4282                         printk("    duplex mode:     full\n");
4283                 }
4284                 Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
4285                 if (Stat == SK_FLOW_STAT_REM_SEND ) {
4286                         printk("    flowctrl:        remote send\n");
4287                 }
4288                 else if (Stat == SK_FLOW_STAT_LOC_SEND ){
4289                         printk("    flowctrl:        local send\n");
4290                 }
4291                 else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
4292                         printk("    flowctrl:        symmetric\n");
4293                 }
4294                 else {
4295                         printk("    flowctrl:        none\n");
4296                 }
4297                 
4298                 /* tschilling: Check against CopperType now. */
4299                 if ((pAC->GIni.GICopperType == SK_TRUE) &&
4300                         (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
4301                         SK_LSPEED_STAT_1000MBPS)) {
4302                         Stat = pAC->GIni.GP[FromPort].PMSStatus;
4303                         if (Stat == SK_MS_STAT_MASTER ) {
4304                                 printk("    role:            master\n");
4305                         }
4306                         else if (Stat == SK_MS_STAT_SLAVE ) {
4307                                 printk("    role:            slave\n");
4308                         }
4309                         else {
4310                                 printk("    role:            ???\n");
4311                         }
4312                 }
4313
4314                 /* 
4315                    Display dim (dynamic interrupt moderation) 
4316                    informations
4317                  */
4318                 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
4319                         printk("    irq moderation:  static (%d ints/sec)\n",
4320                                         pAC->DynIrqModInfo.MaxModIntsPerSec);
4321                 else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
4322                         printk("    irq moderation:  dynamic (%d ints/sec)\n",
4323                                         pAC->DynIrqModInfo.MaxModIntsPerSec);
4324                 else
4325                         printk("    irq moderation:  disabled\n");
4326
4327
4328 #ifdef SK_ZEROCOPY
4329                 if (pAC->ChipsetType)
4330 #ifdef USE_SK_TX_CHECKSUM
4331                         printk("    scatter-gather:  enabled\n");
4332 #else
4333                         printk("    tx-checksum:     disabled\n");
4334 #endif
4335                 else
4336                         printk("    scatter-gather:  disabled\n");
4337 #else
4338                         printk("    scatter-gather:  disabled\n");
4339 #endif
4340
4341 #ifndef USE_SK_RX_CHECKSUM
4342                         printk("    rx-checksum:     disabled\n");
4343 #endif
4344
4345                 } else {
4346                         DoPrintInterfaceChange = SK_TRUE;
4347                 }
4348         
4349                 if ((Param.Para32[0] != pAC->ActivePort) &&
4350                         (pAC->RlmtNets == 1)) {
4351                         NewPara.Para32[0] = pAC->ActivePort;
4352                         NewPara.Para32[1] = Param.Para32[0];
4353                         SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
4354                                 NewPara);
4355                 }
4356
4357                 /* Inform the world that link protocol is up. */
4358                 netif_carrier_on(pAC->dev[Param.Para32[0]]);
4359
4360                 break;
4361         case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
4362                 /* action list 7 */
4363                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4364                         ("NET DOWN EVENT "));
4365                 if (DoPrintInterfaceChange) {
4366                         printk("%s: network connection down\n", 
4367                                 pAC->dev[Param.Para32[1]]->name);
4368                 } else {
4369                         DoPrintInterfaceChange = SK_TRUE;
4370                 }
4371                 netif_carrier_off(pAC->dev[Param.Para32[1]]);
4372                 break;
4373         case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4374                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4375                         ("PORT SWITCH HARD "));
4376         case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4377         /* action list 6 */
4378                 printk("%s: switching to port %c\n", pAC->dev[0]->name,
4379                         'A'+Param.Para32[1]);
4380         case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4381                 FromPort = Param.Para32[0];
4382                 ToPort = Param.Para32[1];
4383                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4384                         ("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
4385                         FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
4386                 NewPara.Para64 = FromPort;
4387                 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4388                 NewPara.Para64 = ToPort;
4389                 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4390                 spin_lock_irqsave(
4391                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4392                         Flags);
4393                 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4394                 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
4395                 SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
4396                 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4397                 spin_unlock_irqrestore(
4398                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4399                         Flags);
4400
4401                 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
4402                 ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
4403                 
4404                 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4405                 ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
4406                 spin_lock_irqsave(
4407                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4408                         Flags);
4409                 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4410                 pAC->ActivePort = ToPort;
4411 #if 0
4412                 SetQueueSizes(pAC);
4413 #else
4414                 /* tschilling: New common function with minimum size check. */
4415                 DualNet = SK_FALSE;
4416                 if (pAC->RlmtNets == 2) {
4417                         DualNet = SK_TRUE;
4418                 }
4419                 
4420                 if (SkGeInitAssignRamToQueues(
4421                         pAC,
4422                         pAC->ActivePort,
4423                         DualNet)) {
4424                         spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4425                         spin_unlock_irqrestore(
4426                                 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4427                                 Flags);
4428                         printk("SkGeInitAssignRamToQueues failed.\n");
4429                         break;
4430                 }
4431 #endif
4432                 /* tschilling: Handling of return values inserted. */
4433                 if (SkGeInitPort(pAC, IoC, FromPort) ||
4434                         SkGeInitPort(pAC, IoC, ToPort)) {
4435                         printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
4436                 }
4437                 if (Event == SK_DRV_SWITCH_SOFT) {
4438                         SkMacRxTxEnable(pAC, IoC, FromPort);
4439                 }
4440                 SkMacRxTxEnable(pAC, IoC, ToPort);
4441                 SkAddrSwap(pAC, IoC, FromPort, ToPort);
4442                 SkAddrMcUpdate(pAC, IoC, FromPort);
4443                 SkAddrMcUpdate(pAC, IoC, ToPort);
4444                 PortReInitBmu(pAC, FromPort);
4445                 PortReInitBmu(pAC, ToPort);
4446                 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4447                 SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
4448                 ClearAndStartRx(pAC, FromPort);
4449                 ClearAndStartRx(pAC, ToPort);
4450                 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4451                 spin_unlock_irqrestore(
4452                         &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4453                         Flags);
4454                 break;
4455         case SK_DRV_RLMT_SEND:   /* SK_MBUF *pMb */
4456                 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4457                         ("RLS "));
4458                 pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
4459                 pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
4460                 skb_put(pMsg, pRlmtMbuf->Length);
4461                 if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
4462                         pMsg) < 0)
4463
4464                         DEV_KFREE_SKB_ANY(pMsg);
4465                 break;
4466         case SK_DRV_TIMER:
4467                 if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
4468                         /*
4469                         ** expiration of the moderation timer implies that
4470                         ** dynamic moderation is to be applied
4471                         */
4472                         SkDimStartModerationTimer(pAC);
4473                         SkDimModerate(pAC);
4474                         if (pAC->DynIrqModInfo.DisplayStats) {
4475                             SkDimDisplayModerationSettings(pAC);
4476                         }
4477                 } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
4478                         /*
4479                         ** check if we need to check for descriptors which
4480                         ** haven't been handled the last millisecs
4481                         */
4482                         StartDrvCleanupTimer(pAC);
4483                         if (pAC->GIni.GIMacsFound == 2) {
4484                                 ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
4485                         }
4486                         ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
4487                 } else {
4488                         printk("Expiration of unknown timer\n");
4489                 }
4490                 break;
4491         default:
4492                 break;
4493         }
4494         SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4495                 ("END EVENT "));
4496         
4497         return (0);
4498 } /* SkDrvEvent */
4499
4500
4501 /*****************************************************************************
4502  *
4503  *      SkErrorLog - log errors
4504  *
4505  * Description:
4506  *      This function logs errors to the system buffer and to the console
4507  *
4508  * Returns:
4509  *      0 if everything ok
4510  *      < 0  on error
4511  *      
4512  */
4513 void SkErrorLog(
4514 SK_AC   *pAC,
4515 int     ErrClass,
4516 int     ErrNum,
4517 char    *pErrorMsg)
4518 {
4519 char    ClassStr[80];
4520
4521         switch (ErrClass) {
4522         case SK_ERRCL_OTHER:
4523                 strcpy(ClassStr, "Other error");
4524                 break;
4525         case SK_ERRCL_CONFIG:
4526                 strcpy(ClassStr, "Configuration error");
4527                 break;
4528         case SK_ERRCL_INIT:
4529                 strcpy(ClassStr, "Initialization error");
4530                 break;
4531         case SK_ERRCL_NORES:
4532                 strcpy(ClassStr, "Out of resources error");
4533                 break;
4534         case SK_ERRCL_SW:
4535                 strcpy(ClassStr, "internal Software error");
4536                 break;
4537         case SK_ERRCL_HW:
4538                 strcpy(ClassStr, "Hardware failure");
4539                 break;
4540         case SK_ERRCL_COMM:
4541                 strcpy(ClassStr, "Communication error");
4542                 break;
4543         }
4544         printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
4545                 "        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
4546                 ClassStr, ErrNum, pErrorMsg);
4547
4548 } /* SkErrorLog */
4549
4550 #ifdef SK_DIAG_SUPPORT
4551
4552 /*****************************************************************************
4553  *
4554  *      SkDrvEnterDiagMode - handles DIAG attach request
4555  *
4556  * Description:
4557  *      Notify the kernel to NOT access the card any longer due to DIAG
4558  *      Deinitialize the Card
4559  *
4560  * Returns:
4561  *      int
4562  */
4563 int SkDrvEnterDiagMode(
4564 SK_AC   *pAc)   /* pointer to adapter context */
4565 {
4566         DEV_NET *pNet = netdev_priv(pAc->dev[0]);
4567         SK_AC   *pAC  = pNet->pAC;
4568
4569         SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), 
4570                         sizeof(SK_PNMI_STRUCT_DATA));
4571
4572         pAC->DiagModeActive = DIAG_ACTIVE;
4573         if (pAC->BoardLevel > SK_INIT_DATA) {
4574                 if (pNet->Up) {
4575                         pAC->WasIfUp[0] = SK_TRUE;
4576                         pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
4577                         DoPrintInterfaceChange = SK_FALSE;
4578                         SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
4579                 } else {
4580                         pAC->WasIfUp[0] = SK_FALSE;
4581                 }
4582                 if (pNet != netdev_priv(pAC->dev[1])) {
4583                         pNet = netdev_priv(pAC->dev[1]);
4584                         if (pNet->Up) {
4585                                 pAC->WasIfUp[1] = SK_TRUE;
4586                                 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4587                                 DoPrintInterfaceChange = SK_FALSE;
4588                                 SkDrvDeInitAdapter(pAC, 1);  /* do SkGeClose  */
4589                         } else {
4590                                 pAC->WasIfUp[1] = SK_FALSE;
4591                         }
4592                 }
4593                 pAC->BoardLevel = SK_INIT_DATA;
4594         }
4595         return(0);
4596 }
4597
4598 /*****************************************************************************
4599  *
4600  *      SkDrvLeaveDiagMode - handles DIAG detach request
4601  *
4602  * Description:
4603  *      Notify the kernel to may access the card again after use by DIAG
4604  *      Initialize the Card
4605  *
4606  * Returns:
4607  *      int
4608  */
4609 int SkDrvLeaveDiagMode(
4610 SK_AC   *pAc)   /* pointer to adapter control context */
4611
4612         SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), 
4613                         sizeof(SK_PNMI_STRUCT_DATA));
4614         pAc->DiagModeActive    = DIAG_NOTACTIVE;
4615         pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
4616         if (pAc->WasIfUp[0] == SK_TRUE) {
4617                 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4618                 DoPrintInterfaceChange = SK_FALSE;
4619                 SkDrvInitAdapter(pAc, 0);    /* first device  */
4620         }
4621         if (pAc->WasIfUp[1] == SK_TRUE) {
4622                 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4623                 DoPrintInterfaceChange = SK_FALSE;
4624                 SkDrvInitAdapter(pAc, 1);    /* second device */
4625         }
4626         return(0);
4627 }
4628
4629 /*****************************************************************************
4630  *
4631  *      ParseDeviceNbrFromSlotName - Evaluate PCI device number
4632  *
4633  * Description:
4634  *      This function parses the PCI slot name information string and will
4635  *      retrieve the devcie number out of it. The slot_name maintianed by
4636  *      linux is in the form of '02:0a.0', whereas the first two characters 
4637  *      represent the bus number in hex (in the sample above this is 
4638  *      pci bus 0x02) and the next two characters the device number (0x0a).
4639  *
4640  * Returns:
4641  *      SK_U32: The device number from the PCI slot name
4642  */ 
4643
4644 static SK_U32 ParseDeviceNbrFromSlotName(
4645 const char *SlotName)   /* pointer to pci slot name eg. '02:0a.0' */
4646 {
4647         char    *CurrCharPos    = (char *) SlotName;
4648         int     FirstNibble     = -1;
4649         int     SecondNibble    = -1;
4650         SK_U32  Result          =  0;
4651
4652         while (*CurrCharPos != '\0') {
4653                 if (*CurrCharPos == ':') { 
4654                         while (*CurrCharPos != '.') {
4655                                 CurrCharPos++;  
4656                                 if (    (*CurrCharPos >= '0') && 
4657                                         (*CurrCharPos <= '9')) {
4658                                         if (FirstNibble == -1) {
4659                                                 /* dec. value for '0' */
4660                                                 FirstNibble = *CurrCharPos - 48;
4661                                         } else {
4662                                                 SecondNibble = *CurrCharPos - 48;
4663                                         }  
4664                                 } else if (     (*CurrCharPos >= 'a') && 
4665                                                 (*CurrCharPos <= 'f')  ) {
4666                                         if (FirstNibble == -1) {
4667                                                 FirstNibble = *CurrCharPos - 87; 
4668                                         } else {
4669                                                 SecondNibble = *CurrCharPos - 87; 
4670                                         }
4671                                 } else {
4672                                         Result = 0;
4673                                 }
4674                         }
4675
4676                         Result = FirstNibble;
4677                         Result = Result << 4; /* first nibble is higher one */
4678                         Result = Result | SecondNibble;
4679                 }
4680                 CurrCharPos++;   /* next character */
4681         }
4682         return (Result);
4683 }
4684
4685 /****************************************************************************
4686  *
4687  *      SkDrvDeInitAdapter - deinitialize adapter (this function is only 
4688  *                              called if Diag attaches to that card)
4689  *
4690  * Description:
4691  *      Close initialized adapter.
4692  *
4693  * Returns:
4694  *      0 - on success
4695  *      error code - on error
4696  */
4697 static int SkDrvDeInitAdapter(
4698 SK_AC   *pAC,           /* pointer to adapter context   */
4699 int      devNbr)        /* what device is to be handled */
4700 {
4701         struct SK_NET_DEVICE *dev;
4702
4703         dev = pAC->dev[devNbr];
4704
4705         /* On Linux 2.6 the network driver does NOT mess with reference
4706         ** counts.  The driver MUST be able to be unloaded at any time
4707         ** due to the possibility of hotplug.
4708         */
4709         if (SkGeClose(dev) != 0) {
4710                 return (-1);
4711         }
4712         return (0);
4713
4714 } /* SkDrvDeInitAdapter() */
4715
4716 /****************************************************************************
4717  *
4718  *      SkDrvInitAdapter - Initialize adapter (this function is only 
4719  *                              called if Diag deattaches from that card)
4720  *
4721  * Description:
4722  *      Close initialized adapter.
4723  *
4724  * Returns:
4725  *      0 - on success
4726  *      error code - on error
4727  */
4728 static int SkDrvInitAdapter(
4729 SK_AC   *pAC,           /* pointer to adapter context   */
4730 int      devNbr)        /* what device is to be handled */
4731 {
4732         struct SK_NET_DEVICE *dev;
4733
4734         dev = pAC->dev[devNbr];
4735
4736         if (SkGeOpen(dev) != 0) {
4737                 return (-1);
4738         }
4739
4740         /*
4741         ** Use correct MTU size and indicate to kernel TX queue can be started
4742         */ 
4743         if (SkGeChangeMtu(dev, dev->mtu) != 0) {
4744                 return (-1);
4745         } 
4746         return (0);
4747
4748 } /* SkDrvInitAdapter */
4749
4750 #endif
4751
4752 #ifdef DEBUG
4753 /****************************************************************************/
4754 /* "debug only" section *****************************************************/
4755 /****************************************************************************/
4756
4757
4758 /*****************************************************************************
4759  *
4760  *      DumpMsg - print a frame
4761  *
4762  * Description:
4763  *      This function prints frames to the system logfile/to the console.
4764  *
4765  * Returns: N/A
4766  *      
4767  */
4768 static void DumpMsg(struct sk_buff *skb, char *str)
4769 {
4770         int     msglen;
4771
4772         if (skb == NULL) {
4773                 printk("DumpMsg(): NULL-Message\n");
4774                 return;
4775         }
4776
4777         if (skb->data == NULL) {
4778                 printk("DumpMsg(): Message empty\n");
4779                 return;
4780         }
4781
4782         msglen = skb->len;
4783         if (msglen > 64)
4784                 msglen = 64;
4785
4786         printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
4787
4788         DumpData((char *)skb->data, msglen);
4789
4790         printk("------- End of message ---------\n");
4791 } /* DumpMsg */
4792
4793
4794
4795 /*****************************************************************************
4796  *
4797  *      DumpData - print a data area
4798  *
4799  * Description:
4800  *      This function prints a area of data to the system logfile/to the
4801  *      console.
4802  *
4803  * Returns: N/A
4804  *      
4805  */
4806 static void DumpData(char *p, int size)
4807 {
4808 register int    i;
4809 int     haddr, addr;
4810 char    hex_buffer[180];
4811 char    asc_buffer[180];
4812 char    HEXCHAR[] = "0123456789ABCDEF";
4813
4814         addr = 0;
4815         haddr = 0;
4816         hex_buffer[0] = 0;
4817         asc_buffer[0] = 0;
4818         for (i=0; i < size; ) {
4819                 if (*p >= '0' && *p <='z')
4820                         asc_buffer[addr] = *p;
4821                 else
4822                         asc_buffer[addr] = '.';
4823                 addr++;
4824                 asc_buffer[addr] = 0;
4825                 hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
4826                 haddr++;
4827                 hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
4828                 haddr++;
4829                 hex_buffer[haddr] = ' ';
4830                 haddr++;
4831                 hex_buffer[haddr] = 0;
4832                 p++;
4833                 i++;
4834                 if (i%16 == 0) {
4835                         printk("%s  %s\n", hex_buffer, asc_buffer);
4836                         addr = 0;
4837                         haddr = 0;
4838                 }
4839         }
4840 } /* DumpData */
4841
4842
4843 /*****************************************************************************
4844  *
4845  *      DumpLong - print a data area as long values
4846  *
4847  * Description:
4848  *      This function prints a area of data to the system logfile/to the
4849  *      console.
4850  *
4851  * Returns: N/A
4852  *      
4853  */
4854 static void DumpLong(char *pc, int size)
4855 {
4856 register int    i;
4857 int     haddr, addr;
4858 char    hex_buffer[180];
4859 char    asc_buffer[180];
4860 char    HEXCHAR[] = "0123456789ABCDEF";
4861 long    *p;
4862 int     l;
4863
4864         addr = 0;
4865         haddr = 0;
4866         hex_buffer[0] = 0;
4867         asc_buffer[0] = 0;
4868         p = (long*) pc;
4869         for (i=0; i < size; ) {
4870                 l = (long) *p;
4871                 hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
4872                 haddr++;
4873                 hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
4874                 haddr++;
4875                 hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
4876                 haddr++;
4877                 hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
4878                 haddr++;
4879                 hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
4880                 haddr++;
4881                 hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
4882                 haddr++;
4883                 hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
4884                 haddr++;
4885                 hex_buffer[haddr] = HEXCHAR[l & 0x0f];
4886                 haddr++;
4887                 hex_buffer[haddr] = ' ';
4888                 haddr++;
4889                 hex_buffer[haddr] = 0;
4890                 p++;
4891                 i++;
4892                 if (i%8 == 0) {
4893                         printk("%4x %s\n", (i-8)*4, hex_buffer);
4894                         haddr = 0;
4895                 }
4896         }
4897         printk("------------------------\n");
4898 } /* DumpLong */
4899
4900 #endif
4901
4902 static int __devinit skge_probe_one(struct pci_dev *pdev,
4903                 const struct pci_device_id *ent)
4904 {
4905         SK_AC                   *pAC;
4906         DEV_NET                 *pNet = NULL;
4907         struct net_device       *dev = NULL;
4908         static int boards_found = 0;
4909         int error = -ENODEV;
4910
4911         if (pci_enable_device(pdev))
4912                 goto out;
4913  
4914         /* Configure DMA attributes. */
4915         if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
4916             pci_set_dma_mask(pdev, DMA_32BIT_MASK))
4917                 goto out_disable_device;
4918
4919
4920         if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
4921                 printk(KERN_ERR "Unable to allocate etherdev "
4922                        "structure!\n");
4923                 goto out_disable_device;
4924         }
4925
4926         pNet = netdev_priv(dev);
4927         pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
4928         if (!pNet->pAC) {
4929                 printk(KERN_ERR "Unable to allocate adapter "
4930                        "structure!\n");
4931                 goto out_free_netdev;
4932         }
4933
4934         memset(pNet->pAC, 0, sizeof(SK_AC));
4935         pAC = pNet->pAC;
4936         pAC->PciDev = pdev;
4937         pAC->PciDevId = pdev->device;
4938         pAC->dev[0] = dev;
4939         pAC->dev[1] = dev;
4940         sprintf(pAC->Name, "SysKonnect SK-98xx");
4941         pAC->CheckQueue = SK_FALSE;
4942
4943         pNet->Mtu = 1500;
4944         pNet->Up = 0;
4945         dev->irq = pdev->irq;
4946         error = SkGeInitPCI(pAC);
4947         if (error) {
4948                 printk("SKGE: PCI setup failed: %i\n", error);
4949                 goto out_free_netdev;
4950         }
4951
4952         SET_MODULE_OWNER(dev);
4953         dev->open =             &SkGeOpen;
4954         dev->stop =             &SkGeClose;
4955         dev->hard_start_xmit =  &SkGeXmit;
4956         dev->get_stats =        &SkGeStats;
4957         dev->set_multicast_list = &SkGeSetRxMode;
4958         dev->set_mac_address =  &SkGeSetMacAddr;
4959         dev->do_ioctl =         &SkGeIoctl;
4960         dev->change_mtu =       &SkGeChangeMtu;
4961 #ifdef CONFIG_NET_POLL_CONTROLLER
4962         dev->poll_controller =  &SkGePollController;
4963 #endif
4964         SET_NETDEV_DEV(dev, &pdev->dev);
4965         SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4966
4967 #ifdef SK_ZEROCOPY
4968 #ifdef USE_SK_TX_CHECKSUM
4969         if (pAC->ChipsetType) {
4970                 /* Use only if yukon hardware */
4971                 /* SK and ZEROCOPY - fly baby... */
4972                 dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
4973         }
4974 #endif
4975 #endif
4976
4977         pAC->Index = boards_found++;
4978
4979         if (SkGeBoardInit(dev, pAC))
4980                 goto out_free_netdev;
4981
4982         /* Register net device */
4983         if (register_netdev(dev)) {
4984                 printk(KERN_ERR "SKGE: Could not register device.\n");
4985                 goto out_free_resources;
4986         }
4987
4988         /* Print adapter specific string from vpd */
4989         ProductStr(pAC);
4990         printk("%s: %s\n", dev->name, pAC->DeviceStr);
4991
4992         /* Print configuration settings */
4993         printk("      PrefPort:%c  RlmtMode:%s\n",
4994                 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
4995                 (pAC->RlmtMode==0)  ? "Check Link State" :
4996                 ((pAC->RlmtMode==1) ? "Check Link State" :
4997                 ((pAC->RlmtMode==3) ? "Check Local Port" :
4998                 ((pAC->RlmtMode==7) ? "Check Segmentation" :
4999                 ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
5000
5001         SkGeYellowLED(pAC, pAC->IoBase, 1);
5002
5003
5004         memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
5005
5006         SkGeProcCreate(dev);
5007
5008         pNet->PortNr = 0;
5009         pNet->NetNr  = 0;
5010
5011         boards_found++;
5012
5013         /* More then one port found */
5014         if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
5015                 if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
5016                         printk(KERN_ERR "Unable to allocate etherdev "
5017                                 "structure!\n");
5018                         goto out;
5019                 }
5020
5021                 pAC->dev[1]   = dev;
5022                 pNet          = netdev_priv(dev);
5023                 pNet->PortNr  = 1;
5024                 pNet->NetNr   = 1;
5025                 pNet->pAC     = pAC;
5026                 pNet->Mtu     = 1500;
5027                 pNet->Up      = 0;
5028
5029                 dev->open               = &SkGeOpen;
5030                 dev->stop               = &SkGeClose;
5031                 dev->hard_start_xmit    = &SkGeXmit;
5032                 dev->get_stats          = &SkGeStats;
5033                 dev->set_multicast_list = &SkGeSetRxMode;
5034                 dev->set_mac_address    = &SkGeSetMacAddr;
5035                 dev->do_ioctl           = &SkGeIoctl;
5036                 dev->change_mtu         = &SkGeChangeMtu;
5037                 SET_NETDEV_DEV(dev, &pdev->dev);
5038                 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
5039
5040 #ifdef SK_ZEROCOPY
5041 #ifdef USE_SK_TX_CHECKSUM
5042                 if (pAC->ChipsetType) {
5043                         /* SG and ZEROCOPY - fly baby... */
5044                         dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
5045                 }
5046 #endif
5047 #endif
5048
5049                 if (register_netdev(dev)) {
5050                         printk(KERN_ERR "SKGE: Could not register device.\n");
5051                         free_netdev(dev);
5052                         pAC->dev[1] = pAC->dev[0];
5053                 } else {
5054                         SkGeProcCreate(dev);
5055                         memcpy(&dev->dev_addr,
5056                                         &pAC->Addr.Net[1].CurrentMacAddress, 6);
5057         
5058                         printk("%s: %s\n", dev->name, pAC->DeviceStr);
5059                         printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
5060                 }
5061         }
5062
5063         /* Save the hardware revision */
5064         pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
5065                 (pAC->GIni.GIPciHwRev & 0x0F);
5066
5067         /* Set driver globals */
5068         pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
5069         pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
5070
5071         memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
5072         memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
5073
5074         pci_set_drvdata(pdev, dev);
5075         return 0;
5076
5077  out_free_resources:
5078         FreeResources(dev);
5079  out_free_netdev:
5080         free_netdev(dev);
5081  out_disable_device:
5082         pci_disable_device(pdev);
5083  out:
5084         return error;
5085 }
5086
5087 static void __devexit skge_remove_one(struct pci_dev *pdev)
5088 {
5089         struct net_device *dev = pci_get_drvdata(pdev);
5090         DEV_NET *pNet = netdev_priv(dev);
5091         SK_AC *pAC = pNet->pAC;
5092         struct net_device *otherdev = pAC->dev[1];
5093
5094         SkGeProcRemove(dev);
5095         unregister_netdev(dev);
5096         if (otherdev != dev)
5097                 SkGeProcRemove(otherdev);
5098
5099         SkGeYellowLED(pAC, pAC->IoBase, 0);
5100
5101         if (pAC->BoardLevel == SK_INIT_RUN) {
5102                 SK_EVPARA EvPara;
5103                 unsigned long Flags;
5104
5105                 /* board is still alive */
5106                 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
5107                 EvPara.Para32[0] = 0;
5108                 EvPara.Para32[1] = -1;
5109                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5110                 EvPara.Para32[0] = 1;
5111                 EvPara.Para32[1] = -1;
5112                 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5113                 SkEventDispatcher(pAC, pAC->IoBase);
5114                 /* disable interrupts */
5115                 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
5116                 SkGeDeInit(pAC, pAC->IoBase);
5117                 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
5118                 pAC->BoardLevel = SK_INIT_DATA;
5119                 /* We do NOT check here, if IRQ was pending, of course*/
5120         }
5121
5122         if (pAC->BoardLevel == SK_INIT_IO) {
5123                 /* board is still alive */
5124                 SkGeDeInit(pAC, pAC->IoBase);
5125                 pAC->BoardLevel = SK_INIT_DATA;
5126         }
5127
5128         FreeResources(dev);
5129         free_netdev(dev);
5130         if (otherdev != dev)
5131                 free_netdev(otherdev);
5132         kfree(pAC);
5133 }
5134
5135 #ifdef CONFIG_PM
5136 static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
5137 {
5138         struct net_device *dev = pci_get_drvdata(pdev);
5139         DEV_NET *pNet = netdev_priv(dev);
5140         SK_AC *pAC = pNet->pAC;
5141         struct net_device *otherdev = pAC->dev[1];
5142
5143         if (netif_running(dev)) {
5144                 netif_carrier_off(dev);
5145                 DoPrintInterfaceChange = SK_FALSE;
5146                 SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
5147                 netif_device_detach(dev);
5148         }
5149         if (otherdev != dev) {
5150                 if (netif_running(otherdev)) {
5151                         netif_carrier_off(otherdev);
5152                         DoPrintInterfaceChange = SK_FALSE;
5153                         SkDrvDeInitAdapter(pAC, 1);  /* performs SkGeClose */
5154                         netif_device_detach(otherdev);
5155                 }
5156         }
5157
5158         pci_save_state(pdev);
5159         pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
5160         if (pAC->AllocFlag & SK_ALLOC_IRQ) {
5161                 free_irq(dev->irq, dev);
5162         }
5163         pci_disable_device(pdev);
5164         pci_set_power_state(pdev, pci_choose_state(pdev, state));
5165
5166         return 0;
5167 }
5168
5169 static int skge_resume(struct pci_dev *pdev)
5170 {
5171         struct net_device *dev = pci_get_drvdata(pdev);
5172         DEV_NET *pNet = netdev_priv(dev);
5173         SK_AC *pAC = pNet->pAC;
5174         struct net_device *otherdev = pAC->dev[1];
5175         int ret;
5176
5177         pci_set_power_state(pdev, PCI_D0);
5178         pci_restore_state(pdev);
5179         pci_enable_device(pdev);
5180         pci_set_master(pdev);
5181         if (pAC->GIni.GIMacsFound == 2)
5182                 ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
5183         else
5184                 ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
5185         if (ret) {
5186                 printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
5187                 pAC->AllocFlag &= ~SK_ALLOC_IRQ;
5188                 dev->irq = 0;
5189                 pci_disable_device(pdev);
5190                 return -EBUSY;
5191         }
5192
5193         netif_device_attach(dev);
5194         if (netif_running(dev)) {
5195                 DoPrintInterfaceChange = SK_FALSE;
5196                 SkDrvInitAdapter(pAC, 0);    /* first device  */
5197         }
5198         if (otherdev != dev) {
5199                 netif_device_attach(otherdev);
5200                 if (netif_running(otherdev)) {
5201                         DoPrintInterfaceChange = SK_FALSE;
5202                         SkDrvInitAdapter(pAC, 1);    /* second device  */
5203                 }
5204         }
5205
5206         return 0;
5207 }
5208 #else
5209 #define skge_suspend NULL
5210 #define skge_resume NULL
5211 #endif
5212
5213 static struct pci_device_id skge_pci_tbl[] = {
5214         { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5215         { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5216         { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5217         { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5218 /* DLink card does not have valid VPD so this driver gags
5219  *      { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5220  */
5221         { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5222         { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5223         { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5224         { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
5225         { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5226         { 0 }
5227 };
5228
5229 MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
5230
5231 static struct pci_driver skge_driver = {
5232         .name           = "sk98lin",
5233         .id_table       = skge_pci_tbl,
5234         .probe          = skge_probe_one,
5235         .remove         = __devexit_p(skge_remove_one),
5236         .suspend        = skge_suspend,
5237         .resume         = skge_resume,
5238 };
5239
5240 static int __init skge_init(void)
5241 {
5242         int error;
5243
5244         pSkRootDir = proc_mkdir(SKRootName, NULL);
5245         if (pSkRootDir) 
5246                 pSkRootDir->owner = THIS_MODULE;
5247         
5248         error = pci_register_driver(&skge_driver);
5249         if (error)
5250                 remove_proc_entry(SKRootName, NULL);
5251         return error;
5252 }
5253
5254 static void __exit skge_exit(void)
5255 {
5256         pci_unregister_driver(&skge_driver);
5257         remove_proc_entry(SKRootName, NULL);
5258
5259 }
5260
5261 module_init(skge_init);
5262 module_exit(skge_exit);