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