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