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