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