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