uboot/drivers/net/tigon3.c
<<
>>
Prefs
   1/******************************************************************************/
   2/*                                                                            */
   3/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom         */
   4/* Corporation.                                                               */
   5/* All rights reserved.                                                       */
   6/*                                                                            */
   7/* This program is free software; you can redistribute it and/or modify       */
   8/* it under the terms of the GNU General Public License as published by       */
   9/* the Free Software Foundation, located in the file LICENSE.                 */
  10/*                                                                            */
  11/* History:                                                                   */
  12/******************************************************************************/
  13#include <common.h>
  14#include <asm/types.h>
  15
  16#ifdef CONFIG_BMW
  17#include <mpc824x.h>
  18#endif
  19#include <malloc.h>
  20#include <linux/byteorder/big_endian.h>
  21#include "bcm570x_mm.h"
  22
  23#define EMBEDDED 1
  24/******************************************************************************/
  25/* Local functions. */
  26/******************************************************************************/
  27
  28LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice);
  29LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice);
  30
  31static LM_STATUS LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE
  32                                                 RequestedMediaType,
  33                                                 PLM_MEDIA_TYPE pMediaType,
  34                                                 PLM_LINE_SPEED pLineSpeed,
  35                                                 PLM_DUPLEX_MODE pDuplexMode);
  36
  37static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice);
  38
  39__inline static LM_VOID LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice);
  40__inline static LM_VOID LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice);
  41
  42static LM_STATUS LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
  43                                            LM_REQUESTED_MEDIA_TYPE
  44                                            RequestedMediaType);
  45static LM_STATUS LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
  46                                  LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
  47static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice);
  48STATIC LM_STATUS LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
  49                                    LM_UINT32 LocalPhyAd,
  50                                    LM_UINT32 RemotePhyAd);
  51#if INCLUDE_TBI_SUPPORT
  52STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice);
  53STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice);
  54#endif
  55STATIC LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice);
  56STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid,
  57                                                 LM_UINT16 Ssid);
  58STATIC LM_STATUS LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
  59                             LM_PHYSICAL_ADDRESS BufferPhy,
  60                             LM_UINT32 BufferSize);
  61STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number);
  62STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice);
  63STATIC LM_STATUS LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice,
  64                                    PLM_PACKET pPacket, PT3_SND_BD pSendBd);
  65
  66/******************************************************************************/
  67/* External functions. */
  68/******************************************************************************/
  69
  70LM_STATUS LM_LoadRlsFirmware (PLM_DEVICE_BLOCK pDevice);
  71
  72/******************************************************************************/
  73/* Description:                                                               */
  74/*                                                                            */
  75/* Return:                                                                    */
  76/******************************************************************************/
  77LM_UINT32 LM_RegRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
  78{
  79        LM_UINT32 Value32;
  80
  81#if PCIX_TARGET_WORKAROUND
  82        MM_ACQUIRE_UNDI_LOCK (pDevice);
  83#endif
  84        MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
  85        MM_ReadConfig32 (pDevice, T3_PCI_REG_DATA_REG, &Value32);
  86#if PCIX_TARGET_WORKAROUND
  87        MM_RELEASE_UNDI_LOCK (pDevice);
  88#endif
  89
  90        return Value32;
  91}                               /* LM_RegRdInd */
  92
  93/******************************************************************************/
  94/* Description:                                                               */
  95/*                                                                            */
  96/* Return:                                                                    */
  97/******************************************************************************/
  98LM_VOID
  99LM_RegWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32)
 100{
 101
 102#if PCIX_TARGET_WORKAROUND
 103        MM_ACQUIRE_UNDI_LOCK (pDevice);
 104#endif
 105        MM_WriteConfig32 (pDevice, T3_PCI_REG_ADDR_REG, Register);
 106        MM_WriteConfig32 (pDevice, T3_PCI_REG_DATA_REG, Value32);
 107#if PCIX_TARGET_WORKAROUND
 108        MM_RELEASE_UNDI_LOCK (pDevice);
 109#endif
 110}                               /* LM_RegWrInd */
 111
 112/******************************************************************************/
 113/* Description:                                                               */
 114/*                                                                            */
 115/* Return:                                                                    */
 116/******************************************************************************/
 117LM_UINT32 LM_MemRdInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr)
 118{
 119        LM_UINT32 Value32;
 120
 121        MM_ACQUIRE_UNDI_LOCK (pDevice);
 122#ifdef BIG_ENDIAN_HOST
 123        MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
 124        Value32 = REG_RD (pDevice, PciCfg.MemWindowData);
 125        /*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
 126#else
 127        MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
 128        MM_ReadConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
 129#endif
 130        MM_RELEASE_UNDI_LOCK (pDevice);
 131
 132        return Value32;
 133}                               /* LM_MemRdInd */
 134
 135/******************************************************************************/
 136/* Description:                                                               */
 137/*                                                                            */
 138/* Return:                                                                    */
 139/******************************************************************************/
 140LM_VOID
 141LM_MemWrInd (PLM_DEVICE_BLOCK pDevice, LM_UINT32 MemAddr, LM_UINT32 Value32)
 142{
 143        MM_ACQUIRE_UNDI_LOCK (pDevice);
 144#ifdef BIG_ENDIAN_HOST
 145        REG_WR (pDevice, PciCfg.MemWindowBaseAddr, MemAddr);
 146        REG_WR (pDevice, uIntMem.Mbuf[(MemAddr & 0x7fff) / 4], Value32);
 147#else
 148        MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
 149        MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
 150#endif
 151        MM_RELEASE_UNDI_LOCK (pDevice);
 152}                               /* LM_MemWrInd */
 153
 154/******************************************************************************/
 155/* Description:                                                               */
 156/*                                                                            */
 157/* Return:                                                                    */
 158/******************************************************************************/
 159LM_STATUS LM_QueueRxPackets (PLM_DEVICE_BLOCK pDevice)
 160{
 161        LM_STATUS Lmstatus;
 162        PLM_PACKET pPacket;
 163        PT3_RCV_BD pRcvBd;
 164        LM_UINT32 StdBdAdded = 0;
 165#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
 166        LM_UINT32 JumboBdAdded = 0;
 167#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
 168
 169        Lmstatus = LM_STATUS_SUCCESS;
 170
 171        pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
 172        while (pPacket) {
 173                switch (pPacket->u.Rx.RcvProdRing) {
 174#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
 175                case T3_JUMBO_RCV_PROD_RING:    /* Jumbo Receive Ring. */
 176                        /* Initialize the buffer descriptor. */
 177                        pRcvBd =
 178                            &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
 179                        pRcvBd->Flags =
 180                            RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
 181                        pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
 182
 183                        /* Initialize the receive buffer pointer */
 184#if 0                           /* Jimmy, deleted in new */
 185                        pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
 186                        pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
 187#endif
 188                        MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
 189
 190                        /* The opaque field may point to an offset from a fix addr. */
 191                        pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
 192                                                      MM_UINT_PTR (pDevice->
 193                                                                   pPacketDescBase));
 194
 195                        /* Update the producer index. */
 196                        pDevice->RxJumboProdIdx =
 197                            (pDevice->RxJumboProdIdx +
 198                             1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
 199
 200                        JumboBdAdded++;
 201                        break;
 202#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
 203
 204                case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
 205                        /* Initialize the buffer descriptor. */
 206                        pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
 207                        pRcvBd->Flags = RCV_BD_FLAG_END;
 208                        pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
 209
 210                        /* Initialize the receive buffer pointer */
 211#if 0                           /* Jimmy, deleted in new replaced with MM_MapRxDma */
 212                        pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
 213                        pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
 214#endif
 215                        MM_MapRxDma (pDevice, pPacket, &pRcvBd->HostAddr);
 216
 217                        /* The opaque field may point to an offset from a fix addr. */
 218                        pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR (pPacket) -
 219                                                      MM_UINT_PTR (pDevice->
 220                                                                   pPacketDescBase));
 221
 222                        /* Update the producer index. */
 223                        pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
 224                            T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
 225
 226                        StdBdAdded++;
 227                        break;
 228
 229                case T3_UNKNOWN_RCV_PROD_RING:
 230                default:
 231                        Lmstatus = LM_STATUS_FAILURE;
 232                        break;
 233                }               /* switch */
 234
 235                /* Bail out if there is any error. */
 236                if (Lmstatus != LM_STATUS_SUCCESS) {
 237                        break;
 238                }
 239
 240                pPacket =
 241                    (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
 242        }                       /* while */
 243
 244        wmb ();
 245        /* Update the procedure index. */
 246        if (StdBdAdded) {
 247                MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low,
 248                           pDevice->RxStdProdIdx);
 249        }
 250#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
 251        if (JumboBdAdded) {
 252                MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low,
 253                           pDevice->RxJumboProdIdx);
 254        }
 255#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
 256
 257        return Lmstatus;
 258}                               /* LM_QueueRxPackets */
 259
 260/******************************************************************************/
 261/* Description:                                                               */
 262/*                                                                            */
 263/* Return:                                                                    */
 264/******************************************************************************/
 265STATIC LM_VOID LM_NvramInit (PLM_DEVICE_BLOCK pDevice)
 266{
 267        LM_UINT32 Value32;
 268        LM_UINT32 j;
 269
 270        /* Intialize clock period and state machine. */
 271        Value32 = SEEPROM_ADDR_CLK_PERD (SEEPROM_CLOCK_PERIOD) |
 272            SEEPROM_ADDR_FSM_RESET;
 273        REG_WR (pDevice, Grc.EepromAddr, Value32);
 274
 275        for (j = 0; j < 100; j++) {
 276                MM_Wait (10);
 277        }
 278
 279        /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
 280        Value32 = REG_RD (pDevice, Grc.LocalCtrl);
 281        REG_WR (pDevice, Grc.LocalCtrl,
 282                Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
 283
 284        /* Set the 5701 compatibility mode if we are using EEPROM. */
 285        if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
 286            T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
 287                Value32 = REG_RD (pDevice, Nvram.Config1);
 288                if ((Value32 & FLASH_INTERFACE_ENABLE) == 0) {
 289                        /* Use the new interface to read EEPROM. */
 290                        Value32 &= ~FLASH_COMPAT_BYPASS;
 291
 292                        REG_WR (pDevice, Nvram.Config1, Value32);
 293                }
 294        }
 295}                               /* LM_NvRamInit */
 296
 297/******************************************************************************/
 298/* Description:                                                               */
 299/*                                                                            */
 300/* Return:                                                                    */
 301/******************************************************************************/
 302STATIC LM_STATUS
 303LM_EepromRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
 304{
 305        LM_UINT32 Value32;
 306        LM_UINT32 Addr;
 307        LM_UINT32 Dev;
 308        LM_UINT32 j;
 309
 310        if (Offset > SEEPROM_CHIP_SIZE) {
 311                return LM_STATUS_FAILURE;
 312        }
 313
 314        Dev = Offset / SEEPROM_CHIP_SIZE;
 315        Addr = Offset % SEEPROM_CHIP_SIZE;
 316
 317        Value32 = REG_RD (pDevice, Grc.EepromAddr);
 318        Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
 319                     SEEPROM_ADDR_RW_MASK);
 320        REG_WR (pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID (Dev) |
 321                SEEPROM_ADDR_ADDRESS (Addr) | SEEPROM_ADDR_START |
 322                SEEPROM_ADDR_READ);
 323
 324        for (j = 0; j < 1000; j++) {
 325                Value32 = REG_RD (pDevice, Grc.EepromAddr);
 326                if (Value32 & SEEPROM_ADDR_COMPLETE) {
 327                        break;
 328                }
 329                MM_Wait (10);
 330        }
 331
 332        if (Value32 & SEEPROM_ADDR_COMPLETE) {
 333                Value32 = REG_RD (pDevice, Grc.EepromData);
 334                *pData = Value32;
 335
 336                return LM_STATUS_SUCCESS;
 337        }
 338
 339        return LM_STATUS_FAILURE;
 340}                               /* LM_EepromRead */
 341
 342/******************************************************************************/
 343/* Description:                                                               */
 344/*                                                                            */
 345/* Return:                                                                    */
 346/******************************************************************************/
 347STATIC LM_STATUS
 348LM_NvramRead (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, LM_UINT32 * pData)
 349{
 350        LM_UINT32 Value32;
 351        LM_STATUS Status;
 352        LM_UINT32 j;
 353
 354        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
 355            T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
 356                Status = LM_EepromRead (pDevice, Offset, pData);
 357        } else {
 358                /* Determine if we have flash or EEPROM. */
 359                Value32 = REG_RD (pDevice, Nvram.Config1);
 360                if (Value32 & FLASH_INTERFACE_ENABLE) {
 361                        if (Value32 & FLASH_SSRAM_BUFFERRED_MODE) {
 362                                Offset = ((Offset / BUFFERED_FLASH_PAGE_SIZE) <<
 363                                          BUFFERED_FLASH_PAGE_POS) +
 364                                    (Offset % BUFFERED_FLASH_PAGE_SIZE);
 365                        }
 366                }
 367
 368                REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
 369                for (j = 0; j < 1000; j++) {
 370                        if (REG_RD (pDevice, Nvram.SwArb) & SW_ARB_GNT1) {
 371                                break;
 372                        }
 373                        MM_Wait (20);
 374                }
 375                if (j == 1000) {
 376                        return LM_STATUS_FAILURE;
 377                }
 378
 379                /* Read from flash or EEPROM with the new 5703/02 interface. */
 380                REG_WR (pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
 381
 382                REG_WR (pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
 383                        NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
 384
 385                /* Wait for the done bit to clear. */
 386                for (j = 0; j < 500; j++) {
 387                        MM_Wait (10);
 388
 389                        Value32 = REG_RD (pDevice, Nvram.Cmd);
 390                        if (!(Value32 & NVRAM_CMD_DONE)) {
 391                                break;
 392                        }
 393                }
 394
 395                /* Wait for the done bit. */
 396                if (!(Value32 & NVRAM_CMD_DONE)) {
 397                        for (j = 0; j < 500; j++) {
 398                                MM_Wait (10);
 399
 400                                Value32 = REG_RD (pDevice, Nvram.Cmd);
 401                                if (Value32 & NVRAM_CMD_DONE) {
 402                                        MM_Wait (10);
 403
 404                                        *pData =
 405                                            REG_RD (pDevice, Nvram.ReadData);
 406
 407                                        /* Change the endianess. */
 408                                        *pData =
 409                                            ((*pData & 0xff) << 24) |
 410                                            ((*pData & 0xff00) << 8) |
 411                                            ((*pData & 0xff0000) >> 8) |
 412                                            ((*pData >> 24) & 0xff);
 413
 414                                        break;
 415                                }
 416                        }
 417                }
 418
 419                REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
 420                if (Value32 & NVRAM_CMD_DONE) {
 421                        Status = LM_STATUS_SUCCESS;
 422                } else {
 423                        Status = LM_STATUS_FAILURE;
 424                }
 425        }
 426
 427        return Status;
 428}                               /* LM_NvramRead */
 429
 430STATIC void LM_ReadVPD (PLM_DEVICE_BLOCK pDevice)
 431{
 432        LM_UINT32 Vpd_arr[256 / 4];
 433        LM_UINT8 *Vpd = (LM_UINT8 *) & Vpd_arr[0];
 434        LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
 435        LM_UINT32 Value32;
 436        unsigned int j;
 437
 438        /* Read PN from VPD */
 439        for (j = 0; j < 256; j += 4, Vpd_dptr++) {
 440                if (LM_NvramRead (pDevice, 0x100 + j, &Value32) !=
 441                    LM_STATUS_SUCCESS) {
 442                        printf ("BCM570x: LM_ReadVPD: VPD read failed"
 443                                " (no EEPROM onboard)\n");
 444                        return;
 445                }
 446                *Vpd_dptr = cpu_to_le32 (Value32);
 447        }
 448        for (j = 0; j < 256;) {
 449                unsigned int Vpd_r_len;
 450                unsigned int Vpd_r_end;
 451
 452                if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91)) {
 453                        j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
 454                } else if (Vpd[j] == 0x90) {
 455                        Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
 456                        j += 3;
 457                        Vpd_r_end = Vpd_r_len + j;
 458                        while (j < Vpd_r_end) {
 459                                if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N')) {
 460                                        unsigned int len = Vpd[j + 2];
 461
 462                                        if (len <= 24) {
 463                                                memcpy (pDevice->PartNo,
 464                                                        &Vpd[j + 3], len);
 465                                        }
 466                                        break;
 467                                } else {
 468                                        if (Vpd[j + 2] == 0) {
 469                                                break;
 470                                        }
 471                                        j = j + Vpd[j + 2];
 472                                }
 473                        }
 474                        break;
 475                } else {
 476                        break;
 477                }
 478        }
 479}
 480
 481STATIC void LM_ReadBootCodeVersion (PLM_DEVICE_BLOCK pDevice)
 482{
 483        LM_UINT32 Value32, offset, ver_offset;
 484        int i;
 485
 486        if (LM_NvramRead (pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
 487                return;
 488        if (Value32 != 0xaa559966)
 489                return;
 490        if (LM_NvramRead (pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
 491                return;
 492
 493        offset = ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) |
 494            ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
 495        if (LM_NvramRead (pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
 496                return;
 497        if ((Value32 == 0x0300000e) &&
 498            (LM_NvramRead (pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS)
 499            && (Value32 == 0)) {
 500
 501                if (LM_NvramRead (pDevice, offset + 8, &ver_offset) !=
 502                    LM_STATUS_SUCCESS)
 503                        return;
 504                ver_offset = ((ver_offset & 0xff0000) >> 8) |
 505                    ((ver_offset >> 24) & 0xff);
 506                for (i = 0; i < 16; i += 4) {
 507                        if (LM_NvramRead
 508                            (pDevice, offset + ver_offset + i,
 509                             &Value32) != LM_STATUS_SUCCESS) {
 510                                return;
 511                        }
 512                        *((LM_UINT32 *) & pDevice->BootCodeVer[i]) =
 513                            cpu_to_le32 (Value32);
 514                }
 515        } else {
 516                char c;
 517
 518                if (LM_NvramRead (pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
 519                        return;
 520
 521                i = 0;
 522                c = ((Value32 & 0xff0000) >> 16);
 523
 524                if (c < 10) {
 525                        pDevice->BootCodeVer[i++] = c + '0';
 526                } else {
 527                        pDevice->BootCodeVer[i++] = (c / 10) + '0';
 528                        pDevice->BootCodeVer[i++] = (c % 10) + '0';
 529                }
 530                pDevice->BootCodeVer[i++] = '.';
 531                c = (Value32 & 0xff000000) >> 24;
 532                if (c < 10) {
 533                        pDevice->BootCodeVer[i++] = c + '0';
 534                } else {
 535                        pDevice->BootCodeVer[i++] = (c / 10) + '0';
 536                        pDevice->BootCodeVer[i++] = (c % 10) + '0';
 537                }
 538                pDevice->BootCodeVer[i] = 0;
 539        }
 540}
 541
 542STATIC void LM_GetBusSpeed (PLM_DEVICE_BLOCK pDevice)
 543{
 544        LM_UINT32 PciState = pDevice->PciState;
 545        LM_UINT32 ClockCtrl;
 546        char *SpeedStr = "";
 547
 548        if (PciState & T3_PCI_STATE_32BIT_PCI_BUS) {
 549                strcpy (pDevice->BusSpeedStr, "32-bit ");
 550        } else {
 551                strcpy (pDevice->BusSpeedStr, "64-bit ");
 552        }
 553        if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) {
 554                strcat (pDevice->BusSpeedStr, "PCI ");
 555                if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED) {
 556                        SpeedStr = "66MHz";
 557                } else {
 558                        SpeedStr = "33MHz";
 559                }
 560        } else {
 561                strcat (pDevice->BusSpeedStr, "PCIX ");
 562                if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE) {
 563                        SpeedStr = "133MHz";
 564                } else {
 565                        ClockCtrl = REG_RD (pDevice, PciCfg.ClockCtrl) & 0x1f;
 566                        switch (ClockCtrl) {
 567                        case 0:
 568                                SpeedStr = "33MHz";
 569                                break;
 570
 571                        case 2:
 572                                SpeedStr = "50MHz";
 573                                break;
 574
 575                        case 4:
 576                                SpeedStr = "66MHz";
 577                                break;
 578
 579                        case 6:
 580                                SpeedStr = "100MHz";
 581                                break;
 582
 583                        case 7:
 584                                SpeedStr = "133MHz";
 585                                break;
 586                        }
 587                }
 588        }
 589        strcat (pDevice->BusSpeedStr, SpeedStr);
 590}
 591
 592/******************************************************************************/
 593/* Description:                                                               */
 594/*    This routine initializes default parameters and reads the PCI           */
 595/*    configurations.                                                         */
 596/*                                                                            */
 597/* Return:                                                                    */
 598/*    LM_STATUS_SUCCESS                                                       */
 599/******************************************************************************/
 600LM_STATUS LM_GetAdapterInfo (PLM_DEVICE_BLOCK pDevice)
 601{
 602        PLM_ADAPTER_INFO pAdapterInfo;
 603        LM_UINT32 Value32;
 604        LM_STATUS Status;
 605        LM_UINT32 j;
 606        LM_UINT32 EeSigFound;
 607        LM_UINT32 EePhyTypeSerdes = 0;
 608        LM_UINT32 EePhyLedMode = 0;
 609        LM_UINT32 EePhyId = 0;
 610
 611        /* Get Device Id and Vendor Id */
 612        Status = MM_ReadConfig32 (pDevice, PCI_VENDOR_ID_REG, &Value32);
 613        if (Status != LM_STATUS_SUCCESS) {
 614                return Status;
 615        }
 616        pDevice->PciVendorId = (LM_UINT16) Value32;
 617        pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
 618
 619        /* If we are not getting the write adapter, exit. */
 620        if ((Value32 != T3_PCI_ID_BCM5700) &&
 621            (Value32 != T3_PCI_ID_BCM5701) &&
 622            (Value32 != T3_PCI_ID_BCM5702) &&
 623            (Value32 != T3_PCI_ID_BCM5702x) &&
 624            (Value32 != T3_PCI_ID_BCM5702FE) &&
 625            (Value32 != T3_PCI_ID_BCM5703) &&
 626            (Value32 != T3_PCI_ID_BCM5703x) && (Value32 != T3_PCI_ID_BCM5704)) {
 627                return LM_STATUS_FAILURE;
 628        }
 629
 630        Status = MM_ReadConfig32 (pDevice, PCI_REV_ID_REG, &Value32);
 631        if (Status != LM_STATUS_SUCCESS) {
 632                return Status;
 633        }
 634        pDevice->PciRevId = (LM_UINT8) Value32;
 635
 636        /* Get IRQ. */
 637        Status = MM_ReadConfig32 (pDevice, PCI_INT_LINE_REG, &Value32);
 638        if (Status != LM_STATUS_SUCCESS) {
 639                return Status;
 640        }
 641        pDevice->Irq = (LM_UINT8) Value32;
 642
 643        /* Get interrupt pin. */
 644        pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
 645
 646        /* Get chip revision id. */
 647        Status = MM_ReadConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
 648        pDevice->ChipRevId = Value32 >> 16;
 649
 650        /* Get subsystem vendor. */
 651        Status =
 652            MM_ReadConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
 653        if (Status != LM_STATUS_SUCCESS) {
 654                return Status;
 655        }
 656        pDevice->SubsystemVendorId = (LM_UINT16) Value32;
 657
 658        /* Get PCI subsystem id. */
 659        pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
 660
 661        /* Get the cache line size. */
 662        MM_ReadConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
 663        pDevice->CacheLineSize = (LM_UINT8) Value32;
 664        pDevice->SavedCacheLineReg = Value32;
 665
 666        if (pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
 667            pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
 668            pDevice->ChipRevId != T3_CHIP_ID_5704_A0) {
 669                pDevice->UndiFix = FALSE;
 670        }
 671#if !PCIX_TARGET_WORKAROUND
 672        pDevice->UndiFix = FALSE;
 673#endif
 674        /* Map the memory base to system address space. */
 675        if (!pDevice->UndiFix) {
 676                Status = MM_MapMemBase (pDevice);
 677                if (Status != LM_STATUS_SUCCESS) {
 678                        return Status;
 679                }
 680                /* Initialize the memory view pointer. */
 681                pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
 682        }
 683#if PCIX_TARGET_WORKAROUND
 684        /* store whether we are in PCI are PCI-X mode */
 685        pDevice->EnablePciXFix = FALSE;
 686
 687        MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
 688        if ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0) {
 689                /* Enable PCI-X workaround only if we are running on 5700 BX. */
 690                if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
 691                        pDevice->EnablePciXFix = TRUE;
 692                }
 693        }
 694        if (pDevice->UndiFix) {
 695                pDevice->EnablePciXFix = TRUE;
 696        }
 697#endif
 698        /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
 699        /* management register may be clobbered which may cause the */
 700        /* BCM5700 to go into D3 state.  While in this state, we will */
 701        /* not have memory mapped register access.  As a workaround, we */
 702        /* need to restore the device to D0 state. */
 703        MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
 704        Value32 |= T3_PM_PME_ASSERTED;
 705        Value32 &= ~T3_PM_POWER_STATE_MASK;
 706        Value32 |= T3_PM_POWER_STATE_D0;
 707        MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
 708
 709        /* read the current PCI command word */
 710        MM_ReadConfig32 (pDevice, PCI_COMMAND_REG, &Value32);
 711
 712        /* Make sure bus-mastering is enabled. */
 713        Value32 |= PCI_BUSMASTER_ENABLE;
 714
 715#if PCIX_TARGET_WORKAROUND
 716        /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
 717           are enabled */
 718        if (pDevice->EnablePciXFix == TRUE) {
 719                Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
 720                            PCI_PARITY_ERROR_ENABLE);
 721        }
 722        if (pDevice->UndiFix) {
 723                Value32 &= ~PCI_MEM_SPACE_ENABLE;
 724        }
 725#endif
 726
 727        if (pDevice->EnableMWI) {
 728                Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
 729        } else {
 730                Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
 731        }
 732
 733        /* Error out if mem-mapping is NOT enabled for PCI systems */
 734        if (!(Value32 | PCI_MEM_SPACE_ENABLE)) {
 735                return LM_STATUS_FAILURE;
 736        }
 737
 738        /* save the value we are going to write into the PCI command word */
 739        pDevice->PciCommandStatusWords = Value32;
 740
 741        Status = MM_WriteConfig32 (pDevice, PCI_COMMAND_REG, Value32);
 742        if (Status != LM_STATUS_SUCCESS) {
 743                return Status;
 744        }
 745
 746        /* Set power state to D0. */
 747        LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
 748
 749#ifdef BIG_ENDIAN_PCI
 750        pDevice->MiscHostCtrl =
 751            MISC_HOST_CTRL_MASK_PCI_INT |
 752            MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
 753            MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
 754            MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
 755#else                           /* No CPU Swap modes for PCI IO */
 756
 757        /* Setup the mode registers. */
 758        pDevice->MiscHostCtrl =
 759            MISC_HOST_CTRL_MASK_PCI_INT |
 760            MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
 761#ifdef BIG_ENDIAN_HOST
 762            MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
 763#endif                          /* BIG_ENDIAN_HOST */
 764            MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
 765            MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
 766#endif                          /* !BIG_ENDIAN_PCI */
 767
 768        /* write to PCI misc host ctr first in order to enable indirect accesses */
 769        MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
 770                          pDevice->MiscHostCtrl);
 771
 772        REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
 773
 774#ifdef BIG_ENDIAN_PCI
 775        Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
 776#else
 777/* No CPU Swap modes for PCI IO */
 778#ifdef BIG_ENDIAN_HOST
 779        Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
 780            GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
 781#else
 782        Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
 783#endif
 784#endif                          /* !BIG_ENDIAN_PCI */
 785
 786        REG_WR (pDevice, Grc.Mode, Value32);
 787
 788        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
 789                REG_WR (pDevice, Grc.LocalCtrl,
 790                        GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
 791                        GRC_MISC_LOCAL_CTRL_GPIO_OE1);
 792        }
 793        MM_Wait (40);
 794
 795        /* Enable indirect memory access */
 796        REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
 797
 798        if (REG_RD (pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK) {
 799                REG_WR (pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
 800                        T3_PCI_SELECT_ALTERNATE_CLOCK);
 801                REG_WR (pDevice, PciCfg.ClockCtrl,
 802                        T3_PCI_SELECT_ALTERNATE_CLOCK);
 803                MM_Wait (40);   /* required delay is 27usec */
 804        }
 805        REG_WR (pDevice, PciCfg.ClockCtrl, 0);
 806        REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
 807
 808#if PCIX_TARGET_WORKAROUND
 809        MM_ReadConfig32 (pDevice, T3_PCI_STATE_REG, &Value32);
 810        if ((pDevice->EnablePciXFix == FALSE) &&
 811            ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)) {
 812                if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
 813                    pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
 814                    pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
 815                    pDevice->ChipRevId == T3_CHIP_ID_5701_B5) {
 816                        __raw_writel (0,
 817                                      &(pDevice->pMemView->uIntMem.
 818                                        MemBlock32K[0x300]));
 819                        __raw_writel (0,
 820                                      &(pDevice->pMemView->uIntMem.
 821                                        MemBlock32K[0x301]));
 822                        __raw_writel (0xffffffff,
 823                                      &(pDevice->pMemView->uIntMem.
 824                                        MemBlock32K[0x301]));
 825                        if (__raw_readl
 826                            (&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
 827                        {
 828                                pDevice->EnablePciXFix = TRUE;
 829                        }
 830                }
 831        }
 832#endif
 833#if 1
 834        /*
 835         *  This code was at the beginning of else block below, but that's
 836         *  a bug if node address in shared memory.
 837         */
 838        MM_Wait (50);
 839        LM_NvramInit (pDevice);
 840#endif
 841        /* Get the node address.  First try to get in from the shared memory. */
 842        /* If the signature is not present, then get it from the NVRAM. */
 843        Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
 844        if ((Value32 >> 16) == 0x484b) {
 845
 846                pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
 847                pDevice->NodeAddress[1] = (LM_UINT8) Value32;
 848
 849                Value32 = MEM_RD_OFFSET (pDevice, T3_MAC_ADDR_LOW_MAILBOX);
 850
 851                pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
 852                pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
 853                pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
 854                pDevice->NodeAddress[5] = (LM_UINT8) Value32;
 855
 856                Status = LM_STATUS_SUCCESS;
 857        } else {
 858                Status = LM_NvramRead (pDevice, 0x7c, &Value32);
 859                if (Status == LM_STATUS_SUCCESS) {
 860                        pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
 861                        pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
 862
 863                        Status = LM_NvramRead (pDevice, 0x80, &Value32);
 864
 865                        pDevice->NodeAddress[2] = (LM_UINT8) Value32;
 866                        pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
 867                        pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
 868                        pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
 869                }
 870        }
 871
 872        /* Assign a default address. */
 873        if (Status != LM_STATUS_SUCCESS) {
 874#ifndef EMBEDDED
 875                printk (KERN_ERR
 876                        "Cannot get MAC addr from NVRAM. Using default.\n");
 877#endif
 878                pDevice->NodeAddress[0] = 0x00;
 879                pDevice->NodeAddress[1] = 0x10;
 880                pDevice->NodeAddress[2] = 0x18;
 881                pDevice->NodeAddress[3] = 0x68;
 882                pDevice->NodeAddress[4] = 0x61;
 883                pDevice->NodeAddress[5] = 0x76;
 884        }
 885
 886        pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
 887        pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
 888        pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
 889        pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
 890        pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
 891        pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
 892
 893        /* Initialize the default values. */
 894        pDevice->NoTxPseudoHdrChksum = FALSE;
 895        pDevice->NoRxPseudoHdrChksum = FALSE;
 896        pDevice->NicSendBd = FALSE;
 897        pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
 898        pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
 899        pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
 900        pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
 901        pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
 902        pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
 903        pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
 904        pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
 905        pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
 906        pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
 907        pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
 908        pDevice->EnableMWI = FALSE;
 909        pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
 910        pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
 911        pDevice->DisableAutoNeg = FALSE;
 912        pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
 913        pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
 914        pDevice->LedMode = LED_MODE_AUTO;
 915        pDevice->ResetPhyOnInit = TRUE;
 916        pDevice->DelayPciGrant = TRUE;
 917        pDevice->UseTaggedStatus = FALSE;
 918        pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
 919
 920        pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
 921        pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
 922        pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
 923
 924        pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
 925        pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
 926        pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
 927        pDevice->EnableTbi = FALSE;
 928#if INCLUDE_TBI_SUPPORT
 929        pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
 930#endif
 931
 932        switch (T3_ASIC_REV (pDevice->ChipRevId)) {
 933        case T3_ASIC_REV_5704:
 934                pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
 935                pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
 936                break;
 937        default:
 938                pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
 939                pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
 940                break;
 941        }
 942
 943        pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
 944        pDevice->QueueRxPackets = TRUE;
 945
 946        pDevice->EnableWireSpeed = TRUE;
 947
 948#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
 949        pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
 950#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
 951
 952        /* Make this is a known adapter. */
 953        pAdapterInfo = LM_GetAdapterInfoBySsid (pDevice->SubsystemVendorId,
 954                                                pDevice->SubsystemId);
 955
 956        pDevice->BondId = REG_RD (pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
 957        if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
 958            pDevice->BondId != GRC_MISC_BD_ID_5701 &&
 959            pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
 960            pDevice->BondId != GRC_MISC_BD_ID_5703 &&
 961            pDevice->BondId != GRC_MISC_BD_ID_5703S &&
 962            pDevice->BondId != GRC_MISC_BD_ID_5704 &&
 963            pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE) {
 964                return LM_STATUS_UNKNOWN_ADAPTER;
 965        }
 966
 967        pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
 968        if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
 969            (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)) {
 970                pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
 971                pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
 972        }
 973
 974        /* Get Eeprom info. */
 975        Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_SIG_ADDR);
 976        if (Value32 == T3_NIC_DATA_SIG) {
 977                EeSigFound = TRUE;
 978                Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
 979
 980                /* Determine PHY type. */
 981                switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK) {
 982                case T3_NIC_CFG_PHY_TYPE_COPPER:
 983                        EePhyTypeSerdes = FALSE;
 984                        break;
 985
 986                case T3_NIC_CFG_PHY_TYPE_FIBER:
 987                        EePhyTypeSerdes = TRUE;
 988                        break;
 989
 990                default:
 991                        EePhyTypeSerdes = FALSE;
 992                        break;
 993                }
 994
 995                /* Determine PHY led mode. */
 996                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
 997                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
 998                        switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
 999                        case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
1000                                EePhyLedMode = LED_MODE_THREE_LINK;
1001                                break;
1002
1003                        case T3_NIC_CFG_LED_MODE_LINK_SPEED:
1004                                EePhyLedMode = LED_MODE_LINK10;
1005                                break;
1006
1007                        default:
1008                                EePhyLedMode = LED_MODE_AUTO;
1009                                break;
1010                        }
1011                } else {
1012                        switch (Value32 & T3_NIC_CFG_LED_MODE_MASK) {
1013                        case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
1014                                EePhyLedMode = LED_MODE_OPEN_DRAIN;
1015                                break;
1016
1017                        case T3_NIC_CFG_LED_MODE_OUTPUT:
1018                                EePhyLedMode = LED_MODE_OUTPUT;
1019                                break;
1020
1021                        default:
1022                                EePhyLedMode = LED_MODE_AUTO;
1023                                break;
1024                        }
1025                }
1026                if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1027                    pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
1028                        /* Enable EEPROM write protection. */
1029                        if (Value32 & T3_NIC_EEPROM_WP) {
1030                                pDevice->EepromWp = TRUE;
1031                        }
1032                }
1033
1034                /* Get the PHY Id. */
1035                Value32 = MEM_RD_OFFSET (pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1036                if (Value32) {
1037                        EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1038                                   PHY_ID1_OUI_MASK) << 10;
1039
1040                        Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1041
1042                        EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1043                            (Value32 & PHY_ID2_MODEL_MASK) | (Value32 &
1044                                                              PHY_ID2_REV_MASK);
1045                } else {
1046                        EePhyId = 0;
1047                }
1048        } else {
1049                EeSigFound = FALSE;
1050        }
1051
1052        /* Set the PHY address. */
1053        pDevice->PhyAddr = PHY_DEVICE_ID;
1054
1055        /* Disable auto polling. */
1056        pDevice->MiMode = 0xc0000;
1057        REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
1058        MM_Wait (40);
1059
1060        /* Get the PHY id. */
1061        LM_ReadPhy (pDevice, PHY_ID1_REG, &Value32);
1062        pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
1063
1064        LM_ReadPhy (pDevice, PHY_ID2_REG, &Value32);
1065        pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1066            (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1067
1068        /* Set the EnableTbi flag to false if we have a copper PHY. */
1069        switch (pDevice->PhyId & PHY_ID_MASK) {
1070        case PHY_BCM5400_PHY_ID:
1071                pDevice->EnableTbi = FALSE;
1072                break;
1073
1074        case PHY_BCM5401_PHY_ID:
1075                pDevice->EnableTbi = FALSE;
1076                break;
1077
1078        case PHY_BCM5411_PHY_ID:
1079                pDevice->EnableTbi = FALSE;
1080                break;
1081
1082        case PHY_BCM5701_PHY_ID:
1083                pDevice->EnableTbi = FALSE;
1084                break;
1085
1086        case PHY_BCM5703_PHY_ID:
1087                pDevice->EnableTbi = FALSE;
1088                break;
1089
1090        case PHY_BCM5704_PHY_ID:
1091                pDevice->EnableTbi = FALSE;
1092                break;
1093
1094        case PHY_BCM8002_PHY_ID:
1095                pDevice->EnableTbi = TRUE;
1096                break;
1097
1098        default:
1099
1100                if (pAdapterInfo) {
1101                        pDevice->PhyId = pAdapterInfo->PhyId;
1102                        pDevice->EnableTbi = pAdapterInfo->Serdes;
1103                } else if (EeSigFound) {
1104                        pDevice->PhyId = EePhyId;
1105                        pDevice->EnableTbi = EePhyTypeSerdes;
1106                }
1107                break;
1108        }
1109
1110        /* Bail out if we don't know the copper PHY id. */
1111        if (UNKNOWN_PHY_ID (pDevice->PhyId) && !pDevice->EnableTbi) {
1112                return LM_STATUS_FAILURE;
1113        }
1114
1115        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
1116                if ((pDevice->SavedCacheLineReg & 0xff00) < 0x4000) {
1117                        pDevice->SavedCacheLineReg &= 0xffff00ff;
1118                        pDevice->SavedCacheLineReg |= 0x4000;
1119                }
1120        }
1121        /* Change driver parameters. */
1122        Status = MM_GetConfig (pDevice);
1123        if (Status != LM_STATUS_SUCCESS) {
1124                return Status;
1125        }
1126#if INCLUDE_5701_AX_FIX
1127        if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1128            pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
1129                pDevice->ResetPhyOnInit = TRUE;
1130        }
1131#endif
1132
1133        /* Save the current phy link status. */
1134        if (!pDevice->EnableTbi) {
1135                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
1136                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
1137
1138                /* If we don't have link reset the PHY. */
1139                if (!(Value32 & PHY_STATUS_LINK_PASS)
1140                    || pDevice->ResetPhyOnInit) {
1141
1142                        LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
1143
1144                        for (j = 0; j < 100; j++) {
1145                                MM_Wait (10);
1146
1147                                LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
1148                                if (Value32 && !(Value32 & PHY_CTRL_PHY_RESET)) {
1149                                        MM_Wait (40);
1150                                        break;
1151                                }
1152                        }
1153
1154#if INCLUDE_5701_AX_FIX
1155                        /* 5701_AX_BX bug:  only advertises 10mb speed. */
1156                        if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1157                            pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
1158
1159                                Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1160                                    PHY_AN_AD_10BASET_HALF |
1161                                    PHY_AN_AD_10BASET_FULL |
1162                                    PHY_AN_AD_100BASETX_FULL |
1163                                    PHY_AN_AD_100BASETX_HALF;
1164                                Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
1165                                LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
1166                                pDevice->advertising = Value32;
1167
1168                                Value32 = BCM540X_AN_AD_1000BASET_HALF |
1169                                    BCM540X_AN_AD_1000BASET_FULL |
1170                                    BCM540X_CONFIG_AS_MASTER |
1171                                    BCM540X_ENABLE_CONFIG_AS_MASTER;
1172                                LM_WritePhy (pDevice,
1173                                             BCM540X_1000BASET_CTRL_REG,
1174                                             Value32);
1175                                pDevice->advertising1000 = Value32;
1176
1177                                LM_WritePhy (pDevice, PHY_CTRL_REG,
1178                                             PHY_CTRL_AUTO_NEG_ENABLE |
1179                                             PHY_CTRL_RESTART_AUTO_NEG);
1180                        }
1181#endif
1182                        if (T3_ASIC_REV (pDevice->ChipRevId) ==
1183                            T3_ASIC_REV_5703) {
1184                                LM_WritePhy (pDevice, 0x18, 0x0c00);
1185                                LM_WritePhy (pDevice, 0x17, 0x201f);
1186                                LM_WritePhy (pDevice, 0x15, 0x2aaa);
1187                        }
1188                        if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
1189                                LM_WritePhy (pDevice, 0x1c, 0x8d68);
1190                                LM_WritePhy (pDevice, 0x1c, 0x8d68);
1191                        }
1192                        /* Enable Ethernet@WireSpeed. */
1193                        if (pDevice->EnableWireSpeed) {
1194                                LM_WritePhy (pDevice, 0x18, 0x7007);
1195                                LM_ReadPhy (pDevice, 0x18, &Value32);
1196                                LM_WritePhy (pDevice, 0x18,
1197                                             Value32 | BIT_15 | BIT_4);
1198                        }
1199                }
1200        }
1201
1202        /* Turn off tap power management. */
1203        if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
1204                LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
1205                LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
1206                LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
1207                LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
1208                LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
1209                LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1210                LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
1211                LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1212                LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
1213                LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
1214                LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
1215
1216                MM_Wait (40);
1217        }
1218#if INCLUDE_TBI_SUPPORT
1219        pDevice->IgnoreTbiLinkChange = FALSE;
1220
1221        if (pDevice->EnableTbi) {
1222                pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1223                pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1224                if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
1225                    pDevice->DisableAutoNeg) {
1226                        pDevice->PollTbiLink = FALSE;
1227                }
1228        } else {
1229                pDevice->PollTbiLink = FALSE;
1230        }
1231#endif                          /* INCLUDE_TBI_SUPPORT */
1232
1233        /* UseTaggedStatus is only valid for 5701 and later. */
1234        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1235                pDevice->UseTaggedStatus = FALSE;
1236
1237                pDevice->CoalesceMode = 0;
1238        } else {
1239                pDevice->CoalesceMode =
1240                    HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1241                    HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1242        }
1243
1244        /* Set the status block size. */
1245        if (T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1246            T3_CHIP_REV (pDevice->ChipRevId) != T3_CHIP_REV_5700_BX) {
1247                pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1248        }
1249
1250        /* Check the DURING_INT coalescing ticks parameters. */
1251        if (pDevice->UseTaggedStatus) {
1252                if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1253                        pDevice->RxCoalescingTicksDuringInt =
1254                            DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1255                }
1256
1257                if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1258                        pDevice->TxCoalescingTicksDuringInt =
1259                            DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1260                }
1261
1262                if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1263                        pDevice->RxMaxCoalescedFramesDuringInt =
1264                            DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1265                }
1266
1267                if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1268                        pDevice->TxMaxCoalescedFramesDuringInt =
1269                            DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1270                }
1271        } else {
1272                if (pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1273                        pDevice->RxCoalescingTicksDuringInt = 0;
1274                }
1275
1276                if (pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE) {
1277                        pDevice->TxCoalescingTicksDuringInt = 0;
1278                }
1279
1280                if (pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1281                        pDevice->RxMaxCoalescedFramesDuringInt = 0;
1282                }
1283
1284                if (pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE) {
1285                        pDevice->TxMaxCoalescedFramesDuringInt = 0;
1286                }
1287        }
1288
1289#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1290        if (pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */ )) {
1291                pDevice->RxJumboDescCnt = 0;
1292                if (pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
1293                        pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1294                }
1295        } else {
1296                pDevice->RxJumboBufferSize =
1297                    (pDevice->RxMtu + 8 /* CRC + VLAN */  +
1298                     COMMON_CACHE_LINE_SIZE - 1) & ~COMMON_CACHE_LINE_MASK;
1299
1300                if (pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE) {
1301                        pDevice->RxJumboBufferSize =
1302                            DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1303                        pDevice->RxMtu =
1304                            pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */ ;
1305                }
1306                pDevice->TxMtu = pDevice->RxMtu;
1307
1308        }
1309#else
1310        pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1311#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1312
1313        pDevice->RxPacketDescCnt =
1314#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1315            pDevice->RxJumboDescCnt +
1316#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1317            pDevice->RxStdDescCnt;
1318
1319        if (pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC) {
1320                pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1321        }
1322
1323        if (pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE) {
1324                pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1325        }
1326
1327        /* Configure the proper ways to get link change interrupt. */
1328        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO) {
1329                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1330                        pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1331                } else {
1332                        pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1333                }
1334        } else if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
1335                /* Auto-polling does not work on 5700_AX and 5700_BX. */
1336                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1337                        pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1338                }
1339        }
1340
1341        /* Determine the method to get link change status. */
1342        if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO) {
1343                /* The link status bit in the status block does not work on 5700_AX */
1344                /* and 5700_BX chips. */
1345                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1346                        pDevice->LinkChngMode =
1347                            T3_LINK_CHNG_MODE_USE_STATUS_REG;
1348                } else {
1349                        pDevice->LinkChngMode =
1350                            T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
1351                }
1352        }
1353
1354        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
1355            T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
1356                pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1357        }
1358
1359        /* Configure PHY led mode. */
1360        if (pDevice->LedMode == LED_MODE_AUTO) {
1361                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1362                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
1363                        if (pDevice->SubsystemVendorId == T3_SVID_DELL) {
1364                                pDevice->LedMode = LED_MODE_LINK10;
1365                        } else {
1366                                pDevice->LedMode = LED_MODE_THREE_LINK;
1367
1368                                if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
1369                                        pDevice->LedMode = EePhyLedMode;
1370                                }
1371                        }
1372
1373                        /* bug? 5701 in LINK10 mode does not seem to work when */
1374                        /* PhyIntMode is LINK_READY. */
1375                        if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700
1376                            &&
1377#if INCLUDE_TBI_SUPPORT
1378                            pDevice->EnableTbi == FALSE &&
1379#endif
1380                            pDevice->LedMode == LED_MODE_LINK10) {
1381                                pDevice->PhyIntMode =
1382                                    T3_PHY_INT_MODE_MI_INTERRUPT;
1383                                pDevice->LinkChngMode =
1384                                    T3_LINK_CHNG_MODE_USE_STATUS_REG;
1385                        }
1386
1387                        if (pDevice->EnableTbi) {
1388                                pDevice->LedMode = LED_MODE_THREE_LINK;
1389                        }
1390                } else {
1391                        if (EeSigFound && EePhyLedMode != LED_MODE_AUTO) {
1392                                pDevice->LedMode = EePhyLedMode;
1393                        } else {
1394                                pDevice->LedMode = LED_MODE_OPEN_DRAIN;
1395                        }
1396                }
1397        }
1398
1399        /* Enable OneDmaAtOnce. */
1400        if (pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE) {
1401                pDevice->OneDmaAtOnce = FALSE;
1402        }
1403
1404        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1405            pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1406            pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1407            pDevice->ChipRevId == T3_CHIP_ID_5701_B2) {
1408                pDevice->WolSpeed = WOL_SPEED_10MB;
1409        } else {
1410                pDevice->WolSpeed = WOL_SPEED_100MB;
1411        }
1412
1413        /* Offloadings. */
1414        pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1415
1416        /* Turn off task offloading on Ax. */
1417        if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0) {
1418                pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1419                                             LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1420        }
1421        pDevice->PciState = REG_RD (pDevice, PciCfg.PciState);
1422        LM_ReadVPD (pDevice);
1423        LM_ReadBootCodeVersion (pDevice);
1424        LM_GetBusSpeed (pDevice);
1425
1426        return LM_STATUS_SUCCESS;
1427}                               /* LM_GetAdapterInfo */
1428
1429STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid (LM_UINT16 Svid, LM_UINT16 Ssid)
1430{
1431        static LM_ADAPTER_INFO AdapterArr[] = {
1432                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6,
1433                 PHY_BCM5401_PHY_ID, 0},
1434                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5,
1435                 PHY_BCM5701_PHY_ID, 0},
1436                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6,
1437                 PHY_BCM8002_PHY_ID, 1},
1438                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1},
1439                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1,
1440                 PHY_BCM5701_PHY_ID, 0},
1441                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8,
1442                 PHY_BCM5701_PHY_ID, 0},
1443                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
1444                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10,
1445                 PHY_BCM5701_PHY_ID, 0},
1446                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12,
1447                 PHY_BCM5701_PHY_ID, 0},
1448                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1,
1449                 PHY_BCM5701_PHY_ID, 0},
1450                {T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2,
1451                 PHY_BCM5701_PHY_ID, 0},
1452
1453                {T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0},
1454                {T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0},
1455                {T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1},
1456                {T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0},
1457                {T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0},
1458
1459                {T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0},
1460                {T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0},
1461                {T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0},
1462                {T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0},
1463
1464                {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0},
1465                {T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID,
1466                 0},
1467                {T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1},
1468                {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0},
1469                {T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID,
1470                 0},
1471
1472        };
1473        LM_UINT32 j;
1474
1475        for (j = 0; j < sizeof (AdapterArr) / sizeof (LM_ADAPTER_INFO); j++) {
1476                if (AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid) {
1477                        return &AdapterArr[j];
1478                }
1479        }
1480
1481        return NULL;
1482}
1483
1484/******************************************************************************/
1485/* Description:                                                               */
1486/*    This routine sets up receive/transmit buffer descriptions queues.       */
1487/*                                                                            */
1488/* Return:                                                                    */
1489/*    LM_STATUS_SUCCESS                                                       */
1490/******************************************************************************/
1491LM_STATUS LM_InitializeAdapter (PLM_DEVICE_BLOCK pDevice)
1492{
1493        LM_PHYSICAL_ADDRESS MemPhy;
1494        PLM_UINT8 pMemVirt;
1495        PLM_PACKET pPacket;
1496        LM_STATUS Status;
1497        LM_UINT32 Size;
1498        LM_UINT32 j;
1499
1500        /* Set power state to D0. */
1501        LM_SetPowerState (pDevice, LM_POWER_STATE_D0);
1502
1503        /* Intialize the queues. */
1504        QQ_InitQueue (&pDevice->RxPacketReceivedQ.Container,
1505                      MAX_RX_PACKET_DESC_COUNT);
1506        QQ_InitQueue (&pDevice->RxPacketFreeQ.Container,
1507                      MAX_RX_PACKET_DESC_COUNT);
1508
1509        QQ_InitQueue (&pDevice->TxPacketFreeQ.Container,
1510                      MAX_TX_PACKET_DESC_COUNT);
1511        QQ_InitQueue (&pDevice->TxPacketActiveQ.Container,
1512                      MAX_TX_PACKET_DESC_COUNT);
1513        QQ_InitQueue (&pDevice->TxPacketXmittedQ.Container,
1514                      MAX_TX_PACKET_DESC_COUNT);
1515
1516        /* Allocate shared memory for: status block, the buffers for receive */
1517        /* rings -- standard, mini, jumbo, and return rings. */
1518        Size = T3_STATUS_BLOCK_SIZE + sizeof (T3_STATS_BLOCK) +
1519            T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
1520#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1521            T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD) +
1522#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1523            T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1524
1525        /* Memory for host based Send BD. */
1526        if (pDevice->NicSendBd == FALSE) {
1527                Size += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1528        }
1529
1530        /* Allocate the memory block. */
1531        Status =
1532            MM_AllocateSharedMemory (pDevice, Size, (PLM_VOID) & pMemVirt,
1533                                     &MemPhy, FALSE);
1534        if (Status != LM_STATUS_SUCCESS) {
1535                return Status;
1536        }
1537
1538        /* Program DMA Read/Write */
1539        if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) {
1540                pDevice->DmaReadWriteCtrl = 0x763f000f;
1541        } else {
1542                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5704) {
1543                        pDevice->DmaReadWriteCtrl = 0x761f0000;
1544                } else {
1545                        pDevice->DmaReadWriteCtrl = 0x761b000f;
1546                }
1547                if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1548                    pDevice->ChipRevId == T3_CHIP_ID_5703_A2) {
1549                        pDevice->OneDmaAtOnce = TRUE;
1550                }
1551        }
1552        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5703) {
1553                pDevice->DmaReadWriteCtrl &= 0xfffffff0;
1554        }
1555
1556        if (pDevice->OneDmaAtOnce) {
1557                pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
1558        }
1559        REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
1560
1561        if (LM_DmaTest (pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS) {
1562                return LM_STATUS_FAILURE;
1563        }
1564
1565        /* Status block. */
1566        pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
1567        pDevice->StatusBlkPhy = MemPhy;
1568        pMemVirt += T3_STATUS_BLOCK_SIZE;
1569        LM_INC_PHYSICAL_ADDRESS (&MemPhy, T3_STATUS_BLOCK_SIZE);
1570
1571        /* Statistics block. */
1572        pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
1573        pDevice->StatsBlkPhy = MemPhy;
1574        pMemVirt += sizeof (T3_STATS_BLOCK);
1575        LM_INC_PHYSICAL_ADDRESS (&MemPhy, sizeof (T3_STATS_BLOCK));
1576
1577        /* Receive standard BD buffer. */
1578        pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
1579        pDevice->RxStdBdPhy = MemPhy;
1580
1581        pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1582        LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1583                                 T3_STD_RCV_RCB_ENTRY_COUNT *
1584                                 sizeof (T3_RCV_BD));
1585
1586#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1587        /* Receive jumbo BD buffer. */
1588        pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
1589        pDevice->RxJumboBdPhy = MemPhy;
1590
1591        pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1592        LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1593                                 T3_JUMBO_RCV_RCB_ENTRY_COUNT *
1594                                 sizeof (T3_RCV_BD));
1595#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1596
1597        /* Receive return BD buffer. */
1598        pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
1599        pDevice->RcvRetBdPhy = MemPhy;
1600
1601        pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof (T3_RCV_BD);
1602        LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1603                                 T3_RCV_RETURN_RCB_ENTRY_COUNT *
1604                                 sizeof (T3_RCV_BD));
1605
1606        /* Set up Send BD. */
1607        if (pDevice->NicSendBd == FALSE) {
1608                pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
1609                pDevice->SendBdPhy = MemPhy;
1610
1611                pMemVirt += sizeof (T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1612                LM_INC_PHYSICAL_ADDRESS (&MemPhy,
1613                                         sizeof (T3_SND_BD) *
1614                                         T3_SEND_RCB_ENTRY_COUNT);
1615        } else {
1616                pDevice->pSendBdVirt = (PT3_SND_BD)
1617                    pDevice->pMemView->uIntMem.First32k.BufferDesc;
1618                pDevice->SendBdPhy.High = 0;
1619                pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
1620        }
1621
1622        /* Allocate memory for packet descriptors. */
1623        Size = (pDevice->RxPacketDescCnt +
1624                pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
1625        Status = MM_AllocateMemory (pDevice, Size, (PLM_VOID *) & pPacket);
1626        if (Status != LM_STATUS_SUCCESS) {
1627                return Status;
1628        }
1629        pDevice->pPacketDescBase = (PLM_VOID) pPacket;
1630
1631        /* Create transmit packet descriptors from the memory block and add them */
1632        /* to the TxPacketFreeQ for each send ring. */
1633        for (j = 0; j < pDevice->TxPacketDescCnt; j++) {
1634                /* Ring index. */
1635                pPacket->Flags = 0;
1636
1637                /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
1638                QQ_PushTail (&pDevice->TxPacketFreeQ.Container, pPacket);
1639
1640                /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1641                /* is the total size of the packet descriptor including the */
1642                /* os-specific extensions in the UM_PACKET structure. */
1643                pPacket =
1644                    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1645        }                       /* for(j.. */
1646
1647        /* Create receive packet descriptors from the memory block and add them */
1648        /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
1649        for (j = 0; j < pDevice->RxStdDescCnt; j++) {
1650                /* Receive producer ring. */
1651                pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
1652
1653                /* Receive buffer size. */
1654                pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
1655
1656                /* Add the descriptor to RxPacketFreeQ. */
1657                QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
1658
1659                /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1660                /* is the total size of the packet descriptor including the */
1661                /* os-specific extensions in the UM_PACKET structure. */
1662                pPacket =
1663                    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1664        }                       /* for */
1665
1666#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1667        /* Create the Jumbo packet descriptors. */
1668        for (j = 0; j < pDevice->RxJumboDescCnt; j++) {
1669                /* Receive producer ring. */
1670                pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
1671
1672                /* Receive buffer size. */
1673                pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
1674
1675                /* Add the descriptor to RxPacketFreeQ. */
1676                QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
1677
1678                /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1679                /* is the total size of the packet descriptor including the */
1680                /* os-specific extensions in the UM_PACKET structure. */
1681                pPacket =
1682                    (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1683        }                       /* for */
1684#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1685
1686        /* Initialize the rest of the packet descriptors. */
1687        Status = MM_InitializeUmPackets (pDevice);
1688        if (Status != LM_STATUS_SUCCESS) {
1689                return Status;
1690        }
1691
1692        /* if */
1693        /* Default receive mask. */
1694        pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1695            LM_ACCEPT_UNICAST;
1696
1697        /* Make sure we are in the first 32k memory window or NicSendBd. */
1698        REG_WR (pDevice, PciCfg.MemWindowBaseAddr, 0);
1699
1700        /* Initialize the hardware. */
1701        Status = LM_ResetAdapter (pDevice);
1702        if (Status != LM_STATUS_SUCCESS) {
1703                return Status;
1704        }
1705
1706        /* We are done with initialization. */
1707        pDevice->InitDone = TRUE;
1708
1709        return LM_STATUS_SUCCESS;
1710}                               /* LM_InitializeAdapter */
1711
1712/******************************************************************************/
1713/* Description:                                                               */
1714/*    This function Enables/Disables a given block.                          */
1715/*                                                                            */
1716/* Return:                                                                    */
1717/*    LM_STATUS_SUCCESS                                                       */
1718/******************************************************************************/
1719LM_STATUS
1720LM_CntrlBlock (PLM_DEVICE_BLOCK pDevice, LM_UINT32 mask, LM_UINT32 cntrl)
1721{
1722        LM_UINT32 j, i, data;
1723        LM_UINT32 MaxWaitCnt;
1724
1725        MaxWaitCnt = 2;
1726        j = 0;
1727
1728        for (i = 0; i < 32; i++) {
1729                if (!(mask & (1 << i)))
1730                        continue;
1731
1732                switch (1 << i) {
1733                case T3_BLOCK_DMA_RD:
1734                        data = REG_RD (pDevice, DmaRead.Mode);
1735                        if (cntrl == LM_DISABLE) {
1736                                data &= ~DMA_READ_MODE_ENABLE;
1737                                REG_WR (pDevice, DmaRead.Mode, data);
1738                                for (j = 0; j < MaxWaitCnt; j++) {
1739                                        if (!
1740                                            (REG_RD (pDevice, DmaRead.Mode) &
1741                                             DMA_READ_MODE_ENABLE))
1742                                                break;
1743                                        MM_Wait (10);
1744                                }
1745                        } else
1746                                REG_WR (pDevice, DmaRead.Mode,
1747                                        data | DMA_READ_MODE_ENABLE);
1748                        break;
1749
1750                case T3_BLOCK_DMA_COMP:
1751                        data = REG_RD (pDevice, DmaComp.Mode);
1752                        if (cntrl == LM_DISABLE) {
1753                                data &= ~DMA_COMP_MODE_ENABLE;
1754                                REG_WR (pDevice, DmaComp.Mode, data);
1755                                for (j = 0; j < MaxWaitCnt; j++) {
1756                                        if (!
1757                                            (REG_RD (pDevice, DmaComp.Mode) &
1758                                             DMA_COMP_MODE_ENABLE))
1759                                                break;
1760                                        MM_Wait (10);
1761                                }
1762                        } else
1763                                REG_WR (pDevice, DmaComp.Mode,
1764                                        data | DMA_COMP_MODE_ENABLE);
1765                        break;
1766
1767                case T3_BLOCK_RX_BD_INITIATOR:
1768                        data = REG_RD (pDevice, RcvBdIn.Mode);
1769                        if (cntrl == LM_DISABLE) {
1770                                data &= ~RCV_BD_IN_MODE_ENABLE;
1771                                REG_WR (pDevice, RcvBdIn.Mode, data);
1772                                for (j = 0; j < MaxWaitCnt; j++) {
1773                                        if (!
1774                                            (REG_RD (pDevice, RcvBdIn.Mode) &
1775                                             RCV_BD_IN_MODE_ENABLE))
1776                                                break;
1777                                        MM_Wait (10);
1778                                }
1779                        } else
1780                                REG_WR (pDevice, RcvBdIn.Mode,
1781                                        data | RCV_BD_IN_MODE_ENABLE);
1782                        break;
1783
1784                case T3_BLOCK_RX_BD_COMP:
1785                        data = REG_RD (pDevice, RcvBdComp.Mode);
1786                        if (cntrl == LM_DISABLE) {
1787                                data &= ~RCV_BD_COMP_MODE_ENABLE;
1788                                REG_WR (pDevice, RcvBdComp.Mode, data);
1789                                for (j = 0; j < MaxWaitCnt; j++) {
1790                                        if (!
1791                                            (REG_RD (pDevice, RcvBdComp.Mode) &
1792                                             RCV_BD_COMP_MODE_ENABLE))
1793                                                break;
1794                                        MM_Wait (10);
1795                                }
1796                        } else
1797                                REG_WR (pDevice, RcvBdComp.Mode,
1798                                        data | RCV_BD_COMP_MODE_ENABLE);
1799                        break;
1800
1801                case T3_BLOCK_DMA_WR:
1802                        data = REG_RD (pDevice, DmaWrite.Mode);
1803                        if (cntrl == LM_DISABLE) {
1804                                data &= ~DMA_WRITE_MODE_ENABLE;
1805                                REG_WR (pDevice, DmaWrite.Mode, data);
1806
1807                                for (j = 0; j < MaxWaitCnt; j++) {
1808                                        if (!
1809                                            (REG_RD (pDevice, DmaWrite.Mode) &
1810                                             DMA_WRITE_MODE_ENABLE))
1811                                                break;
1812                                        MM_Wait (10);
1813                                }
1814                        } else
1815                                REG_WR (pDevice, DmaWrite.Mode,
1816                                        data | DMA_WRITE_MODE_ENABLE);
1817                        break;
1818
1819                case T3_BLOCK_MSI_HANDLER:
1820                        data = REG_RD (pDevice, Msi.Mode);
1821                        if (cntrl == LM_DISABLE) {
1822                                data &= ~MSI_MODE_ENABLE;
1823                                REG_WR (pDevice, Msi.Mode, data);
1824                                for (j = 0; j < MaxWaitCnt; j++) {
1825                                        if (!
1826                                            (REG_RD (pDevice, Msi.Mode) &
1827                                             MSI_MODE_ENABLE))
1828                                                break;
1829                                        MM_Wait (10);
1830                                }
1831                        } else
1832                                REG_WR (pDevice, Msi.Mode,
1833                                        data | MSI_MODE_ENABLE);
1834                        break;
1835
1836                case T3_BLOCK_RX_LIST_PLMT:
1837                        data = REG_RD (pDevice, RcvListPlmt.Mode);
1838                        if (cntrl == LM_DISABLE) {
1839                                data &= ~RCV_LIST_PLMT_MODE_ENABLE;
1840                                REG_WR (pDevice, RcvListPlmt.Mode, data);
1841                                for (j = 0; j < MaxWaitCnt; j++) {
1842                                        if (!
1843                                            (REG_RD (pDevice, RcvListPlmt.Mode)
1844                                             & RCV_LIST_PLMT_MODE_ENABLE))
1845                                                break;
1846                                        MM_Wait (10);
1847                                }
1848                        } else
1849                                REG_WR (pDevice, RcvListPlmt.Mode,
1850                                        data | RCV_LIST_PLMT_MODE_ENABLE);
1851                        break;
1852
1853                case T3_BLOCK_RX_LIST_SELECTOR:
1854                        data = REG_RD (pDevice, RcvListSel.Mode);
1855                        if (cntrl == LM_DISABLE) {
1856                                data &= ~RCV_LIST_SEL_MODE_ENABLE;
1857                                REG_WR (pDevice, RcvListSel.Mode, data);
1858                                for (j = 0; j < MaxWaitCnt; j++) {
1859                                        if (!
1860                                            (REG_RD (pDevice, RcvListSel.Mode) &
1861                                             RCV_LIST_SEL_MODE_ENABLE))
1862                                                break;
1863                                        MM_Wait (10);
1864                                }
1865                        } else
1866                                REG_WR (pDevice, RcvListSel.Mode,
1867                                        data | RCV_LIST_SEL_MODE_ENABLE);
1868                        break;
1869
1870                case T3_BLOCK_RX_DATA_INITIATOR:
1871                        data = REG_RD (pDevice, RcvDataBdIn.Mode);
1872                        if (cntrl == LM_DISABLE) {
1873                                data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
1874                                REG_WR (pDevice, RcvDataBdIn.Mode, data);
1875                                for (j = 0; j < MaxWaitCnt; j++) {
1876                                        if (!
1877                                            (REG_RD (pDevice, RcvDataBdIn.Mode)
1878                                             & RCV_DATA_BD_IN_MODE_ENABLE))
1879                                                break;
1880                                        MM_Wait (10);
1881                                }
1882                        } else
1883                                REG_WR (pDevice, RcvDataBdIn.Mode,
1884                                        data | RCV_DATA_BD_IN_MODE_ENABLE);
1885                        break;
1886
1887                case T3_BLOCK_RX_DATA_COMP:
1888                        data = REG_RD (pDevice, RcvDataComp.Mode);
1889                        if (cntrl == LM_DISABLE) {
1890                                data &= ~RCV_DATA_COMP_MODE_ENABLE;
1891                                REG_WR (pDevice, RcvDataComp.Mode, data);
1892                                for (j = 0; j < MaxWaitCnt; j++) {
1893                                        if (!
1894                                            (REG_RD (pDevice, RcvDataBdIn.Mode)
1895                                             & RCV_DATA_COMP_MODE_ENABLE))
1896                                                break;
1897                                        MM_Wait (10);
1898                                }
1899                        } else
1900                                REG_WR (pDevice, RcvDataComp.Mode,
1901                                        data | RCV_DATA_COMP_MODE_ENABLE);
1902                        break;
1903
1904                case T3_BLOCK_HOST_COALESING:
1905                        data = REG_RD (pDevice, HostCoalesce.Mode);
1906                        if (cntrl == LM_DISABLE) {
1907                                data &= ~HOST_COALESCE_ENABLE;
1908                                REG_WR (pDevice, HostCoalesce.Mode, data);
1909                                for (j = 0; j < MaxWaitCnt; j++) {
1910                                        if (!
1911                                            (REG_RD (pDevice, SndBdIn.Mode) &
1912                                             HOST_COALESCE_ENABLE))
1913                                                break;
1914                                        MM_Wait (10);
1915                                }
1916                        } else
1917                                REG_WR (pDevice, HostCoalesce.Mode,
1918                                        data | HOST_COALESCE_ENABLE);
1919                        break;
1920
1921                case T3_BLOCK_MAC_RX_ENGINE:
1922                        if (cntrl == LM_DISABLE) {
1923                                pDevice->RxMode &= ~RX_MODE_ENABLE;
1924                                REG_WR (pDevice, MacCtrl.RxMode,
1925                                        pDevice->RxMode);
1926                                for (j = 0; j < MaxWaitCnt; j++) {
1927                                        if (!
1928                                            (REG_RD (pDevice, MacCtrl.RxMode) &
1929                                             RX_MODE_ENABLE)) {
1930                                                break;
1931                                        }
1932                                        MM_Wait (10);
1933                                }
1934                        } else {
1935                                pDevice->RxMode |= RX_MODE_ENABLE;
1936                                REG_WR (pDevice, MacCtrl.RxMode,
1937                                        pDevice->RxMode);
1938                        }
1939                        break;
1940
1941                case T3_BLOCK_MBUF_CLUSTER_FREE:
1942                        data = REG_RD (pDevice, MbufClusterFree.Mode);
1943                        if (cntrl == LM_DISABLE) {
1944                                data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
1945                                REG_WR (pDevice, MbufClusterFree.Mode, data);
1946                                for (j = 0; j < MaxWaitCnt; j++) {
1947                                        if (!
1948                                            (REG_RD
1949                                             (pDevice,
1950                                              MbufClusterFree.
1951                                              Mode) &
1952                                             MBUF_CLUSTER_FREE_MODE_ENABLE))
1953                                                break;
1954                                        MM_Wait (10);
1955                                }
1956                        } else
1957                                REG_WR (pDevice, MbufClusterFree.Mode,
1958                                        data | MBUF_CLUSTER_FREE_MODE_ENABLE);
1959                        break;
1960
1961                case T3_BLOCK_SEND_BD_INITIATOR:
1962                        data = REG_RD (pDevice, SndBdIn.Mode);
1963                        if (cntrl == LM_DISABLE) {
1964                                data &= ~SND_BD_IN_MODE_ENABLE;
1965                                REG_WR (pDevice, SndBdIn.Mode, data);
1966                                for (j = 0; j < MaxWaitCnt; j++) {
1967                                        if (!
1968                                            (REG_RD (pDevice, SndBdIn.Mode) &
1969                                             SND_BD_IN_MODE_ENABLE))
1970                                                break;
1971                                        MM_Wait (10);
1972                                }
1973                        } else
1974                                REG_WR (pDevice, SndBdIn.Mode,
1975                                        data | SND_BD_IN_MODE_ENABLE);
1976                        break;
1977
1978                case T3_BLOCK_SEND_BD_COMP:
1979                        data = REG_RD (pDevice, SndBdComp.Mode);
1980                        if (cntrl == LM_DISABLE) {
1981                                data &= ~SND_BD_COMP_MODE_ENABLE;
1982                                REG_WR (pDevice, SndBdComp.Mode, data);
1983                                for (j = 0; j < MaxWaitCnt; j++) {
1984                                        if (!
1985                                            (REG_RD (pDevice, SndBdComp.Mode) &
1986                                             SND_BD_COMP_MODE_ENABLE))
1987                                                break;
1988                                        MM_Wait (10);
1989                                }
1990                        } else
1991                                REG_WR (pDevice, SndBdComp.Mode,
1992                                        data | SND_BD_COMP_MODE_ENABLE);
1993                        break;
1994
1995                case T3_BLOCK_SEND_BD_SELECTOR:
1996                        data = REG_RD (pDevice, SndBdSel.Mode);
1997                        if (cntrl == LM_DISABLE) {
1998                                data &= ~SND_BD_SEL_MODE_ENABLE;
1999                                REG_WR (pDevice, SndBdSel.Mode, data);
2000                                for (j = 0; j < MaxWaitCnt; j++) {
2001                                        if (!
2002                                            (REG_RD (pDevice, SndBdSel.Mode) &
2003                                             SND_BD_SEL_MODE_ENABLE))
2004                                                break;
2005                                        MM_Wait (10);
2006                                }
2007                        } else
2008                                REG_WR (pDevice, SndBdSel.Mode,
2009                                        data | SND_BD_SEL_MODE_ENABLE);
2010                        break;
2011
2012                case T3_BLOCK_SEND_DATA_INITIATOR:
2013                        data = REG_RD (pDevice, SndDataIn.Mode);
2014                        if (cntrl == LM_DISABLE) {
2015                                data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2016                                REG_WR (pDevice, SndDataIn.Mode, data);
2017                                for (j = 0; j < MaxWaitCnt; j++) {
2018                                        if (!
2019                                            (REG_RD (pDevice, SndDataIn.Mode) &
2020                                             T3_SND_DATA_IN_MODE_ENABLE))
2021                                                break;
2022                                        MM_Wait (10);
2023                                }
2024                        } else
2025                                REG_WR (pDevice, SndDataIn.Mode,
2026                                        data | T3_SND_DATA_IN_MODE_ENABLE);
2027                        break;
2028
2029                case T3_BLOCK_SEND_DATA_COMP:
2030                        data = REG_RD (pDevice, SndDataComp.Mode);
2031                        if (cntrl == LM_DISABLE) {
2032                                data &= ~SND_DATA_COMP_MODE_ENABLE;
2033                                REG_WR (pDevice, SndDataComp.Mode, data);
2034                                for (j = 0; j < MaxWaitCnt; j++) {
2035                                        if (!
2036                                            (REG_RD (pDevice, SndDataComp.Mode)
2037                                             & SND_DATA_COMP_MODE_ENABLE))
2038                                                break;
2039                                        MM_Wait (10);
2040                                }
2041                        } else
2042                                REG_WR (pDevice, SndDataComp.Mode,
2043                                        data | SND_DATA_COMP_MODE_ENABLE);
2044                        break;
2045
2046                case T3_BLOCK_MAC_TX_ENGINE:
2047                        if (cntrl == LM_DISABLE) {
2048                                pDevice->TxMode &= ~TX_MODE_ENABLE;
2049                                REG_WR (pDevice, MacCtrl.TxMode,
2050                                        pDevice->TxMode);
2051                                for (j = 0; j < MaxWaitCnt; j++) {
2052                                        if (!
2053                                            (REG_RD (pDevice, MacCtrl.TxMode) &
2054                                             TX_MODE_ENABLE))
2055                                                break;
2056                                        MM_Wait (10);
2057                                }
2058                        } else {
2059                                pDevice->TxMode |= TX_MODE_ENABLE;
2060                                REG_WR (pDevice, MacCtrl.TxMode,
2061                                        pDevice->TxMode);
2062                        }
2063                        break;
2064
2065                case T3_BLOCK_MEM_ARBITOR:
2066                        data = REG_RD (pDevice, MemArbiter.Mode);
2067                        if (cntrl == LM_DISABLE) {
2068                                data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2069                                REG_WR (pDevice, MemArbiter.Mode, data);
2070                                for (j = 0; j < MaxWaitCnt; j++) {
2071                                        if (!
2072                                            (REG_RD (pDevice, MemArbiter.Mode) &
2073                                             T3_MEM_ARBITER_MODE_ENABLE))
2074                                                break;
2075                                        MM_Wait (10);
2076                                }
2077                        } else
2078                                REG_WR (pDevice, MemArbiter.Mode,
2079                                        data | T3_MEM_ARBITER_MODE_ENABLE);
2080                        break;
2081
2082                case T3_BLOCK_MBUF_MANAGER:
2083                        data = REG_RD (pDevice, BufMgr.Mode);
2084                        if (cntrl == LM_DISABLE) {
2085                                data &= ~BUFMGR_MODE_ENABLE;
2086                                REG_WR (pDevice, BufMgr.Mode, data);
2087                                for (j = 0; j < MaxWaitCnt; j++) {
2088                                        if (!
2089                                            (REG_RD (pDevice, BufMgr.Mode) &
2090                                             BUFMGR_MODE_ENABLE))
2091                                                break;
2092                                        MM_Wait (10);
2093                                }
2094                        } else
2095                                REG_WR (pDevice, BufMgr.Mode,
2096                                        data | BUFMGR_MODE_ENABLE);
2097                        break;
2098
2099                case T3_BLOCK_MAC_GLOBAL:
2100                        if (cntrl == LM_DISABLE) {
2101                                pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
2102                                                      MAC_MODE_ENABLE_RDE |
2103                                                      MAC_MODE_ENABLE_FHDE);
2104                        } else {
2105                                pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
2106                                                     MAC_MODE_ENABLE_RDE |
2107                                                     MAC_MODE_ENABLE_FHDE);
2108                        }
2109                        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
2110                        break;
2111
2112                default:
2113                        return LM_STATUS_FAILURE;
2114                }               /* switch */
2115
2116                if (j >= MaxWaitCnt) {
2117                        return LM_STATUS_FAILURE;
2118                }
2119        }
2120
2121        return LM_STATUS_SUCCESS;
2122}
2123
2124/******************************************************************************/
2125/* Description:                                                               */
2126/*    This function reinitializes the adapter.                                */
2127/*                                                                            */
2128/* Return:                                                                    */
2129/*    LM_STATUS_SUCCESS                                                       */
2130/******************************************************************************/
2131LM_STATUS LM_ResetAdapter (PLM_DEVICE_BLOCK pDevice)
2132{
2133        LM_UINT32 Value32;
2134        LM_UINT16 Value16;
2135        LM_UINT32 j, k;
2136
2137        /* Disable interrupt. */
2138        LM_DisableInterrupt (pDevice);
2139
2140        /* May get a spurious interrupt */
2141        pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2142
2143        /* Disable transmit and receive DMA engines.  Abort all pending requests. */
2144        if (pDevice->InitDone) {
2145                LM_Abort (pDevice);
2146        }
2147
2148        pDevice->ShuttingDown = FALSE;
2149
2150        LM_ResetChip (pDevice);
2151
2152        /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
2153        /* in other chip revisions. */
2154        if (pDevice->DelayPciGrant) {
2155                Value32 = REG_RD (pDevice, PciCfg.ClockCtrl);
2156                REG_WR (pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
2157        }
2158
2159        if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
2160                if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
2161                        Value32 = REG_RD (pDevice, PciCfg.PciState);
2162                        Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2163                        REG_WR (pDevice, PciCfg.PciState, Value32);
2164                }
2165        }
2166
2167        /* Enable TaggedStatus mode. */
2168        if (pDevice->UseTaggedStatus) {
2169                pDevice->MiscHostCtrl |=
2170                    MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2171        }
2172
2173        /* Restore PCI configuration registers. */
2174        MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
2175                          pDevice->SavedCacheLineReg);
2176        MM_WriteConfig32 (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2177                          (pDevice->SubsystemId << 16) | pDevice->
2178                          SubsystemVendorId);
2179
2180        /* Clear the statistics block. */
2181        for (j = 0x0300; j < 0x0b00; j++) {
2182                MEM_WR_OFFSET (pDevice, j, 0);
2183        }
2184
2185        /* Initialize the statistis Block */
2186        pDevice->pStatusBlkVirt->Status = 0;
2187        pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2188        pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2189        pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2190
2191        for (j = 0; j < 16; j++) {
2192                pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2193                pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2194        }
2195
2196        for (k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT; k++) {
2197                pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2198                pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2199        }
2200
2201#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2202        /* Receive jumbo BD buffer. */
2203        for (k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++) {
2204                pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2205                pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2206        }
2207#endif
2208
2209        REG_WR (pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2210
2211        /* GRC mode control register. */
2212#ifdef BIG_ENDIAN_PCI           /* Jimmy, this ifdef block deleted in new code! */
2213        Value32 =
2214            GRC_MODE_WORD_SWAP_DATA |
2215            GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2216            GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
2217#else
2218        /* No CPU Swap modes for PCI IO */
2219        Value32 =
2220#ifdef BIG_ENDIAN_HOST
2221            GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2222            GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2223            GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
2224#else
2225            GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2226            GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA |
2227#endif
2228            GRC_MODE_INT_ON_MAC_ATTN | GRC_MODE_HOST_STACK_UP;
2229#endif                          /* !BIG_ENDIAN_PCI */
2230
2231        /* Configure send BD mode. */
2232        if (pDevice->NicSendBd == FALSE) {
2233                Value32 |= GRC_MODE_HOST_SEND_BDS;
2234        } else {
2235                Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2236        }
2237
2238        /* Configure pseudo checksum mode. */
2239        if (pDevice->NoTxPseudoHdrChksum) {
2240                Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2241        }
2242
2243        if (pDevice->NoRxPseudoHdrChksum) {
2244                Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2245        }
2246
2247        REG_WR (pDevice, Grc.Mode, Value32);
2248
2249        /* Setup the timer prescalar register. */
2250        REG_WR (pDevice, Grc.MiscCfg, 65 << 1); /* Clock is alwasy 66MHz. */
2251
2252        /* Set up the MBUF pool base address and size. */
2253        REG_WR (pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2254        REG_WR (pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2255
2256        /* Set up the DMA descriptor pool base address and size. */
2257        REG_WR (pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2258        REG_WR (pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2259
2260        /* Configure MBUF and Threshold watermarks */
2261        /* Configure the DMA read MBUF low water mark. */
2262        if (pDevice->DmaMbufLowMark) {
2263                REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2264                        pDevice->DmaMbufLowMark);
2265        } else {
2266                if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2267                        REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2268                                T3_DEF_DMA_MBUF_LOW_WMARK);
2269                } else {
2270                        REG_WR (pDevice, BufMgr.MbufReadDmaLowWaterMark,
2271                                T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2272                }
2273        }
2274
2275        /* Configure the MAC Rx MBUF low water mark. */
2276        if (pDevice->RxMacMbufLowMark) {
2277                REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2278                        pDevice->RxMacMbufLowMark);
2279        } else {
2280                if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2281                        REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2282                                T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2283                } else {
2284                        REG_WR (pDevice, BufMgr.MbufMacRxLowWaterMark,
2285                                T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2286                }
2287        }
2288
2289        /* Configure the MBUF high water mark. */
2290        if (pDevice->MbufHighMark) {
2291                REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2292                        pDevice->MbufHighMark);
2293        } else {
2294                if (pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE) {
2295                        REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2296                                T3_DEF_MBUF_HIGH_WMARK);
2297                } else {
2298                        REG_WR (pDevice, BufMgr.MbufHighWaterMark,
2299                                T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2300                }
2301        }
2302
2303        REG_WR (pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2304        REG_WR (pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2305
2306        /* Enable buffer manager. */
2307        REG_WR (pDevice, BufMgr.Mode,
2308                BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2309
2310        for (j = 0; j < 2000; j++) {
2311                if (REG_RD (pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2312                        break;
2313                MM_Wait (10);
2314        }
2315
2316        if (j >= 2000) {
2317                return LM_STATUS_FAILURE;
2318        }
2319
2320        /* Enable the FTQs. */
2321        REG_WR (pDevice, Ftq.Reset, 0xffffffff);
2322        REG_WR (pDevice, Ftq.Reset, 0);
2323
2324        /* Wait until FTQ is ready */
2325        for (j = 0; j < 2000; j++) {
2326                if (REG_RD (pDevice, Ftq.Reset) == 0)
2327                        break;
2328                MM_Wait (10);
2329        }
2330
2331        if (j >= 2000) {
2332                return LM_STATUS_FAILURE;
2333        }
2334
2335        /* Initialize the Standard Receive RCB. */
2336        REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2337                pDevice->RxStdBdPhy.High);
2338        REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2339                pDevice->RxStdBdPhy.Low);
2340        REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2341                MAX_STD_RCV_BUFFER_SIZE << 16);
2342
2343        /* Initialize the Jumbo Receive RCB. */
2344        REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2345                T3_RCB_FLAG_RING_DISABLED);
2346#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2347        REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2348                pDevice->RxJumboBdPhy.High);
2349        REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2350                pDevice->RxJumboBdPhy.Low);
2351
2352        REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2353
2354#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2355
2356        /* Initialize the Mini Receive RCB. */
2357        REG_WR (pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2358                T3_RCB_FLAG_RING_DISABLED);
2359
2360        {
2361                REG_WR (pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2362                        (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2363                REG_WR (pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2364                        (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2365        }
2366
2367        /* Receive BD Ring replenish threshold. */
2368        REG_WR (pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt / 8);
2369#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2370        REG_WR (pDevice, RcvBdIn.JumboRcvThreshold,
2371                pDevice->RxJumboDescCnt / 8);
2372#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2373
2374        /* Disable all the unused rings. */
2375        for (j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2376                MEM_WR (pDevice, SendRcb[j].u.MaxLen_Flags,
2377                        T3_RCB_FLAG_RING_DISABLED);
2378        }                       /* for */
2379
2380        /* Initialize the indices. */
2381        pDevice->SendProdIdx = 0;
2382        pDevice->SendConIdx = 0;
2383
2384        MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2385        MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2386
2387        /* Set up host or NIC based send RCB. */
2388        if (pDevice->NicSendBd == FALSE) {
2389                MEM_WR (pDevice, SendRcb[0].HostRingAddr.High,
2390                        pDevice->SendBdPhy.High);
2391                MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low,
2392                        pDevice->SendBdPhy.Low);
2393
2394                /* Set up the NIC ring address in the RCB. */
2395                MEM_WR (pDevice, SendRcb[0].NicRingAddr,
2396                        T3_NIC_SND_BUFFER_DESC_ADDR);
2397
2398                /* Setup the RCB. */
2399                MEM_WR (pDevice, SendRcb[0].u.MaxLen_Flags,
2400                        T3_SEND_RCB_ENTRY_COUNT << 16);
2401
2402                for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
2403                        pDevice->pSendBdVirt[k].HostAddr.High = 0;
2404                        pDevice->pSendBdVirt[k].HostAddr.Low = 0;
2405                }
2406        } else {
2407                MEM_WR (pDevice, SendRcb[0].HostRingAddr.High, 0);
2408                MEM_WR (pDevice, SendRcb[0].HostRingAddr.Low, 0);
2409                MEM_WR (pDevice, SendRcb[0].NicRingAddr,
2410                        pDevice->SendBdPhy.Low);
2411
2412                for (k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++) {
2413                        __raw_writel (0,
2414                                      &(pDevice->pSendBdVirt[k].HostAddr.High));
2415                        __raw_writel (0,
2416                                      &(pDevice->pSendBdVirt[k].HostAddr.Low));
2417                        __raw_writel (0,
2418                                      &(pDevice->pSendBdVirt[k].u1.Len_Flags));
2419                        pDevice->ShadowSendBd[k].HostAddr.High = 0;
2420                        pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
2421                }
2422        }
2423        atomic_set (&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT - 1);
2424
2425        /* Configure the receive return rings. */
2426        for (j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++) {
2427                MEM_WR (pDevice, RcvRetRcb[j].u.MaxLen_Flags,
2428                        T3_RCB_FLAG_RING_DISABLED);
2429        }
2430
2431        pDevice->RcvRetConIdx = 0;
2432
2433        MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.High,
2434                pDevice->RcvRetBdPhy.High);
2435        MEM_WR (pDevice, RcvRetRcb[0].HostRingAddr.Low,
2436                pDevice->RcvRetBdPhy.Low);
2437
2438        /* Set up the NIC ring address in the RCB. */
2439        /* Not very clear from the spec.  I am guessing that for Receive */
2440        /* Return Ring, NicRingAddr is not used. */
2441        MEM_WR (pDevice, RcvRetRcb[0].NicRingAddr, 0);
2442
2443        /* Setup the RCB. */
2444        MEM_WR (pDevice, RcvRetRcb[0].u.MaxLen_Flags,
2445                T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
2446
2447        /* Reinitialize RX ring producer index */
2448        MB_REG_WR (pDevice, Mailbox.RcvStdProdIdx.Low, 0);
2449        MB_REG_WR (pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
2450        MB_REG_WR (pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
2451
2452#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2453        pDevice->RxJumboProdIdx = 0;
2454        pDevice->RxJumboQueuedCnt = 0;
2455#endif
2456
2457        /* Reinitialize our copy of the indices. */
2458        pDevice->RxStdProdIdx = 0;
2459        pDevice->RxStdQueuedCnt = 0;
2460
2461#if T3_JUMBO_RCV_ENTRY_COUNT
2462        pDevice->RxJumboProdIdx = 0;
2463#endif                          /* T3_JUMBO_RCV_ENTRY_COUNT */
2464
2465        /* Configure the MAC address. */
2466        LM_SetMacAddress (pDevice);
2467
2468        /* Initialize the transmit random backoff seed. */
2469        Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
2470                   pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
2471                   pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
2472            MAC_TX_BACKOFF_SEED_MASK;
2473        REG_WR (pDevice, MacCtrl.TxBackoffSeed, Value32);
2474
2475        /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
2476        REG_WR (pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);  /* CRC + VLAN. */
2477
2478        /* Configure Time slot/IPG per 802.3 */
2479        REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
2480
2481        /*
2482         * Configure Receive Rules so that packets don't match
2483         * Programmble rule will be queued to Return Ring 1
2484         */
2485        REG_WR (pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
2486
2487        /*
2488         * Configure to have 16 Classes of Services (COS) and one
2489         * queue per class.  Bad frames are queued to RRR#1.
2490         * And frames don't match rules are also queued to COS#1.
2491         */
2492        REG_WR (pDevice, RcvListPlmt.Config, 0x181);
2493
2494        /* Enable Receive Placement Statistics */
2495        REG_WR (pDevice, RcvListPlmt.StatsEnableMask, 0xffffff);
2496        REG_WR (pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
2497
2498        /* Enable Send Data Initator Statistics */
2499        REG_WR (pDevice, SndDataIn.StatsEnableMask, 0xffffff);
2500        REG_WR (pDevice, SndDataIn.StatsCtrl,
2501                T3_SND_DATA_IN_STATS_CTRL_ENABLE |
2502                T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
2503
2504        /* Disable the host coalescing state machine before configuring it's */
2505        /* parameters. */
2506        REG_WR (pDevice, HostCoalesce.Mode, 0);
2507        for (j = 0; j < 2000; j++) {
2508                Value32 = REG_RD (pDevice, HostCoalesce.Mode);
2509                if (!(Value32 & HOST_COALESCE_ENABLE)) {
2510                        break;
2511                }
2512                MM_Wait (10);
2513        }
2514
2515        /* Host coalescing configurations. */
2516        REG_WR (pDevice, HostCoalesce.RxCoalescingTicks,
2517                pDevice->RxCoalescingTicks);
2518        REG_WR (pDevice, HostCoalesce.TxCoalescingTicks,
2519                pDevice->TxCoalescingTicks);
2520        REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFrames,
2521                pDevice->RxMaxCoalescedFrames);
2522        REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFrames,
2523                pDevice->TxMaxCoalescedFrames);
2524        REG_WR (pDevice, HostCoalesce.RxCoalescedTickDuringInt,
2525                pDevice->RxCoalescingTicksDuringInt);
2526        REG_WR (pDevice, HostCoalesce.TxCoalescedTickDuringInt,
2527                pDevice->TxCoalescingTicksDuringInt);
2528        REG_WR (pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
2529                pDevice->RxMaxCoalescedFramesDuringInt);
2530        REG_WR (pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
2531                pDevice->TxMaxCoalescedFramesDuringInt);
2532
2533        /* Initialize the address of the status block.  The NIC will DMA */
2534        /* the status block to this memory which resides on the host. */
2535        REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.High,
2536                pDevice->StatusBlkPhy.High);
2537        REG_WR (pDevice, HostCoalesce.StatusBlkHostAddr.Low,
2538                pDevice->StatusBlkPhy.Low);
2539
2540        /* Initialize the address of the statistics block.  The NIC will DMA */
2541        /* the statistics to this block of memory. */
2542        REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.High,
2543                pDevice->StatsBlkPhy.High);
2544        REG_WR (pDevice, HostCoalesce.StatsBlkHostAddr.Low,
2545                pDevice->StatsBlkPhy.Low);
2546
2547        REG_WR (pDevice, HostCoalesce.StatsCoalescingTicks,
2548                pDevice->StatsCoalescingTicks);
2549
2550        REG_WR (pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
2551        REG_WR (pDevice, HostCoalesce.StatusBlkNicAddr, 0xb00);
2552
2553        /* Enable Host Coalesing state machine */
2554        REG_WR (pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
2555                pDevice->CoalesceMode);
2556
2557        /* Enable the Receive BD Completion state machine. */
2558        REG_WR (pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
2559                RCV_BD_COMP_MODE_ATTN_ENABLE);
2560
2561        /* Enable the Receive List Placement state machine. */
2562        REG_WR (pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
2563
2564        /* Enable the Receive List Selector state machine. */
2565        REG_WR (pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
2566                RCV_LIST_SEL_MODE_ATTN_ENABLE);
2567
2568        /* Enable transmit DMA, clear statistics. */
2569        pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
2570            MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
2571            MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
2572        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
2573                MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
2574
2575        /* GRC miscellaneous local control register. */
2576        pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
2577            GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
2578
2579        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2580                pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
2581                    GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
2582        }
2583
2584        REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
2585        MM_Wait (40);
2586
2587        /* Reset RX counters. */
2588        for (j = 0; j < sizeof (LM_RX_COUNTERS); j++) {
2589                ((PLM_UINT8) & pDevice->RxCounters)[j] = 0;
2590        }
2591
2592        /* Reset TX counters. */
2593        for (j = 0; j < sizeof (LM_TX_COUNTERS); j++) {
2594                ((PLM_UINT8) & pDevice->TxCounters)[j] = 0;
2595        }
2596
2597        MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
2598
2599        /* Enable the DMA Completion state machine. */
2600        REG_WR (pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
2601
2602        /* Enable the DMA Write state machine. */
2603        Value32 = DMA_WRITE_MODE_ENABLE |
2604            DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
2605            DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
2606            DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
2607            DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2608            DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2609            DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2610            DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2611            DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
2612        REG_WR (pDevice, DmaWrite.Mode, Value32);
2613
2614        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
2615                if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
2616                        Value16 = REG_RD (pDevice, PciCfg.PciXCommand);
2617                        Value16 &=
2618                            ~(PCIX_CMD_MAX_SPLIT_MASK |
2619                              PCIX_CMD_MAX_BURST_MASK);
2620                        Value16 |=
2621                            ((PCIX_CMD_MAX_BURST_CPIOB <<
2622                              PCIX_CMD_MAX_BURST_SHL) &
2623                             PCIX_CMD_MAX_BURST_MASK);
2624                        if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
2625                                Value16 |=
2626                                    (pDevice->
2627                                     SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
2628                                    & PCIX_CMD_MAX_SPLIT_MASK;
2629                        }
2630                        REG_WR (pDevice, PciCfg.PciXCommand, Value16);
2631                }
2632        }
2633
2634        /* Enable the Read DMA state machine. */
2635        Value32 = DMA_READ_MODE_ENABLE |
2636            DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
2637            DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
2638            DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
2639            DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2640            DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2641            DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2642            DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2643            DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
2644
2645        if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE) {
2646                Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
2647        }
2648        REG_WR (pDevice, DmaRead.Mode, Value32);
2649
2650        /* Enable the Receive Data Completion state machine. */
2651        REG_WR (pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
2652                RCV_DATA_COMP_MODE_ATTN_ENABLE);
2653
2654        /* Enable the Mbuf Cluster Free state machine. */
2655        REG_WR (pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
2656
2657        /* Enable the Send Data Completion state machine. */
2658        REG_WR (pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
2659
2660        /* Enable the Send BD Completion state machine. */
2661        REG_WR (pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
2662                SND_BD_COMP_MODE_ATTN_ENABLE);
2663
2664        /* Enable the Receive BD Initiator state machine. */
2665        REG_WR (pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
2666                RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
2667
2668        /* Enable the Receive Data and Receive BD Initiator state machine. */
2669        REG_WR (pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
2670                RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
2671
2672        /* Enable the Send Data Initiator state machine. */
2673        REG_WR (pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
2674
2675        /* Enable the Send BD Initiator state machine. */
2676        REG_WR (pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
2677                SND_BD_IN_MODE_ATTN_ENABLE);
2678
2679        /* Enable the Send BD Selector state machine. */
2680        REG_WR (pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
2681                SND_BD_SEL_MODE_ATTN_ENABLE);
2682
2683#if INCLUDE_5701_AX_FIX
2684        /* Load the firmware for the 5701_A0 workaround. */
2685        if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0) {
2686                LM_LoadRlsFirmware (pDevice);
2687        }
2688#endif
2689
2690        /* Enable the transmitter. */
2691        pDevice->TxMode = TX_MODE_ENABLE;
2692        REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
2693
2694        /* Enable the receiver. */
2695        pDevice->RxMode = RX_MODE_ENABLE;
2696        REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
2697
2698        if (pDevice->RestoreOnWakeUp) {
2699                pDevice->RestoreOnWakeUp = FALSE;
2700                pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
2701                pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
2702        }
2703
2704        /* Disable auto polling. */
2705        pDevice->MiMode = 0xc0000;
2706        REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
2707
2708        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2709            T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
2710                Value32 = LED_CTRL_PHY_MODE_1;
2711        } else {
2712                if (pDevice->LedMode == LED_MODE_OUTPUT) {
2713                        Value32 = LED_CTRL_PHY_MODE_2;
2714                } else {
2715                        Value32 = LED_CTRL_PHY_MODE_1;
2716                }
2717        }
2718        REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
2719
2720        /* Activate Link to enable MAC state machine */
2721        REG_WR (pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
2722
2723        if (pDevice->EnableTbi) {
2724                REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_RESET);
2725                MM_Wait (10);
2726                REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
2727                if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1) {
2728                        REG_WR (pDevice, MacCtrl.SerdesCfg, 0x616000);
2729                }
2730        }
2731        /* Setup the phy chip. */
2732        LM_SetupPhy (pDevice);
2733
2734        if (!pDevice->EnableTbi) {
2735                /* Clear CRC stats */
2736                LM_ReadPhy (pDevice, 0x1e, &Value32);
2737                LM_WritePhy (pDevice, 0x1e, Value32 | 0x8000);
2738                LM_ReadPhy (pDevice, 0x14, &Value32);
2739        }
2740
2741        /* Set up the receive mask. */
2742        LM_SetReceiveMask (pDevice, pDevice->ReceiveMask);
2743
2744        /* Queue Rx packet buffers. */
2745        if (pDevice->QueueRxPackets) {
2746                LM_QueueRxPackets (pDevice);
2747        }
2748
2749        /* Enable interrupt to the host. */
2750        if (pDevice->InitDone) {
2751                LM_EnableInterrupt (pDevice);
2752        }
2753
2754        return LM_STATUS_SUCCESS;
2755}                               /* LM_ResetAdapter */
2756
2757/******************************************************************************/
2758/* Description:                                                               */
2759/*    This routine disables the adapter from generating interrupts.           */
2760/*                                                                            */
2761/* Return:                                                                    */
2762/*    LM_STATUS_SUCCESS                                                       */
2763/******************************************************************************/
2764LM_STATUS LM_DisableInterrupt (PLM_DEVICE_BLOCK pDevice)
2765{
2766        REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
2767                MISC_HOST_CTRL_MASK_PCI_INT);
2768        MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 1);
2769
2770        return LM_STATUS_SUCCESS;
2771}
2772
2773/******************************************************************************/
2774/* Description:                                                               */
2775/*    This routine enables the adapter to generate interrupts.                */
2776/*                                                                            */
2777/* Return:                                                                    */
2778/*    LM_STATUS_SUCCESS                                                       */
2779/******************************************************************************/
2780LM_STATUS LM_EnableInterrupt (PLM_DEVICE_BLOCK pDevice)
2781{
2782        REG_WR (pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
2783                ~MISC_HOST_CTRL_MASK_PCI_INT);
2784        MB_REG_WR (pDevice, Mailbox.Interrupt[0].Low, 0);
2785
2786        if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
2787                REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
2788                        GRC_MISC_LOCAL_CTRL_SET_INT);
2789        }
2790
2791        return LM_STATUS_SUCCESS;
2792}
2793
2794/******************************************************************************/
2795/* Description:                                                               */
2796/*    This routine puts a packet on the wire if there is a transmit DMA       */
2797/*    descriptor available; otherwise the packet is queued for later          */
2798/*    transmission.  If the second argue is NULL, this routine will put       */
2799/*    the queued packet on the wire if possible.                              */
2800/*                                                                            */
2801/* Return:                                                                    */
2802/*    LM_STATUS_SUCCESS                                                       */
2803/******************************************************************************/
2804#if 0
2805LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
2806{
2807        LM_UINT32 FragCount;
2808        PT3_SND_BD pSendBd;
2809        PT3_SND_BD pShadowSendBd;
2810        LM_UINT32 Value32, Len;
2811        LM_UINT32 Idx;
2812
2813        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2814                return LM_5700SendPacket (pDevice, pPacket);
2815        }
2816
2817        /* Update the SendBdLeft count. */
2818        atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
2819
2820        /* Initalize the send buffer descriptors. */
2821        Idx = pDevice->SendProdIdx;
2822
2823        pSendBd = &pDevice->pSendBdVirt[Idx];
2824
2825        /* Next producer index. */
2826        if (pDevice->NicSendBd == TRUE) {
2827                T3_64BIT_HOST_ADDR paddr;
2828
2829                pShadowSendBd = &pDevice->ShadowSendBd[Idx];
2830                for (FragCount = 0;;) {
2831                        MM_MapTxDma (pDevice, pPacket, &paddr, &Len, FragCount);
2832                        /* Initialize the pointer to the send buffer fragment. */
2833                        if (paddr.High != pShadowSendBd->HostAddr.High) {
2834                                __raw_writel (paddr.High,
2835                                              &(pSendBd->HostAddr.High));
2836                                pShadowSendBd->HostAddr.High = paddr.High;
2837                        }
2838                        __raw_writel (paddr.Low, &(pSendBd->HostAddr.Low));
2839
2840                        /* Setup the control flags and send buffer size. */
2841                        Value32 = (Len << 16) | pPacket->Flags;
2842
2843                        Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2844
2845                        FragCount++;
2846                        if (FragCount >= pPacket->u.Tx.FragCount) {
2847                                Value32 |= SND_BD_FLAG_END;
2848                                if (Value32 != pShadowSendBd->u1.Len_Flags) {
2849                                        __raw_writel (Value32,
2850                                                      &(pSendBd->u1.Len_Flags));
2851                                        pShadowSendBd->u1.Len_Flags = Value32;
2852                                }
2853                                if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
2854                                        __raw_writel (pPacket->VlanTag,
2855                                                      &(pSendBd->u2.VlanTag));
2856                                }
2857                                break;
2858                        } else {
2859                                if (Value32 != pShadowSendBd->u1.Len_Flags) {
2860                                        __raw_writel (Value32,
2861                                                      &(pSendBd->u1.Len_Flags));
2862                                        pShadowSendBd->u1.Len_Flags = Value32;
2863                                }
2864                                if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
2865                                        __raw_writel (pPacket->VlanTag,
2866                                                      &(pSendBd->u2.VlanTag));
2867                                }
2868                        }
2869
2870                        pSendBd++;
2871                        pShadowSendBd++;
2872                        if (Idx == 0) {
2873                                pSendBd = &pDevice->pSendBdVirt[0];
2874                                pShadowSendBd = &pDevice->ShadowSendBd[0];
2875                        }
2876                }               /* for */
2877
2878                /* Put the packet descriptor in the ActiveQ. */
2879                QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2880
2881                wmb ();
2882                MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
2883
2884        } else {
2885                for (FragCount = 0;;) {
2886                        /* Initialize the pointer to the send buffer fragment. */
2887                        MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
2888                                     FragCount);
2889
2890                        pSendBd->u2.VlanTag = pPacket->VlanTag;
2891
2892                        /* Setup the control flags and send buffer size. */
2893                        Value32 = (Len << 16) | pPacket->Flags;
2894
2895                        Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2896
2897                        FragCount++;
2898                        if (FragCount >= pPacket->u.Tx.FragCount) {
2899                                pSendBd->u1.Len_Flags =
2900                                    Value32 | SND_BD_FLAG_END;
2901                                break;
2902                        } else {
2903                                pSendBd->u1.Len_Flags = Value32;
2904                        }
2905                        pSendBd++;
2906                        if (Idx == 0) {
2907                                pSendBd = &pDevice->pSendBdVirt[0];
2908                        }
2909                }               /* for */
2910
2911                /* Put the packet descriptor in the ActiveQ. */
2912                QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2913
2914                wmb ();
2915                MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
2916
2917        }
2918
2919        /* Update the producer index. */
2920        pDevice->SendProdIdx = Idx;
2921
2922        return LM_STATUS_SUCCESS;
2923}
2924#endif
2925
2926LM_STATUS LM_SendPacket (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
2927{
2928        LM_UINT32 FragCount;
2929        PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
2930        T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
2931        LM_UINT32 StartIdx, Idx;
2932
2933        while (1) {
2934                /* Initalize the send buffer descriptors. */
2935                StartIdx = Idx = pDevice->SendProdIdx;
2936
2937                if (pDevice->NicSendBd) {
2938                        pTmpSendBd = pSendBd = &NicSendBdArr[0];
2939                } else {
2940                        pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
2941                }
2942
2943                /* Next producer index. */
2944                for (FragCount = 0;;) {
2945                        LM_UINT32 Value32, Len;
2946
2947                        /* Initialize the pointer to the send buffer fragment. */
2948                        MM_MapTxDma (pDevice, pPacket, &pSendBd->HostAddr, &Len,
2949                                     FragCount);
2950
2951                        pSendBd->u2.VlanTag = pPacket->VlanTag;
2952
2953                        /* Setup the control flags and send buffer size. */
2954                        Value32 = (Len << 16) | pPacket->Flags;
2955
2956                        Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
2957
2958                        FragCount++;
2959                        if (FragCount >= pPacket->u.Tx.FragCount) {
2960                                pSendBd->u1.Len_Flags =
2961                                    Value32 | SND_BD_FLAG_END;
2962                                break;
2963                        } else {
2964                                pSendBd->u1.Len_Flags = Value32;
2965                        }
2966                        pSendBd++;
2967                        if ((Idx == 0) && !pDevice->NicSendBd) {
2968                                pSendBd = &pDevice->pSendBdVirt[0];
2969                        }
2970                }               /* for */
2971                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
2972                        if (LM_Test4GBoundary (pDevice, pPacket, pTmpSendBd) ==
2973                            LM_STATUS_SUCCESS) {
2974                                if (MM_CoalesceTxBuffer (pDevice, pPacket) !=
2975                                    LM_STATUS_SUCCESS) {
2976                                        QQ_PushHead (&pDevice->TxPacketFreeQ.
2977                                                     Container, pPacket);
2978                                        return LM_STATUS_FAILURE;
2979                                }
2980                                continue;
2981                        }
2982                }
2983                break;
2984        }
2985        /* Put the packet descriptor in the ActiveQ. */
2986        QQ_PushTail (&pDevice->TxPacketActiveQ.Container, pPacket);
2987
2988        if (pDevice->NicSendBd) {
2989                pSendBd = &pDevice->pSendBdVirt[StartIdx];
2990                pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
2991
2992                while (StartIdx != Idx) {
2993                        LM_UINT32 Value32;
2994
2995                        if ((Value32 = pTmpSendBd->HostAddr.High) !=
2996                            pShadowSendBd->HostAddr.High) {
2997                                __raw_writel (Value32,
2998                                              &(pSendBd->HostAddr.High));
2999                                pShadowSendBd->HostAddr.High = Value32;
3000                        }
3001
3002                        __raw_writel (pTmpSendBd->HostAddr.Low,
3003                                      &(pSendBd->HostAddr.Low));
3004
3005                        if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3006                            pShadowSendBd->u1.Len_Flags) {
3007                                __raw_writel (Value32,
3008                                              &(pSendBd->u1.Len_Flags));
3009                                pShadowSendBd->u1.Len_Flags = Value32;
3010                        }
3011
3012                        if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3013                                __raw_writel (pTmpSendBd->u2.VlanTag,
3014                                              &(pSendBd->u2.VlanTag));
3015                        }
3016
3017                        StartIdx =
3018                            (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3019                        if (StartIdx == 0)
3020                                pSendBd = &pDevice->pSendBdVirt[0];
3021                        else
3022                                pSendBd++;
3023                        pTmpSendBd++;
3024                }
3025                wmb ();
3026                MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3027
3028                if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
3029                        MB_REG_WR (pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3030                }
3031        } else {
3032                wmb ();
3033                MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3034
3035                if (T3_CHIP_REV (pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
3036                        MB_REG_WR (pDevice, Mailbox.SendHostProdIdx[0].Low,
3037                                   Idx);
3038                }
3039        }
3040
3041        /* Update the SendBdLeft count. */
3042        atomic_sub (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3043
3044        /* Update the producer index. */
3045        pDevice->SendProdIdx = Idx;
3046
3047        return LM_STATUS_SUCCESS;
3048}
3049
3050STATIC LM_STATUS
3051LM_Test4GBoundary (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3052                   PT3_SND_BD pSendBd)
3053{
3054        int FragCount;
3055        LM_UINT32 Idx, Base, Len;
3056
3057        Idx = pDevice->SendProdIdx;
3058        for (FragCount = 0;;) {
3059                Len = pSendBd->u1.Len_Flags >> 16;
3060                if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3061                    (pSendBd->HostAddr.High == 0) &&
3062                    ((Base + 8 + Len) < Base)) {
3063                        return LM_STATUS_SUCCESS;
3064                }
3065                FragCount++;
3066                if (FragCount >= pPacket->u.Tx.FragCount) {
3067                        break;
3068                }
3069                pSendBd++;
3070                if (!pDevice->NicSendBd) {
3071                        Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3072                        if (Idx == 0) {
3073                                pSendBd = &pDevice->pSendBdVirt[0];
3074                        }
3075                }
3076        }
3077        return LM_STATUS_FAILURE;
3078}
3079
3080/******************************************************************************/
3081/* Description:                                                               */
3082/*                                                                            */
3083/* Return:                                                                    */
3084/******************************************************************************/
3085__inline static unsigned long
3086ComputeCrc32 (unsigned char *pBuffer, unsigned long BufferSize)
3087{
3088        unsigned long Reg;
3089        unsigned long Tmp;
3090        unsigned long j, k;
3091
3092        Reg = 0xffffffff;
3093
3094        for (j = 0; j < BufferSize; j++) {
3095                Reg ^= pBuffer[j];
3096
3097                for (k = 0; k < 8; k++) {
3098                        Tmp = Reg & 0x01;
3099
3100                        Reg >>= 1;
3101
3102                        if (Tmp) {
3103                                Reg ^= 0xedb88320;
3104                        }
3105                }
3106        }
3107
3108        return ~Reg;
3109}                               /* ComputeCrc32 */
3110
3111/******************************************************************************/
3112/* Description:                                                               */
3113/*    This routine sets the receive control register according to ReceiveMask */
3114/*                                                                            */
3115/* Return:                                                                    */
3116/*    LM_STATUS_SUCCESS                                                       */
3117/******************************************************************************/
3118LM_STATUS LM_SetReceiveMask (PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
3119{
3120        LM_UINT32 ReceiveMask;
3121        LM_UINT32 RxMode;
3122        LM_UINT32 j, k;
3123
3124        ReceiveMask = Mask;
3125
3126        RxMode = pDevice->RxMode;
3127
3128        if (Mask & LM_ACCEPT_UNICAST) {
3129                Mask &= ~LM_ACCEPT_UNICAST;
3130        }
3131
3132        if (Mask & LM_ACCEPT_MULTICAST) {
3133                Mask &= ~LM_ACCEPT_MULTICAST;
3134        }
3135
3136        if (Mask & LM_ACCEPT_ALL_MULTICAST) {
3137                Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3138        }
3139
3140        if (Mask & LM_ACCEPT_BROADCAST) {
3141                Mask &= ~LM_ACCEPT_BROADCAST;
3142        }
3143
3144        RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3145        if (Mask & LM_PROMISCUOUS_MODE) {
3146                RxMode |= RX_MODE_PROMISCUOUS_MODE;
3147                Mask &= ~LM_PROMISCUOUS_MODE;
3148        }
3149
3150        RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3151        if (Mask & LM_ACCEPT_ERROR_PACKET) {
3152                RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3153                Mask &= ~LM_ACCEPT_ERROR_PACKET;
3154        }
3155
3156        /* Make sure all the bits are valid before committing changes. */
3157        if (Mask) {
3158                return LM_STATUS_FAILURE;
3159        }
3160
3161        /* Commit the new filter. */
3162        pDevice->RxMode = RxMode;
3163        REG_WR (pDevice, MacCtrl.RxMode, RxMode);
3164
3165        pDevice->ReceiveMask = ReceiveMask;
3166
3167        /* Set up the MC hash table. */
3168        if (ReceiveMask & LM_ACCEPT_ALL_MULTICAST) {
3169                for (k = 0; k < 4; k++) {
3170                        REG_WR (pDevice, MacCtrl.HashReg[k], 0xffffffff);
3171                }
3172        } else if (ReceiveMask & LM_ACCEPT_MULTICAST) {
3173                LM_UINT32 HashReg[4];
3174
3175                HashReg[0] = 0;
3176                HashReg[1] = 0;
3177                HashReg[2] = 0;
3178                HashReg[3] = 0;
3179                for (j = 0; j < pDevice->McEntryCount; j++) {
3180                        LM_UINT32 RegIndex;
3181                        LM_UINT32 Bitpos;
3182                        LM_UINT32 Crc32;
3183
3184                        Crc32 =
3185                            ComputeCrc32 (pDevice->McTable[j],
3186                                          ETHERNET_ADDRESS_SIZE);
3187
3188                        /* The most significant 7 bits of the CRC32 (no inversion), */
3189                        /* are used to index into one of the possible 128 bit positions. */
3190                        Bitpos = ~Crc32 & 0x7f;
3191
3192                        /* Hash register index. */
3193                        RegIndex = (Bitpos & 0x60) >> 5;
3194
3195                        /* Bit to turn on within a hash register. */
3196                        Bitpos &= 0x1f;
3197
3198                        /* Enable the multicast bit. */
3199                        HashReg[RegIndex] |= (1 << Bitpos);
3200                }
3201
3202                /* REV_AX has problem with multicast filtering where it uses both */
3203                /* DA and SA to perform hashing. */
3204                for (k = 0; k < 4; k++) {
3205                        REG_WR (pDevice, MacCtrl.HashReg[k], HashReg[k]);
3206                }
3207        } else {
3208                /* Reject all multicast frames. */
3209                for (j = 0; j < 4; j++) {
3210                        REG_WR (pDevice, MacCtrl.HashReg[j], 0);
3211                }
3212        }
3213
3214        /* By default, Tigon3 will accept broadcast frames.  We need to setup */
3215        if (ReceiveMask & LM_ACCEPT_BROADCAST) {
3216                REG_WR (pDevice,
3217                        MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3218                        REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3219                REG_WR (pDevice,
3220                        MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3221                        REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3222                REG_WR (pDevice,
3223                        MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3224                        REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3225                REG_WR (pDevice,
3226                        MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3227                        REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3228        } else {
3229                REG_WR (pDevice,
3230                        MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3231                        REJECT_BROADCAST_RULE1_RULE);
3232                REG_WR (pDevice,
3233                        MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3234                        REJECT_BROADCAST_RULE1_VALUE);
3235                REG_WR (pDevice,
3236                        MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3237                        REJECT_BROADCAST_RULE2_RULE);
3238                REG_WR (pDevice,
3239                        MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3240                        REJECT_BROADCAST_RULE2_VALUE);
3241        }
3242
3243        /* disable the rest of the rules. */
3244        for (j = RCV_LAST_RULE_IDX; j < 16; j++) {
3245                REG_WR (pDevice, MacCtrl.RcvRules[j].Rule, 0);
3246                REG_WR (pDevice, MacCtrl.RcvRules[j].Value, 0);
3247        }
3248
3249        return LM_STATUS_SUCCESS;
3250}                               /* LM_SetReceiveMask */
3251
3252/******************************************************************************/
3253/* Description:                                                               */
3254/*    Disable the interrupt and put the transmitter and receiver engines in   */
3255/*    an idle state.  Also aborts all pending send requests and receive       */
3256/*    buffers.                                                                */
3257/*                                                                            */
3258/* Return:                                                                    */
3259/*    LM_STATUS_SUCCESS                                                       */
3260/******************************************************************************/
3261LM_STATUS LM_Abort (PLM_DEVICE_BLOCK pDevice)
3262{
3263        PLM_PACKET pPacket;
3264        LM_UINT Idx;
3265
3266        LM_DisableInterrupt (pDevice);
3267
3268        /* Disable all the state machines. */
3269        LM_CntrlBlock (pDevice, T3_BLOCK_MAC_RX_ENGINE, LM_DISABLE);
3270        LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_INITIATOR, LM_DISABLE);
3271        LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_PLMT, LM_DISABLE);
3272        LM_CntrlBlock (pDevice, T3_BLOCK_RX_LIST_SELECTOR, LM_DISABLE);
3273        LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_INITIATOR, LM_DISABLE);
3274        LM_CntrlBlock (pDevice, T3_BLOCK_RX_DATA_COMP, LM_DISABLE);
3275        LM_CntrlBlock (pDevice, T3_BLOCK_RX_BD_COMP, LM_DISABLE);
3276
3277        LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_SELECTOR, LM_DISABLE);
3278        LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_INITIATOR, LM_DISABLE);
3279        LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_INITIATOR, LM_DISABLE);
3280        LM_CntrlBlock (pDevice, T3_BLOCK_DMA_RD, LM_DISABLE);
3281        LM_CntrlBlock (pDevice, T3_BLOCK_SEND_DATA_COMP, LM_DISABLE);
3282        LM_CntrlBlock (pDevice, T3_BLOCK_DMA_COMP, LM_DISABLE);
3283        LM_CntrlBlock (pDevice, T3_BLOCK_SEND_BD_COMP, LM_DISABLE);
3284
3285        /* Clear TDE bit */
3286        pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
3287        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
3288
3289        LM_CntrlBlock (pDevice, T3_BLOCK_MAC_TX_ENGINE, LM_DISABLE);
3290        LM_CntrlBlock (pDevice, T3_BLOCK_HOST_COALESING, LM_DISABLE);
3291        LM_CntrlBlock (pDevice, T3_BLOCK_DMA_WR, LM_DISABLE);
3292        LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_CLUSTER_FREE, LM_DISABLE);
3293
3294        /* Reset all FTQs */
3295        REG_WR (pDevice, Ftq.Reset, 0xffffffff);
3296        REG_WR (pDevice, Ftq.Reset, 0x0);
3297
3298        LM_CntrlBlock (pDevice, T3_BLOCK_MBUF_MANAGER, LM_DISABLE);
3299        LM_CntrlBlock (pDevice, T3_BLOCK_MEM_ARBITOR, LM_DISABLE);
3300
3301        MM_ACQUIRE_INT_LOCK (pDevice);
3302
3303        /* Abort packets that have already queued to go out. */
3304        pPacket = (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
3305        while (pPacket) {
3306
3307                pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3308                pDevice->TxCounters.TxPacketAbortedCnt++;
3309
3310                atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3311
3312                QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
3313
3314                pPacket = (PLM_PACKET)
3315                    QQ_PopHead (&pDevice->TxPacketActiveQ.Container);
3316        }
3317
3318        /* Cleanup the receive return rings. */
3319        LM_ServiceRxInterrupt (pDevice);
3320
3321        /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
3322        /* Doing so may cause system crash. */
3323        if (!pDevice->ShuttingDown) {
3324                /* Indicate packets to the protocol. */
3325                MM_IndicateTxPackets (pDevice);
3326
3327                /* Indicate received packets to the protocols. */
3328                MM_IndicateRxPackets (pDevice);
3329        } else {
3330                /* Move the receive packet descriptors in the ReceivedQ to the */
3331                /* free queue. */
3332                for (;;) {
3333                        pPacket =
3334                            (PLM_PACKET) QQ_PopHead (&pDevice->
3335                                                     RxPacketReceivedQ.
3336                                                     Container);
3337                        if (pPacket == NULL) {
3338                                break;
3339                        }
3340                        QQ_PushTail (&pDevice->RxPacketFreeQ.Container,
3341                                     pPacket);
3342                }
3343        }
3344
3345        /* Clean up the Std Receive Producer ring. */
3346        Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
3347
3348        while (Idx != pDevice->RxStdProdIdx) {
3349                pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3350                                        MM_UINT_PTR (pDevice->pRxStdBdVirt[Idx].
3351                                                     Opaque));
3352
3353                QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3354
3355                Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
3356        }                       /* while */
3357
3358        /* Reinitialize our copy of the indices. */
3359        pDevice->RxStdProdIdx = 0;
3360
3361#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3362        /* Clean up the Jumbo Receive Producer ring. */
3363        Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
3364
3365        while (Idx != pDevice->RxJumboProdIdx) {
3366                pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3367                                        MM_UINT_PTR (pDevice->
3368                                                     pRxJumboBdVirt[Idx].
3369                                                     Opaque));
3370
3371                QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3372
3373                Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
3374        }                       /* while */
3375
3376        /* Reinitialize our copy of the indices. */
3377        pDevice->RxJumboProdIdx = 0;
3378#endif                          /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3379
3380        MM_RELEASE_INT_LOCK (pDevice);
3381
3382        /* Initialize the statistis Block */
3383        pDevice->pStatusBlkVirt->Status = 0;
3384        pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
3385        pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
3386        pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
3387
3388        return LM_STATUS_SUCCESS;
3389}                               /* LM_Abort */
3390
3391/******************************************************************************/
3392/* Description:                                                               */
3393/*    Disable the interrupt and put the transmitter and receiver engines in   */
3394/*    an idle state.  Aborts all pending send requests and receive buffers.   */
3395/*    Also free all the receive buffers.                                      */
3396/*                                                                            */
3397/* Return:                                                                    */
3398/*    LM_STATUS_SUCCESS                                                       */
3399/******************************************************************************/
3400LM_STATUS LM_Halt (PLM_DEVICE_BLOCK pDevice)
3401{
3402        PLM_PACKET pPacket;
3403        LM_UINT32 EntryCnt;
3404
3405        LM_Abort (pDevice);
3406
3407        /* Get the number of entries in the queue. */
3408        EntryCnt = QQ_GetEntryCnt (&pDevice->RxPacketFreeQ.Container);
3409
3410        /* Make sure all the packets have been accounted for. */
3411        for (EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++) {
3412                pPacket =
3413                    (PLM_PACKET) QQ_PopHead (&pDevice->RxPacketFreeQ.Container);
3414                if (pPacket == 0)
3415                        break;
3416
3417                MM_FreeRxBuffer (pDevice, pPacket);
3418
3419                QQ_PushTail (&pDevice->RxPacketFreeQ.Container, pPacket);
3420        }
3421
3422        LM_ResetChip (pDevice);
3423
3424        /* Restore PCI configuration registers. */
3425        MM_WriteConfig32 (pDevice, PCI_CACHE_LINE_SIZE_REG,
3426                          pDevice->SavedCacheLineReg);
3427        LM_RegWrInd (pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
3428                     (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
3429
3430        /* Reprogram the MAC address. */
3431        LM_SetMacAddress (pDevice);
3432
3433        return LM_STATUS_SUCCESS;
3434}                               /* LM_Halt */
3435
3436STATIC LM_STATUS LM_ResetChip (PLM_DEVICE_BLOCK pDevice)
3437{
3438        LM_UINT32 Value32;
3439        LM_UINT32 j;
3440
3441        /* Wait for access to the nvram interface before resetting.  This is */
3442        /* a workaround to prevent EEPROM corruption. */
3443        if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
3444            T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
3445                /* Request access to the flash interface. */
3446                REG_WR (pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
3447
3448                for (j = 0; j < 100000; j++) {
3449                        Value32 = REG_RD (pDevice, Nvram.SwArb);
3450                        if (Value32 & SW_ARB_GNT1) {
3451                                break;
3452                        }
3453                        MM_Wait (10);
3454                }
3455        }
3456
3457        /* Global reset. */
3458        REG_WR (pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
3459        MM_Wait (40);
3460        MM_Wait (40);
3461        MM_Wait (40);
3462
3463        /* make sure we re-enable indirect accesses */
3464        MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
3465                          pDevice->MiscHostCtrl);
3466
3467        /* Set MAX PCI retry to zero. */
3468        Value32 =
3469            T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
3470        if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
3471                if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
3472                        Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
3473                }
3474        }
3475        MM_WriteConfig32 (pDevice, T3_PCI_STATE_REG, Value32);
3476
3477        /* Restore PCI command register. */
3478        MM_WriteConfig32 (pDevice, PCI_COMMAND_REG,
3479                          pDevice->PciCommandStatusWords);
3480
3481        /* Disable PCI-X relaxed ordering bit. */
3482        MM_ReadConfig32 (pDevice, PCIX_CAP_REG, &Value32);
3483        Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
3484        MM_WriteConfig32 (pDevice, PCIX_CAP_REG, Value32);
3485
3486        /* Enable memory arbiter. */
3487        REG_WR (pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
3488
3489#ifdef BIG_ENDIAN_PCI           /* This from jfd */
3490        Value32 = GRC_MODE_WORD_SWAP_DATA | GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
3491#else
3492#ifdef BIG_ENDIAN_HOST
3493        /* Reconfigure the mode register. */
3494        Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
3495            GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3496            GRC_MODE_BYTE_SWAP_DATA | GRC_MODE_WORD_SWAP_DATA;
3497#else
3498        /* Reconfigure the mode register. */
3499        Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
3500#endif
3501#endif
3502        REG_WR (pDevice, Grc.Mode, Value32);
3503
3504        /* Prevent PXE from restarting. */
3505        MEM_WR_OFFSET (pDevice, 0x0b50, T3_MAGIC_NUM);
3506
3507        if (pDevice->EnableTbi) {
3508                pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
3509                REG_WR (pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
3510        } else {
3511                REG_WR (pDevice, MacCtrl.Mode, 0);
3512        }
3513
3514        /* Wait for the firmware to finish initialization. */
3515        for (j = 0; j < 100000; j++) {
3516                MM_Wait (10);
3517
3518                Value32 = MEM_RD_OFFSET (pDevice, 0x0b50);
3519                if (Value32 == ~T3_MAGIC_NUM) {
3520                        break;
3521                }
3522        }
3523        return LM_STATUS_SUCCESS;
3524}
3525
3526/******************************************************************************/
3527/* Description:                                                               */
3528/*                                                                            */
3529/* Return:                                                                    */
3530/******************************************************************************/
3531__inline static void LM_ServiceTxInterrupt (PLM_DEVICE_BLOCK pDevice)
3532{
3533        PLM_PACKET pPacket;
3534        LM_UINT32 HwConIdx;
3535        LM_UINT32 SwConIdx;
3536
3537        HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3538
3539        /* Get our copy of the consumer index.  The buffer descriptors */
3540        /* that are in between the consumer indices are freed. */
3541        SwConIdx = pDevice->SendConIdx;
3542
3543        /* Move the packets from the TxPacketActiveQ that are sent out to */
3544        /* the TxPacketXmittedQ.  Packets that are sent use the */
3545        /* descriptors that are between SwConIdx and HwConIdx. */
3546        while (SwConIdx != HwConIdx) {
3547                /* Get the packet that was sent from the TxPacketActiveQ. */
3548                pPacket =
3549                    (PLM_PACKET) QQ_PopHead (&pDevice->TxPacketActiveQ.
3550                                             Container);
3551
3552                /* Set the return status. */
3553                pPacket->PacketStatus = LM_STATUS_SUCCESS;
3554
3555                /* Put the packet in the TxPacketXmittedQ for indication later. */
3556                QQ_PushTail (&pDevice->TxPacketXmittedQ.Container, pPacket);
3557
3558                /* Move to the next packet's BD. */
3559                SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
3560                    T3_SEND_RCB_ENTRY_COUNT_MASK;
3561
3562                /* Update the number of unused BDs. */
3563                atomic_add (pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3564
3565                /* Get the new updated HwConIdx. */
3566                HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3567        }                       /* while */
3568
3569        /* Save the new SwConIdx. */
3570        pDevice->SendConIdx = SwConIdx;
3571
3572}                               /* LM_ServiceTxInterrupt */
3573
3574/******************************************************************************/
3575/* Description:                                                               */
3576/*                                                                            */
3577/* Return:                                                                    */
3578/******************************************************************************/
3579__inline static void LM_ServiceRxInterrupt (PLM_DEVICE_BLOCK pDevice)
3580{
3581        PLM_PACKET pPacket;
3582        PT3_RCV_BD pRcvBd;
3583        LM_UINT32 HwRcvRetProdIdx;
3584        LM_UINT32 SwRcvRetConIdx;
3585
3586        /* Loop thru the receive return rings for received packets. */
3587        HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3588
3589        SwRcvRetConIdx = pDevice->RcvRetConIdx;
3590        while (SwRcvRetConIdx != HwRcvRetProdIdx) {
3591                pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
3592
3593                /* Get the received packet descriptor. */
3594                pPacket = (PLM_PACKET) (MM_UINT_PTR (pDevice->pPacketDescBase) +
3595                                        MM_UINT_PTR (pRcvBd->Opaque));
3596
3597                /* Check the error flag. */
3598                if (pRcvBd->ErrorFlag &&
3599                    pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
3600                        pPacket->PacketStatus = LM_STATUS_FAILURE;
3601
3602                        pDevice->RxCounters.RxPacketErrCnt++;
3603
3604                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC) {
3605                                pDevice->RxCounters.RxErrCrcCnt++;
3606                        }
3607
3608                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT) {
3609                                pDevice->RxCounters.RxErrCollCnt++;
3610                        }
3611
3612                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT) {
3613                                pDevice->RxCounters.RxErrLinkLostCnt++;
3614                        }
3615
3616                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR) {
3617                                pDevice->RxCounters.RxErrPhyDecodeCnt++;
3618                        }
3619
3620                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
3621                                pDevice->RxCounters.RxErrOddNibbleCnt++;
3622                        }
3623
3624                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT) {
3625                                pDevice->RxCounters.RxErrMacAbortCnt++;
3626                        }
3627
3628                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64) {
3629                                pDevice->RxCounters.RxErrShortPacketCnt++;
3630                        }
3631
3632                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES) {
3633                                pDevice->RxCounters.RxErrNoResourceCnt++;
3634                        }
3635
3636                        if (pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD) {
3637                                pDevice->RxCounters.RxErrLargePacketCnt++;
3638                        }
3639                } else {
3640                        pPacket->PacketStatus = LM_STATUS_SUCCESS;
3641                        pPacket->PacketSize = pRcvBd->Len - 4;
3642
3643                        pPacket->Flags = pRcvBd->Flags;
3644                        if (pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG) {
3645                                pPacket->VlanTag = pRcvBd->VlanTag;
3646                        }
3647
3648                        pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
3649                }
3650
3651                /* Put the packet descriptor containing the received packet */
3652                /* buffer in the RxPacketReceivedQ for indication later. */
3653                QQ_PushTail (&pDevice->RxPacketReceivedQ.Container, pPacket);
3654
3655                /* Go to the next buffer descriptor. */
3656                SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
3657                    T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
3658
3659                /* Get the updated HwRcvRetProdIdx. */
3660                HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3661        }                       /* while */
3662
3663        pDevice->RcvRetConIdx = SwRcvRetConIdx;
3664
3665        /* Update the receive return ring consumer index. */
3666        MB_REG_WR (pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
3667}                               /* LM_ServiceRxInterrupt */
3668
3669/******************************************************************************/
3670/* Description:                                                               */
3671/*    This is the interrupt event handler routine. It acknowledges all        */
3672/*    pending interrupts and process all pending events.                      */
3673/*                                                                            */
3674/* Return:                                                                    */
3675/*    LM_STATUS_SUCCESS                                                       */
3676/******************************************************************************/
3677LM_STATUS LM_ServiceInterrupts (PLM_DEVICE_BLOCK pDevice)
3678{
3679        LM_UINT32 Value32;
3680        int ServicePhyInt = FALSE;
3681
3682        /* Setup the phy chip whenever the link status changes. */
3683        if (pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG) {
3684                Value32 = REG_RD (pDevice, MacCtrl.Status);
3685                if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
3686                        if (Value32 & MAC_STATUS_MI_INTERRUPT) {
3687                                ServicePhyInt = TRUE;
3688                        }
3689                } else if (Value32 & MAC_STATUS_LINK_STATE_CHANGED) {
3690                        ServicePhyInt = TRUE;
3691                }
3692        } else {
3693                if (pDevice->pStatusBlkVirt->
3694                    Status & STATUS_BLOCK_LINK_CHANGED_STATUS) {
3695                        pDevice->pStatusBlkVirt->Status =
3696                            STATUS_BLOCK_UPDATED | (pDevice->pStatusBlkVirt->
3697                                                    Status &
3698                                                    ~STATUS_BLOCK_LINK_CHANGED_STATUS);
3699                        ServicePhyInt = TRUE;
3700                }
3701        }
3702#if INCLUDE_TBI_SUPPORT
3703        if (pDevice->IgnoreTbiLinkChange == TRUE) {
3704                ServicePhyInt = FALSE;
3705        }
3706#endif
3707        if (ServicePhyInt == TRUE) {
3708                LM_SetupPhy (pDevice);
3709        }
3710
3711        /* Service receive and transmit interrupts. */
3712        LM_ServiceRxInterrupt (pDevice);
3713        LM_ServiceTxInterrupt (pDevice);
3714
3715        /* No spinlock for this queue since this routine is serialized. */
3716        if (!QQ_Empty (&pDevice->RxPacketReceivedQ.Container)) {
3717                /* Indicate receive packets. */
3718                MM_IndicateRxPackets (pDevice);
3719                /*       LM_QueueRxPackets(pDevice); */
3720        }
3721
3722        /* No spinlock for this queue since this routine is serialized. */
3723        if (!QQ_Empty (&pDevice->TxPacketXmittedQ.Container)) {
3724                MM_IndicateTxPackets (pDevice);
3725        }
3726
3727        return LM_STATUS_SUCCESS;
3728}                               /* LM_ServiceInterrupts */
3729
3730/******************************************************************************/
3731/* Description:                                                               */
3732/*                                                                            */
3733/* Return:                                                                    */
3734/******************************************************************************/
3735LM_STATUS LM_MulticastAdd (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
3736{
3737        PLM_UINT8 pEntry;
3738        LM_UINT32 j;
3739
3740        pEntry = pDevice->McTable[0];
3741        for (j = 0; j < pDevice->McEntryCount; j++) {
3742                if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
3743                        /* Found a match, increment the instance count. */
3744                        pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
3745
3746                        return LM_STATUS_SUCCESS;
3747                }
3748
3749                pEntry += LM_MC_ENTRY_SIZE;
3750        }
3751
3752        if (pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE) {
3753                return LM_STATUS_FAILURE;
3754        }
3755
3756        pEntry = pDevice->McTable[pDevice->McEntryCount];
3757
3758        COPY_ETH_ADDRESS (pMcAddress, pEntry);
3759        pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
3760
3761        pDevice->McEntryCount++;
3762
3763        LM_SetReceiveMask (pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
3764
3765        return LM_STATUS_SUCCESS;
3766}                               /* LM_MulticastAdd */
3767
3768/******************************************************************************/
3769/* Description:                                                               */
3770/*                                                                            */
3771/* Return:                                                                    */
3772/******************************************************************************/
3773LM_STATUS LM_MulticastDel (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pMcAddress)
3774{
3775        PLM_UINT8 pEntry;
3776        LM_UINT32 j;
3777
3778        pEntry = pDevice->McTable[0];
3779        for (j = 0; j < pDevice->McEntryCount; j++) {
3780                if (IS_ETH_ADDRESS_EQUAL (pEntry, pMcAddress)) {
3781                        /* Found a match, decrement the instance count. */
3782                        pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
3783
3784                        /* No more instance left, remove the address from the table. */
3785                        /* Move the last entry in the table to the delete slot. */
3786                        if (pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
3787                            pDevice->McEntryCount > 1) {
3788
3789                                COPY_ETH_ADDRESS (pDevice->
3790                                                  McTable[pDevice->
3791                                                          McEntryCount - 1],
3792                                                  pEntry);
3793                                pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
3794                                    pDevice->McTable[pDevice->McEntryCount - 1]
3795                                    [LM_MC_INSTANCE_COUNT_INDEX];
3796                        }
3797                        pDevice->McEntryCount--;
3798
3799                        /* Update the receive mask if the table is empty. */
3800                        if (pDevice->McEntryCount == 0) {
3801                                LM_SetReceiveMask (pDevice,
3802                                                   pDevice->
3803                                                   ReceiveMask &
3804                                                   ~LM_ACCEPT_MULTICAST);
3805                        }
3806
3807                        return LM_STATUS_SUCCESS;
3808                }
3809
3810                pEntry += LM_MC_ENTRY_SIZE;
3811        }
3812
3813        return LM_STATUS_FAILURE;
3814}                               /* LM_MulticastDel */
3815
3816/******************************************************************************/
3817/* Description:                                                               */
3818/*                                                                            */
3819/* Return:                                                                    */
3820/******************************************************************************/
3821LM_STATUS LM_MulticastClear (PLM_DEVICE_BLOCK pDevice)
3822{
3823        pDevice->McEntryCount = 0;
3824
3825        LM_SetReceiveMask (pDevice,
3826                           pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
3827
3828        return LM_STATUS_SUCCESS;
3829}                               /* LM_MulticastClear */
3830
3831/******************************************************************************/
3832/* Description:                                                               */
3833/*                                                                            */
3834/* Return:                                                                    */
3835/******************************************************************************/
3836LM_STATUS LM_SetMacAddress (PLM_DEVICE_BLOCK pDevice)
3837{
3838        LM_UINT32 j;
3839        PLM_UINT8 pMacAddress = pDevice->NodeAddress;
3840
3841        for (j = 0; j < 4; j++) {
3842                REG_WR (pDevice, MacCtrl.MacAddr[j].High,
3843                        (pMacAddress[0] << 8) | pMacAddress[1]);
3844                REG_WR (pDevice, MacCtrl.MacAddr[j].Low,
3845                        (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
3846                        (pMacAddress[4] << 8) | pMacAddress[5]);
3847        }
3848
3849        return LM_STATUS_SUCCESS;
3850}
3851
3852/******************************************************************************/
3853/* Description:                                                               */
3854/*    Sets up the default line speed, and duplex modes based on the requested */
3855/*    media type.                                                             */
3856/*                                                                            */
3857/* Return:                                                                    */
3858/*    None.                                                                   */
3859/******************************************************************************/
3860static LM_STATUS
3861LM_TranslateRequestedMediaType (LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
3862                                PLM_MEDIA_TYPE pMediaType,
3863                                PLM_LINE_SPEED pLineSpeed,
3864                                PLM_DUPLEX_MODE pDuplexMode)
3865{
3866        *pMediaType = LM_MEDIA_TYPE_AUTO;
3867        *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
3868        *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
3869
3870        /* determine media type */
3871        switch (RequestedMediaType) {
3872        case LM_REQUESTED_MEDIA_TYPE_BNC:
3873                *pMediaType = LM_MEDIA_TYPE_BNC;
3874                *pLineSpeed = LM_LINE_SPEED_10MBPS;
3875                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3876                break;
3877
3878        case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
3879                *pMediaType = LM_MEDIA_TYPE_UTP;
3880                break;
3881
3882        case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
3883                *pMediaType = LM_MEDIA_TYPE_UTP;
3884                *pLineSpeed = LM_LINE_SPEED_10MBPS;
3885                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3886                break;
3887
3888        case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
3889                *pMediaType = LM_MEDIA_TYPE_UTP;
3890                *pLineSpeed = LM_LINE_SPEED_10MBPS;
3891                *pDuplexMode = LM_DUPLEX_MODE_FULL;
3892                break;
3893
3894        case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
3895                *pMediaType = LM_MEDIA_TYPE_UTP;
3896                *pLineSpeed = LM_LINE_SPEED_100MBPS;
3897                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3898                break;
3899
3900        case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
3901                *pMediaType = LM_MEDIA_TYPE_UTP;
3902                *pLineSpeed = LM_LINE_SPEED_100MBPS;
3903                *pDuplexMode = LM_DUPLEX_MODE_FULL;
3904                break;
3905
3906        case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
3907                *pMediaType = LM_MEDIA_TYPE_UTP;
3908                *pLineSpeed = LM_LINE_SPEED_1000MBPS;
3909                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3910                break;
3911
3912        case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
3913                *pMediaType = LM_MEDIA_TYPE_UTP;
3914                *pLineSpeed = LM_LINE_SPEED_1000MBPS;
3915                *pDuplexMode = LM_DUPLEX_MODE_FULL;
3916                break;
3917
3918        case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
3919                *pMediaType = LM_MEDIA_TYPE_FIBER;
3920                *pLineSpeed = LM_LINE_SPEED_100MBPS;
3921                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3922                break;
3923
3924        case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
3925                *pMediaType = LM_MEDIA_TYPE_FIBER;
3926                *pLineSpeed = LM_LINE_SPEED_100MBPS;
3927                *pDuplexMode = LM_DUPLEX_MODE_FULL;
3928                break;
3929
3930        case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
3931                *pMediaType = LM_MEDIA_TYPE_FIBER;
3932                *pLineSpeed = LM_LINE_SPEED_1000MBPS;
3933                *pDuplexMode = LM_DUPLEX_MODE_HALF;
3934                break;
3935
3936        case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
3937                *pMediaType = LM_MEDIA_TYPE_FIBER;
3938                *pLineSpeed = LM_LINE_SPEED_1000MBPS;
3939                *pDuplexMode = LM_DUPLEX_MODE_FULL;
3940                break;
3941
3942        default:
3943                break;
3944        }                       /* switch */
3945
3946        return LM_STATUS_SUCCESS;
3947}                               /* LM_TranslateRequestedMediaType */
3948
3949/******************************************************************************/
3950/* Description:                                                               */
3951/*                                                                            */
3952/* Return:                                                                    */
3953/*    LM_STATUS_LINK_ACTIVE                                                   */
3954/*    LM_STATUS_LINK_DOWN                                                     */
3955/******************************************************************************/
3956static LM_STATUS LM_InitBcm540xPhy (PLM_DEVICE_BLOCK pDevice)
3957{
3958        LM_LINE_SPEED CurrentLineSpeed;
3959        LM_DUPLEX_MODE CurrentDuplexMode;
3960        LM_STATUS CurrentLinkStatus;
3961        LM_UINT32 Value32;
3962        LM_UINT32 j;
3963
3964#if 1                           /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
3965        LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x2);
3966#endif
3967        if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID) {
3968                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3969                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3970
3971                if (!pDevice->InitDone) {
3972                        Value32 = 0;
3973                }
3974
3975                if (!(Value32 & PHY_STATUS_LINK_PASS)) {
3976                        LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x0c20);
3977
3978                        LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
3979                        LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1804);
3980
3981                        LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
3982                        LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x1204);
3983
3984                        LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
3985                        LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0132);
3986
3987                        LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
3988                        LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0232);
3989
3990                        LM_WritePhy (pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
3991                        LM_WritePhy (pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
3992
3993                        LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3994                        for (j = 0; j < 1000; j++) {
3995                                MM_Wait (10);
3996
3997                                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
3998                                if (Value32 & PHY_STATUS_LINK_PASS) {
3999                                        MM_Wait (40);
4000                                        break;
4001                                }
4002                        }
4003
4004                        if ((pDevice->PhyId & PHY_ID_REV_MASK) ==
4005                            PHY_BCM5401_B0_REV) {
4006                                if (!(Value32 & PHY_STATUS_LINK_PASS)
4007                                    && (pDevice->OldLineSpeed ==
4008                                        LM_LINE_SPEED_1000MBPS)) {
4009                                        LM_WritePhy (pDevice, PHY_CTRL_REG,
4010                                                     PHY_CTRL_PHY_RESET);
4011                                        for (j = 0; j < 100; j++) {
4012                                                MM_Wait (10);
4013
4014                                                LM_ReadPhy (pDevice,
4015                                                            PHY_CTRL_REG,
4016                                                            &Value32);
4017                                                if (!
4018                                                    (Value32 &
4019                                                     PHY_CTRL_PHY_RESET)) {
4020                                                        MM_Wait (40);
4021                                                        break;
4022                                                }
4023                                        }
4024
4025                                        LM_WritePhy (pDevice, BCM5401_AUX_CTRL,
4026                                                     0x0c20);
4027
4028                                        LM_WritePhy (pDevice,
4029                                                     BCM540X_DSP_ADDRESS_REG,
4030                                                     0x0012);
4031                                        LM_WritePhy (pDevice,
4032                                                     BCM540X_DSP_RW_PORT,
4033                                                     0x1804);
4034
4035                                        LM_WritePhy (pDevice,
4036                                                     BCM540X_DSP_ADDRESS_REG,
4037                                                     0x0013);
4038                                        LM_WritePhy (pDevice,
4039                                                     BCM540X_DSP_RW_PORT,
4040                                                     0x1204);
4041
4042                                        LM_WritePhy (pDevice,
4043                                                     BCM540X_DSP_ADDRESS_REG,
4044                                                     0x8006);
4045                                        LM_WritePhy (pDevice,
4046                                                     BCM540X_DSP_RW_PORT,
4047                                                     0x0132);
4048
4049                                        LM_WritePhy (pDevice,
4050                                                     BCM540X_DSP_ADDRESS_REG,
4051                                                     0x8006);
4052                                        LM_WritePhy (pDevice,
4053                                                     BCM540X_DSP_RW_PORT,
4054                                                     0x0232);
4055
4056                                        LM_WritePhy (pDevice,
4057                                                     BCM540X_DSP_ADDRESS_REG,
4058                                                     0x201f);
4059                                        LM_WritePhy (pDevice,
4060                                                     BCM540X_DSP_RW_PORT,
4061                                                     0x0a20);
4062                                }
4063                        }
4064                }
4065        } else if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
4066                   pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
4067                /* Bug: 5701 A0, B0 TX CRC workaround. */
4068                LM_WritePhy (pDevice, 0x15, 0x0a75);
4069                LM_WritePhy (pDevice, 0x1c, 0x8c68);
4070                LM_WritePhy (pDevice, 0x1c, 0x8d68);
4071                LM_WritePhy (pDevice, 0x1c, 0x8c68);
4072        }
4073
4074        /* Acknowledge interrupts. */
4075        LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
4076        LM_ReadPhy (pDevice, BCM540X_INT_STATUS_REG, &Value32);
4077
4078        /* Configure the interrupt mask. */
4079        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
4080                LM_WritePhy (pDevice, BCM540X_INT_MASK_REG,
4081                             ~BCM540X_INT_LINK_CHANGE);
4082        }
4083
4084        /* Configure PHY led mode. */
4085        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
4086            (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700)) {
4087                if (pDevice->LedMode == LED_MODE_THREE_LINK) {
4088                        LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG,
4089                                     BCM540X_EXT_CTRL_LINK3_LED_MODE);
4090                } else {
4091                        LM_WritePhy (pDevice, BCM540X_EXT_CTRL_REG, 0);
4092                }
4093        }
4094
4095        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4096
4097        /* Get current link and duplex mode. */
4098        for (j = 0; j < 100; j++) {
4099                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4100                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4101
4102                if (Value32 & PHY_STATUS_LINK_PASS) {
4103                        break;
4104                }
4105                MM_Wait (40);
4106        }
4107
4108        if (Value32 & PHY_STATUS_LINK_PASS) {
4109
4110                /* Determine the current line and duplex settings. */
4111                LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4112                for (j = 0; j < 2000; j++) {
4113                        MM_Wait (10);
4114
4115                        LM_ReadPhy (pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4116                        if (Value32) {
4117                                break;
4118                        }
4119                }
4120
4121                switch (Value32 & BCM540X_AUX_SPEED_MASK) {
4122                case BCM540X_AUX_10BASET_HD:
4123                        CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4124                        CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4125                        break;
4126
4127                case BCM540X_AUX_10BASET_FD:
4128                        CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4129                        CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4130                        break;
4131
4132                case BCM540X_AUX_100BASETX_HD:
4133                        CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4134                        CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4135                        break;
4136
4137                case BCM540X_AUX_100BASETX_FD:
4138                        CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4139                        CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4140                        break;
4141
4142                case BCM540X_AUX_100BASET_HD:
4143                        CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4144                        CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4145                        break;
4146
4147                case BCM540X_AUX_100BASET_FD:
4148                        CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4149                        CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4150                        break;
4151
4152                default:
4153
4154                        CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
4155                        CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4156                        break;
4157                }
4158
4159                /* Make sure we are in auto-neg mode. */
4160                for (j = 0; j < 200; j++) {
4161                        LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
4162                        if (Value32 && Value32 != 0x7fff) {
4163                                break;
4164                        }
4165
4166                        if (Value32 == 0 && pDevice->RequestedMediaType ==
4167                            LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS) {
4168                                break;
4169                        }
4170
4171                        MM_Wait (10);
4172                }
4173
4174                /* Use the current line settings for "auto" mode. */
4175                if (pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO
4176                    || pDevice->RequestedMediaType ==
4177                    LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
4178                        if (Value32 & PHY_CTRL_AUTO_NEG_ENABLE) {
4179                                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4180
4181                                /* We may be exiting low power mode and the link is in */
4182                                /* 10mb.  In this case, we need to restart autoneg. */
4183                                LM_ReadPhy (pDevice, BCM540X_1000BASET_CTRL_REG,
4184                                            &Value32);
4185                                pDevice->advertising1000 = Value32;
4186                                /* 5702FE supports 10/100Mb only. */
4187                                if (T3_ASIC_REV (pDevice->ChipRevId) !=
4188                                    T3_ASIC_REV_5703
4189                                    || pDevice->BondId !=
4190                                    GRC_MISC_BD_ID_5702FE) {
4191                                        if (!
4192                                            (Value32 &
4193                                             (BCM540X_AN_AD_1000BASET_HALF |
4194                                              BCM540X_AN_AD_1000BASET_FULL))) {
4195                                                CurrentLinkStatus =
4196                                                    LM_STATUS_LINK_SETTING_MISMATCH;
4197                                        }
4198                                }
4199                        } else {
4200                                CurrentLinkStatus =
4201                                    LM_STATUS_LINK_SETTING_MISMATCH;
4202                        }
4203                } else {
4204                        /* Force line settings. */
4205                        /* Use the current setting if it matches the user's requested */
4206                        /* setting. */
4207                        LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
4208                        if ((pDevice->LineSpeed == CurrentLineSpeed) &&
4209                            (pDevice->DuplexMode == CurrentDuplexMode)) {
4210                                if ((pDevice->DisableAutoNeg &&
4211                                     !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
4212                                    (!pDevice->DisableAutoNeg &&
4213                                     (Value32 & PHY_CTRL_AUTO_NEG_ENABLE))) {
4214                                        CurrentLinkStatus =
4215                                            LM_STATUS_LINK_ACTIVE;
4216                                } else {
4217                                        CurrentLinkStatus =
4218                                            LM_STATUS_LINK_SETTING_MISMATCH;
4219                                }
4220                        } else {
4221                                CurrentLinkStatus =
4222                                    LM_STATUS_LINK_SETTING_MISMATCH;
4223                        }
4224                }
4225
4226                /* Save line settings. */
4227                pDevice->LineSpeed = CurrentLineSpeed;
4228                pDevice->DuplexMode = CurrentDuplexMode;
4229                pDevice->MediaType = LM_MEDIA_TYPE_UTP;
4230        }
4231
4232        return CurrentLinkStatus;
4233}                               /* LM_InitBcm540xPhy */
4234
4235/******************************************************************************/
4236/* Description:                                                               */
4237/*                                                                            */
4238/* Return:                                                                    */
4239/******************************************************************************/
4240LM_STATUS
4241LM_SetFlowControl (PLM_DEVICE_BLOCK pDevice,
4242                   LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd)
4243{
4244        LM_FLOW_CONTROL FlowCap;
4245
4246        /* Resolve flow control. */
4247        FlowCap = LM_FLOW_CONTROL_NONE;
4248
4249        /* See Table 28B-3 of 802.3ab-1999 spec. */
4250        if (pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE) {
4251                if (LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE) {
4252                        if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
4253                                if (RemotePhyAd &
4254                                    PHY_LINK_PARTNER_PAUSE_CAPABLE) {
4255                                        FlowCap =
4256                                            LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4257                                            LM_FLOW_CONTROL_RECEIVE_PAUSE;
4258                                } else if (RemotePhyAd &
4259                                           PHY_LINK_PARTNER_ASYM_PAUSE) {
4260                                        FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
4261                                }
4262                        } else {
4263                                if (RemotePhyAd &
4264                                    PHY_LINK_PARTNER_PAUSE_CAPABLE) {
4265                                        FlowCap =
4266                                            LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4267                                            LM_FLOW_CONTROL_RECEIVE_PAUSE;
4268                                }
4269                        }
4270                } else if (LocalPhyAd & PHY_AN_AD_ASYM_PAUSE) {
4271                        if ((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
4272                            (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)) {
4273                                FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4274                        }
4275                }
4276        } else {
4277                FlowCap = pDevice->FlowControlCap;
4278        }
4279
4280        /* Enable/disable rx PAUSE. */
4281        pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
4282        if (FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
4283            (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4284             pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)) {
4285                pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
4286                pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
4287
4288        }
4289        REG_WR (pDevice, MacCtrl.RxMode, pDevice->RxMode);
4290
4291        /* Enable/disable tx PAUSE. */
4292        pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
4293        if (FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
4294            (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4295             pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
4296                pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4297                pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
4298
4299        }
4300        REG_WR (pDevice, MacCtrl.TxMode, pDevice->TxMode);
4301
4302        return LM_STATUS_SUCCESS;
4303}
4304
4305#if INCLUDE_TBI_SUPPORT
4306/******************************************************************************/
4307/* Description:                                                               */
4308/*                                                                            */
4309/* Return:                                                                    */
4310/******************************************************************************/
4311STATIC LM_STATUS LM_InitBcm800xPhy (PLM_DEVICE_BLOCK pDevice)
4312{
4313        LM_UINT32 Value32;
4314        LM_UINT32 j;
4315
4316        Value32 = REG_RD (pDevice, MacCtrl.Status);
4317
4318        /* Reset the SERDES during init and when we have link. */
4319        if (!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED) {
4320                /* Set PLL lock range. */
4321                LM_WritePhy (pDevice, 0x16, 0x8007);
4322
4323                /* Software reset. */
4324                LM_WritePhy (pDevice, 0x00, 0x8000);
4325
4326                /* Wait for reset to complete. */
4327                for (j = 0; j < 500; j++) {
4328                        MM_Wait (10);
4329                }
4330
4331                /* Config mode; seletct PMA/Ch 1 regs. */
4332                LM_WritePhy (pDevice, 0x10, 0x8411);
4333
4334                /* Enable auto-lock and comdet, select txclk for tx. */
4335                LM_WritePhy (pDevice, 0x11, 0x0a10);
4336
4337                LM_WritePhy (pDevice, 0x18, 0x00a0);
4338                LM_WritePhy (pDevice, 0x16, 0x41ff);
4339
4340                /* Assert and deassert POR. */
4341                LM_WritePhy (pDevice, 0x13, 0x0400);
4342                MM_Wait (40);
4343                LM_WritePhy (pDevice, 0x13, 0x0000);
4344
4345                LM_WritePhy (pDevice, 0x11, 0x0a50);
4346                MM_Wait (40);
4347                LM_WritePhy (pDevice, 0x11, 0x0a10);
4348
4349                /* Delay for signal to stabilize. */
4350                for (j = 0; j < 15000; j++) {
4351                        MM_Wait (10);
4352                }
4353
4354                /* Deselect the channel register so we can read the PHY id later. */
4355                LM_WritePhy (pDevice, 0x10, 0x8011);
4356        }
4357
4358        return LM_STATUS_SUCCESS;
4359}
4360
4361/******************************************************************************/
4362/* Description:                                                               */
4363/*                                                                            */
4364/* Return:                                                                    */
4365/******************************************************************************/
4366STATIC LM_STATUS LM_SetupFiberPhy (PLM_DEVICE_BLOCK pDevice)
4367{
4368        LM_STATUS CurrentLinkStatus;
4369        AUTONEG_STATUS AnStatus = 0;
4370        LM_UINT32 Value32;
4371        LM_UINT32 Cnt;
4372        LM_UINT32 j, k;
4373
4374        pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
4375
4376        /* Initialize the send_config register. */
4377        REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
4378
4379        /* Enable TBI and full duplex mode. */
4380        pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
4381        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4382
4383        /* Initialize the BCM8002 SERDES PHY. */
4384        switch (pDevice->PhyId & PHY_ID_MASK) {
4385        case PHY_BCM8002_PHY_ID:
4386                LM_InitBcm800xPhy (pDevice);
4387                break;
4388
4389        default:
4390                break;
4391        }
4392
4393        /* Enable link change interrupt. */
4394        REG_WR (pDevice, MacCtrl.MacEvent,
4395                MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4396
4397        /* Default to link down. */
4398        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4399
4400        /* Get the link status. */
4401        Value32 = REG_RD (pDevice, MacCtrl.Status);
4402        if (Value32 & MAC_STATUS_PCS_SYNCED) {
4403                if ((pDevice->RequestedMediaType ==
4404                     LM_REQUESTED_MEDIA_TYPE_AUTO)
4405                    || (pDevice->DisableAutoNeg == FALSE)) {
4406                        /* auto-negotiation mode. */
4407                        /* Initialize the autoneg default capaiblities. */
4408                        AutonegInit (&pDevice->AnInfo);
4409
4410                        /* Set the context pointer to point to the main device structure. */
4411                        pDevice->AnInfo.pContext = pDevice;
4412
4413                        /* Setup flow control advertisement register. */
4414                        Value32 = GetPhyAdFlowCntrlSettings (pDevice);
4415                        if (Value32 & PHY_AN_AD_PAUSE_CAPABLE) {
4416                                pDevice->AnInfo.mr_adv_sym_pause = 1;
4417                        } else {
4418                                pDevice->AnInfo.mr_adv_sym_pause = 0;
4419                        }
4420
4421                        if (Value32 & PHY_AN_AD_ASYM_PAUSE) {
4422                                pDevice->AnInfo.mr_adv_asym_pause = 1;
4423                        } else {
4424                                pDevice->AnInfo.mr_adv_asym_pause = 0;
4425                        }
4426
4427                        /* Try to autoneg up to six times. */
4428                        if (pDevice->IgnoreTbiLinkChange) {
4429                                Cnt = 1;
4430                        } else {
4431                                Cnt = 6;
4432                        }
4433                        for (j = 0; j < Cnt; j++) {
4434                                REG_WR (pDevice, MacCtrl.TxAutoNeg, 0);
4435
4436                                Value32 =
4437                                    pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
4438                                REG_WR (pDevice, MacCtrl.Mode, Value32);
4439                                MM_Wait (20);
4440
4441                                REG_WR (pDevice, MacCtrl.Mode,
4442                                        pDevice->
4443                                        MacMode | MAC_MODE_SEND_CONFIGS);
4444
4445                                MM_Wait (20);
4446
4447                                pDevice->AnInfo.State = AN_STATE_UNKNOWN;
4448                                pDevice->AnInfo.CurrentTime_us = 0;
4449
4450                                REG_WR (pDevice, Grc.Timer, 0);
4451                                for (k = 0;
4452                                     (pDevice->AnInfo.CurrentTime_us < 75000)
4453                                     && (k < 75000); k++) {
4454                                        AnStatus =
4455                                            Autoneg8023z (&pDevice->AnInfo);
4456
4457                                        if ((AnStatus == AUTONEG_STATUS_DONE) ||
4458                                            (AnStatus == AUTONEG_STATUS_FAILED))
4459                                        {
4460                                                break;
4461                                        }
4462
4463                                        pDevice->AnInfo.CurrentTime_us =
4464                                            REG_RD (pDevice, Grc.Timer);
4465
4466                                }
4467                                if ((AnStatus == AUTONEG_STATUS_DONE) ||
4468                                    (AnStatus == AUTONEG_STATUS_FAILED)) {
4469                                        break;
4470                                }
4471                                if (j >= 1) {
4472                                        if (!(REG_RD (pDevice, MacCtrl.Status) &
4473                                              MAC_STATUS_PCS_SYNCED)) {
4474                                                break;
4475                                        }
4476                                }
4477                        }
4478
4479                        /* Stop sending configs. */
4480                        MM_AnTxIdle (&pDevice->AnInfo);
4481
4482                        /* Resolve flow control settings. */
4483                        if ((AnStatus == AUTONEG_STATUS_DONE) &&
4484                            pDevice->AnInfo.mr_an_complete
4485                            && pDevice->AnInfo.mr_link_ok
4486                            && pDevice->AnInfo.mr_lp_adv_full_duplex) {
4487                                LM_UINT32 RemotePhyAd;
4488                                LM_UINT32 LocalPhyAd;
4489
4490                                LocalPhyAd = 0;
4491                                if (pDevice->AnInfo.mr_adv_sym_pause) {
4492                                        LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
4493                                }
4494
4495                                if (pDevice->AnInfo.mr_adv_asym_pause) {
4496                                        LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
4497                                }
4498
4499                                RemotePhyAd = 0;
4500                                if (pDevice->AnInfo.mr_lp_adv_sym_pause) {
4501                                        RemotePhyAd |=
4502                                            PHY_LINK_PARTNER_PAUSE_CAPABLE;
4503                                }
4504
4505                                if (pDevice->AnInfo.mr_lp_adv_asym_pause) {
4506                                        RemotePhyAd |=
4507                                            PHY_LINK_PARTNER_ASYM_PAUSE;
4508                                }
4509
4510                                LM_SetFlowControl (pDevice, LocalPhyAd,
4511                                                   RemotePhyAd);
4512
4513                                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4514                        }
4515                        for (j = 0; j < 30; j++) {
4516                                MM_Wait (20);
4517                                REG_WR (pDevice, MacCtrl.Status,
4518                                        MAC_STATUS_SYNC_CHANGED |
4519                                        MAC_STATUS_CFG_CHANGED);
4520                                MM_Wait (20);
4521                                if ((REG_RD (pDevice, MacCtrl.Status) &
4522                                     (MAC_STATUS_SYNC_CHANGED |
4523                                      MAC_STATUS_CFG_CHANGED)) == 0)
4524                                        break;
4525                        }
4526                        if (pDevice->PollTbiLink) {
4527                                Value32 = REG_RD (pDevice, MacCtrl.Status);
4528                                if (Value32 & MAC_STATUS_RECEIVING_CFG) {
4529                                        pDevice->IgnoreTbiLinkChange = TRUE;
4530                                } else {
4531                                        pDevice->IgnoreTbiLinkChange = FALSE;
4532                                }
4533                        }
4534                        Value32 = REG_RD (pDevice, MacCtrl.Status);
4535                        if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
4536                            (Value32 & MAC_STATUS_PCS_SYNCED) &&
4537                            ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0)) {
4538                                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4539                        }
4540                } else {
4541                        /* We are forcing line speed. */
4542                        pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
4543                        LM_SetFlowControl (pDevice, 0, 0);
4544
4545                        CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4546                        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
4547                                MAC_MODE_SEND_CONFIGS);
4548                }
4549        }
4550        /* Set the link polarity bit. */
4551        pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4552        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4553
4554        pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4555            (pDevice->pStatusBlkVirt->
4556             Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4557
4558        for (j = 0; j < 100; j++) {
4559                REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4560                        MAC_STATUS_CFG_CHANGED);
4561                MM_Wait (5);
4562                if ((REG_RD (pDevice, MacCtrl.Status) &
4563                     (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4564                        break;
4565        }
4566
4567        Value32 = REG_RD (pDevice, MacCtrl.Status);
4568        if ((Value32 & MAC_STATUS_PCS_SYNCED) == 0) {
4569                CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4570                if (pDevice->DisableAutoNeg == FALSE) {
4571                        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode |
4572                                MAC_MODE_SEND_CONFIGS);
4573                        MM_Wait (1);
4574                        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4575                }
4576        }
4577
4578        /* Initialize the current link status. */
4579        if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4580                pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
4581                pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
4582                REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4583                        LED_CTRL_1000MBPS_LED_ON);
4584        } else {
4585                pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
4586                pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4587                REG_WR (pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4588                        LED_CTRL_OVERRIDE_TRAFFIC_LED);
4589        }
4590
4591        /* Indicate link status. */
4592        if (pDevice->LinkStatus != CurrentLinkStatus) {
4593                pDevice->LinkStatus = CurrentLinkStatus;
4594                MM_IndicateStatus (pDevice, CurrentLinkStatus);
4595        }
4596
4597        return LM_STATUS_SUCCESS;
4598}
4599#endif                          /* INCLUDE_TBI_SUPPORT */
4600
4601/******************************************************************************/
4602/* Description:                                                               */
4603/*                                                                            */
4604/* Return:                                                                    */
4605/******************************************************************************/
4606LM_STATUS LM_SetupCopperPhy (PLM_DEVICE_BLOCK pDevice)
4607{
4608        LM_STATUS CurrentLinkStatus;
4609        LM_UINT32 Value32;
4610
4611        /* Assume there is not link first. */
4612        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4613
4614        /* Disable phy link change attention. */
4615        REG_WR (pDevice, MacCtrl.MacEvent, 0);
4616
4617        /* Clear link change attention. */
4618        REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4619                MAC_STATUS_CFG_CHANGED);
4620
4621        /* Disable auto-polling for the moment. */
4622        pDevice->MiMode = 0xc0000;
4623        REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4624        MM_Wait (40);
4625
4626        /* Determine the requested line speed and duplex. */
4627        pDevice->OldLineSpeed = pDevice->LineSpeed;
4628        LM_TranslateRequestedMediaType (pDevice->RequestedMediaType,
4629                                        &pDevice->MediaType,
4630                                        &pDevice->LineSpeed,
4631                                        &pDevice->DuplexMode);
4632
4633        /* Initialize the phy chip. */
4634        switch (pDevice->PhyId & PHY_ID_MASK) {
4635        case PHY_BCM5400_PHY_ID:
4636        case PHY_BCM5401_PHY_ID:
4637        case PHY_BCM5411_PHY_ID:
4638        case PHY_BCM5701_PHY_ID:
4639        case PHY_BCM5703_PHY_ID:
4640        case PHY_BCM5704_PHY_ID:
4641                CurrentLinkStatus = LM_InitBcm540xPhy (pDevice);
4642                break;
4643
4644        default:
4645                break;
4646        }
4647
4648        if (CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH) {
4649                CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4650        }
4651
4652        /* Setup flow control. */
4653        pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
4654        if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4655                LM_FLOW_CONTROL FlowCap;        /* Flow control capability. */
4656
4657                FlowCap = LM_FLOW_CONTROL_NONE;
4658
4659                if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) {
4660                        if (pDevice->DisableAutoNeg == FALSE ||
4661                            pDevice->RequestedMediaType ==
4662                            LM_REQUESTED_MEDIA_TYPE_AUTO
4663                            || pDevice->RequestedMediaType ==
4664                            LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
4665                                LM_UINT32 ExpectedPhyAd;
4666                                LM_UINT32 LocalPhyAd;
4667                                LM_UINT32 RemotePhyAd;
4668
4669                                LM_ReadPhy (pDevice, PHY_AN_AD_REG,
4670                                            &LocalPhyAd);
4671                                pDevice->advertising = LocalPhyAd;
4672                                LocalPhyAd &=
4673                                    (PHY_AN_AD_ASYM_PAUSE |
4674                                     PHY_AN_AD_PAUSE_CAPABLE);
4675
4676                                ExpectedPhyAd =
4677                                    GetPhyAdFlowCntrlSettings (pDevice);
4678
4679                                if (LocalPhyAd != ExpectedPhyAd) {
4680                                        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4681                                } else {
4682                                        LM_ReadPhy (pDevice,
4683                                                    PHY_LINK_PARTNER_ABILITY_REG,
4684                                                    &RemotePhyAd);
4685
4686                                        LM_SetFlowControl (pDevice, LocalPhyAd,
4687                                                           RemotePhyAd);
4688                                }
4689                        } else {
4690                                pDevice->FlowControlCap &=
4691                                    ~LM_FLOW_CONTROL_AUTO_PAUSE;
4692                                LM_SetFlowControl (pDevice, 0, 0);
4693                        }
4694                }
4695        }
4696
4697        if (CurrentLinkStatus == LM_STATUS_LINK_DOWN) {
4698                LM_ForceAutoNeg (pDevice, pDevice->RequestedMediaType);
4699
4700                /* If we force line speed, we make get link right away. */
4701                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4702                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
4703                if (Value32 & PHY_STATUS_LINK_PASS) {
4704                        CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4705                }
4706        }
4707
4708        /* GMII interface. */
4709        pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
4710        if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4711                if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
4712                    pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) {
4713                        pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
4714                } else {
4715                        pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
4716                }
4717        } else {
4718                pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
4719        }
4720
4721        /* Set the MAC to operate in the appropriate duplex mode. */
4722        pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
4723        if (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF) {
4724                pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
4725        }
4726
4727        /* Set the link polarity bit. */
4728        pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4729        if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
4730                if ((pDevice->LedMode == LED_MODE_LINK10) ||
4731                    (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
4732                     pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)) {
4733                        pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
4734                }
4735        } else {
4736                if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) {
4737                        pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
4738                }
4739
4740                /* Set LED mode. */
4741                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
4742                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
4743                        Value32 = LED_CTRL_PHY_MODE_1;
4744                } else {
4745                        if (pDevice->LedMode == LED_MODE_OUTPUT) {
4746                                Value32 = LED_CTRL_PHY_MODE_2;
4747                        } else {
4748                                Value32 = LED_CTRL_PHY_MODE_1;
4749                        }
4750                }
4751                REG_WR (pDevice, MacCtrl.LedCtrl, Value32);
4752        }
4753
4754        REG_WR (pDevice, MacCtrl.Mode, pDevice->MacMode);
4755
4756        /* Enable auto polling. */
4757        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4758                pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
4759                REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4760        }
4761
4762        /* Enable phy link change attention. */
4763        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT) {
4764                REG_WR (pDevice, MacCtrl.MacEvent,
4765                        MAC_EVENT_ENABLE_MI_INTERRUPT);
4766        } else {
4767                REG_WR (pDevice, MacCtrl.MacEvent,
4768                        MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4769        }
4770        if ((T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
4771            (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
4772            (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
4773            (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
4774              (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
4775             !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))) {
4776                MM_Wait (120);
4777                REG_WR (pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4778                        MAC_STATUS_CFG_CHANGED);
4779                MEM_WR_OFFSET (pDevice, T3_FIRMWARE_MAILBOX,
4780                               T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
4781        }
4782
4783        /* Indicate link status. */
4784        if (pDevice->LinkStatus != CurrentLinkStatus) {
4785                pDevice->LinkStatus = CurrentLinkStatus;
4786                MM_IndicateStatus (pDevice, CurrentLinkStatus);
4787        }
4788
4789        return LM_STATUS_SUCCESS;
4790}                               /* LM_SetupCopperPhy */
4791
4792/******************************************************************************/
4793/* Description:                                                               */
4794/*                                                                            */
4795/* Return:                                                                    */
4796/******************************************************************************/
4797LM_STATUS LM_SetupPhy (PLM_DEVICE_BLOCK pDevice)
4798{
4799        LM_STATUS LmStatus;
4800        LM_UINT32 Value32;
4801
4802#if INCLUDE_TBI_SUPPORT
4803        if (pDevice->EnableTbi) {
4804                LmStatus = LM_SetupFiberPhy (pDevice);
4805        } else
4806#endif                          /* INCLUDE_TBI_SUPPORT */
4807        {
4808                LmStatus = LM_SetupCopperPhy (pDevice);
4809        }
4810        if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0) {
4811                if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)) {
4812                        Value32 = REG_RD (pDevice, PciCfg.PciState);
4813                        REG_WR (pDevice, PciCfg.PciState,
4814                                Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
4815                }
4816        }
4817        if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
4818            (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)) {
4819                REG_WR (pDevice, MacCtrl.TxLengths, 0x26ff);
4820        } else {
4821                REG_WR (pDevice, MacCtrl.TxLengths, 0x2620);
4822        }
4823
4824        return LmStatus;
4825}
4826
4827/******************************************************************************/
4828/* Description:                                                               */
4829/*                                                                            */
4830/* Return:                                                                    */
4831/******************************************************************************/
4832LM_VOID
4833LM_ReadPhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, PLM_UINT32 pData32)
4834{
4835        LM_UINT32 Value32;
4836        LM_UINT32 j;
4837
4838        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4839                REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
4840                        ~MI_MODE_AUTO_POLLING_ENABLE);
4841                MM_Wait (40);
4842        }
4843
4844        Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
4845            ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
4846             MI_COM_FIRST_PHY_REG_ADDR_BIT) | MI_COM_CMD_READ | MI_COM_START;
4847
4848        REG_WR (pDevice, MacCtrl.MiCom, Value32);
4849
4850        for (j = 0; j < 20; j++) {
4851                MM_Wait (25);
4852
4853                Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4854
4855                if (!(Value32 & MI_COM_BUSY)) {
4856                        MM_Wait (5);
4857                        Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4858                        Value32 &= MI_COM_PHY_DATA_MASK;
4859                        break;
4860                }
4861        }
4862
4863        if (Value32 & MI_COM_BUSY) {
4864                Value32 = 0;
4865        }
4866
4867        *pData32 = Value32;
4868
4869        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4870                REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4871                MM_Wait (40);
4872        }
4873}                               /* LM_ReadPhy */
4874
4875/******************************************************************************/
4876/* Description:                                                               */
4877/*                                                                            */
4878/* Return:                                                                    */
4879/******************************************************************************/
4880LM_VOID
4881LM_WritePhy (PLM_DEVICE_BLOCK pDevice, LM_UINT32 PhyReg, LM_UINT32 Data32)
4882{
4883        LM_UINT32 Value32;
4884        LM_UINT32 j;
4885
4886        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4887                REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode &
4888                        ~MI_MODE_AUTO_POLLING_ENABLE);
4889                MM_Wait (40);
4890        }
4891
4892        Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
4893            ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) <<
4894             MI_COM_FIRST_PHY_REG_ADDR_BIT) | (Data32 & MI_COM_PHY_DATA_MASK) |
4895            MI_COM_CMD_WRITE | MI_COM_START;
4896
4897        REG_WR (pDevice, MacCtrl.MiCom, Value32);
4898
4899        for (j = 0; j < 20; j++) {
4900                MM_Wait (25);
4901
4902                Value32 = REG_RD (pDevice, MacCtrl.MiCom);
4903
4904                if (!(Value32 & MI_COM_BUSY)) {
4905                        MM_Wait (5);
4906                        break;
4907                }
4908        }
4909
4910        if (pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING) {
4911                REG_WR (pDevice, MacCtrl.MiMode, pDevice->MiMode);
4912                MM_Wait (40);
4913        }
4914}                               /* LM_WritePhy */
4915
4916/******************************************************************************/
4917/* Description:                                                               */
4918/*                                                                            */
4919/* Return:                                                                    */
4920/******************************************************************************/
4921LM_STATUS LM_SetPowerState (PLM_DEVICE_BLOCK pDevice, LM_POWER_STATE PowerLevel)
4922{
4923        LM_UINT32 PmeSupport;
4924        LM_UINT32 Value32;
4925        LM_UINT32 PmCtrl;
4926
4927        /* make sureindirect accesses are enabled */
4928        MM_WriteConfig32 (pDevice, T3_PCI_MISC_HOST_CTRL_REG,
4929                          pDevice->MiscHostCtrl);
4930
4931        /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
4932        /* the PME bit. */
4933        MM_ReadConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
4934
4935        PmCtrl |= T3_PM_PME_ASSERTED;
4936        PmCtrl &= ~T3_PM_POWER_STATE_MASK;
4937
4938        /* Set the appropriate power state. */
4939        if (PowerLevel == LM_POWER_STATE_D0) {
4940
4941                /* Bring the card out of low power mode. */
4942                PmCtrl |= T3_PM_POWER_STATE_D0;
4943                MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
4944
4945                REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
4946                MM_Wait (40);
4947#if 0                           /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
4948                LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x02);
4949#endif
4950
4951                return LM_STATUS_SUCCESS;
4952        } else if (PowerLevel == LM_POWER_STATE_D1) {
4953                PmCtrl |= T3_PM_POWER_STATE_D1;
4954        } else if (PowerLevel == LM_POWER_STATE_D2) {
4955                PmCtrl |= T3_PM_POWER_STATE_D2;
4956        } else if (PowerLevel == LM_POWER_STATE_D3) {
4957                PmCtrl |= T3_PM_POWER_STATE_D3;
4958        } else {
4959                return LM_STATUS_FAILURE;
4960        }
4961        PmCtrl |= T3_PM_PME_ENABLE;
4962
4963        /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
4964        /* setting new line speed. */
4965        Value32 = REG_RD (pDevice, PciCfg.MiscHostCtrl);
4966        REG_WR (pDevice, PciCfg.MiscHostCtrl,
4967                Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
4968
4969        if (!pDevice->RestoreOnWakeUp) {
4970                pDevice->RestoreOnWakeUp = TRUE;
4971                pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
4972                pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
4973        }
4974
4975        /* Force auto-negotiation to 10 line speed. */
4976        pDevice->DisableAutoNeg = FALSE;
4977        pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
4978        LM_SetupPhy (pDevice);
4979
4980        /* Put the driver in the initial state, and go through the power down */
4981        /* sequence. */
4982        LM_Halt (pDevice);
4983
4984        MM_ReadConfig32 (pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
4985
4986        if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) {
4987
4988                /* Enable WOL. */
4989                LM_WritePhy (pDevice, BCM5401_AUX_CTRL, 0x5a);
4990                MM_Wait (40);
4991
4992                /* Set LED mode. */
4993                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
4994                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
4995                        Value32 = LED_CTRL_PHY_MODE_1;
4996                } else {
4997                        if (pDevice->LedMode == LED_MODE_OUTPUT) {
4998                                Value32 = LED_CTRL_PHY_MODE_2;
4999                        } else {
5000                                Value32 = LED_CTRL_PHY_MODE_1;
5001                        }
5002                }
5003
5004                Value32 = MAC_MODE_PORT_MODE_MII;
5005                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700) {
5006                        if (pDevice->LedMode == LED_MODE_LINK10 ||
5007                            pDevice->WolSpeed == WOL_SPEED_10MB) {
5008                                Value32 |= MAC_MODE_LINK_POLARITY;
5009                        }
5010                } else {
5011                        Value32 |= MAC_MODE_LINK_POLARITY;
5012                }
5013                REG_WR (pDevice, MacCtrl.Mode, Value32);
5014                MM_Wait (40);
5015                MM_Wait (40);
5016                MM_Wait (40);
5017
5018                /* Always enable magic packet wake-up if we have vaux. */
5019                if ((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
5020                    (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET)) {
5021                        Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
5022                }
5023
5024                REG_WR (pDevice, MacCtrl.Mode, Value32);
5025
5026                /* Enable the receiver. */
5027                REG_WR (pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
5028        }
5029
5030        /* Disable tx/rx clocks, and seletect an alternate clock. */
5031        if (pDevice->WolSpeed == WOL_SPEED_100MB) {
5032                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5033                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5034                        Value32 =
5035                            T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5036                            T3_PCI_SELECT_ALTERNATE_CLOCK;
5037                } else {
5038                        Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
5039                }
5040                REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5041
5042                MM_Wait (40);
5043
5044                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5045                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5046                        Value32 =
5047                            T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5048                            T3_PCI_SELECT_ALTERNATE_CLOCK |
5049                            T3_PCI_44MHZ_CORE_CLOCK;
5050                } else {
5051                        Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5052                            T3_PCI_44MHZ_CORE_CLOCK;
5053                }
5054
5055                REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5056
5057                MM_Wait (40);
5058
5059                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5060                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5061                        Value32 =
5062                            T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5063                            T3_PCI_44MHZ_CORE_CLOCK;
5064                } else {
5065                        Value32 = T3_PCI_44MHZ_CORE_CLOCK;
5066                }
5067
5068                REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5069        } else {
5070                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5071                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5072                        Value32 =
5073                            T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5074                            T3_PCI_SELECT_ALTERNATE_CLOCK |
5075                            T3_PCI_POWER_DOWN_PCI_PLL133;
5076                } else {
5077                        Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5078                            T3_PCI_POWER_DOWN_PCI_PLL133;
5079                }
5080
5081                REG_WR (pDevice, PciCfg.ClockCtrl, Value32);
5082        }
5083
5084        MM_Wait (40);
5085
5086        if (!pDevice->EepromWp
5087            && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)) {
5088                /* Switch adapter to auxilliary power. */
5089                if (T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5090                    T3_ASIC_REV (pDevice->ChipRevId) == T3_ASIC_REV_5701) {
5091                        /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5092                        REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5093                                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5094                                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5095                                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5096                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5097                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5098                        MM_Wait (40);
5099                } else {
5100                        /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
5101                        REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5102                                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5103                                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5104                                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5105                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5106                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5107                        MM_Wait (40);
5108
5109                        /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
5110                        REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5111                                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5112                                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5113                                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5114                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5115                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5116                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5117                        MM_Wait (40);
5118
5119                        /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5120                        REG_WR (pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5121                                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5122                                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5123                                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5124                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5125                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5126                        MM_Wait (40);
5127                }
5128        }
5129
5130        /* Set the phy to low power mode. */
5131        /* Put the the hardware in low power mode. */
5132        MM_WriteConfig32 (pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5133
5134        return LM_STATUS_SUCCESS;
5135}                               /* LM_SetPowerState */
5136
5137/******************************************************************************/
5138/* Description:                                                               */
5139/*                                                                            */
5140/* Return:                                                                    */
5141/******************************************************************************/
5142static LM_UINT32 GetPhyAdFlowCntrlSettings (PLM_DEVICE_BLOCK pDevice)
5143{
5144        LM_UINT32 Value32;
5145
5146        Value32 = 0;
5147
5148        /* Auto negotiation flow control only when autonegotiation is enabled. */
5149        if (pDevice->DisableAutoNeg == FALSE ||
5150            pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5151            pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO) {
5152                /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
5153                if ((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
5154                    ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
5155                     && (pDevice->
5156                         FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))) {
5157                        Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
5158                } else if (pDevice->
5159                           FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
5160                        Value32 |= PHY_AN_AD_ASYM_PAUSE;
5161                } else if (pDevice->
5162                           FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) {
5163                        Value32 |=
5164                            PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
5165                }
5166        }
5167
5168        return Value32;
5169}
5170
5171/******************************************************************************/
5172/* Description:                                                               */
5173/*                                                                            */
5174/* Return:                                                                    */
5175/*    LM_STATUS_FAILURE                                                       */
5176/*    LM_STATUS_SUCCESS                                                       */
5177/*                                                                            */
5178/******************************************************************************/
5179static LM_STATUS
5180LM_ForceAutoNegBcm540xPhy (PLM_DEVICE_BLOCK pDevice,
5181                           LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5182{
5183        LM_MEDIA_TYPE MediaType;
5184        LM_LINE_SPEED LineSpeed;
5185        LM_DUPLEX_MODE DuplexMode;
5186        LM_UINT32 NewPhyCtrl;
5187        LM_UINT32 Value32;
5188        LM_UINT32 Cnt;
5189
5190        /* Get the interface type, line speed, and duplex mode. */
5191        LM_TranslateRequestedMediaType (RequestedMediaType, &MediaType,
5192                                        &LineSpeed, &DuplexMode);
5193
5194        if (pDevice->RestoreOnWakeUp) {
5195                LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5196                pDevice->advertising1000 = 0;
5197                Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
5198                if (pDevice->WolSpeed == WOL_SPEED_100MB) {
5199                        Value32 |=
5200                            PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5201                }
5202                Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5203                Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5204                LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5205                pDevice->advertising = Value32;
5206        }
5207        /* Setup the auto-negotiation advertisement register. */
5208        else if (LineSpeed == LM_LINE_SPEED_UNKNOWN) {
5209                /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
5210                Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
5211                    PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
5212                    PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5213                Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5214
5215                LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5216                pDevice->advertising = Value32;
5217
5218                /* Advertise 1000Mbps */
5219                Value32 =
5220                    BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
5221
5222#if INCLUDE_5701_AX_FIX
5223                /* Bug: workaround for CRC error in gigabit mode when we are in */
5224                /* slave mode.  This will force the PHY to operate in */
5225                /* master mode. */
5226                if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5227                    pDevice->ChipRevId == T3_CHIP_ID_5701_B0) {
5228                        Value32 |= BCM540X_CONFIG_AS_MASTER |
5229                            BCM540X_ENABLE_CONFIG_AS_MASTER;
5230                }
5231#endif
5232
5233                LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5234                pDevice->advertising1000 = Value32;
5235        } else {
5236                if (LineSpeed == LM_LINE_SPEED_1000MBPS) {
5237                        Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5238                        Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5239
5240                        LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5241                        pDevice->advertising = Value32;
5242
5243                        if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5244                                Value32 = BCM540X_AN_AD_1000BASET_HALF;
5245                        } else {
5246                                Value32 = BCM540X_AN_AD_1000BASET_FULL;
5247                        }
5248
5249                        LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG,
5250                                     Value32);
5251                        pDevice->advertising1000 = Value32;
5252                } else if (LineSpeed == LM_LINE_SPEED_100MBPS) {
5253                        LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5254                        pDevice->advertising1000 = 0;
5255
5256                        if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5257                                Value32 = PHY_AN_AD_100BASETX_HALF;
5258                        } else {
5259                                Value32 = PHY_AN_AD_100BASETX_FULL;
5260                        }
5261
5262                        Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5263                        Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5264
5265                        LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5266                        pDevice->advertising = Value32;
5267                } else if (LineSpeed == LM_LINE_SPEED_10MBPS) {
5268                        LM_WritePhy (pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5269                        pDevice->advertising1000 = 0;
5270
5271                        if (DuplexMode != LM_DUPLEX_MODE_FULL) {
5272                                Value32 = PHY_AN_AD_10BASET_HALF;
5273                        } else {
5274                                Value32 = PHY_AN_AD_10BASET_FULL;
5275                        }
5276
5277                        Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5278                        Value32 |= GetPhyAdFlowCntrlSettings (pDevice);
5279
5280                        LM_WritePhy (pDevice, PHY_AN_AD_REG, Value32);
5281                        pDevice->advertising = Value32;
5282                }
5283        }
5284
5285        /* Force line speed if auto-negotiation is disabled. */
5286        if (pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN) {
5287                /* This code path is executed only when there is link. */
5288                pDevice->MediaType = MediaType;
5289                pDevice->LineSpeed = LineSpeed;
5290                pDevice->DuplexMode = DuplexMode;
5291
5292                /* Force line seepd. */
5293                NewPhyCtrl = 0;
5294                switch (LineSpeed) {
5295                case LM_LINE_SPEED_10MBPS:
5296                        NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
5297                        break;
5298                case LM_LINE_SPEED_100MBPS:
5299                        NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
5300                        break;
5301                case LM_LINE_SPEED_1000MBPS:
5302                        NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5303                        break;
5304                default:
5305                        NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5306                        break;
5307                }
5308
5309                if (DuplexMode == LM_DUPLEX_MODE_FULL) {
5310                        NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
5311                }
5312
5313                /* Don't do anything if the PHY_CTRL is already what we wanted. */
5314                LM_ReadPhy (pDevice, PHY_CTRL_REG, &Value32);
5315                if (Value32 != NewPhyCtrl) {
5316                        /* Temporary bring the link down before forcing line speed. */
5317                        LM_WritePhy (pDevice, PHY_CTRL_REG,
5318                                     PHY_CTRL_LOOPBACK_MODE);
5319
5320                        /* Wait for link to go down. */
5321                        for (Cnt = 0; Cnt < 15000; Cnt++) {
5322                                MM_Wait (10);
5323
5324                                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
5325                                LM_ReadPhy (pDevice, PHY_STATUS_REG, &Value32);
5326
5327                                if (!(Value32 & PHY_STATUS_LINK_PASS)) {
5328                                        MM_Wait (40);
5329                                        break;
5330                                }
5331                        }
5332
5333                        LM_WritePhy (pDevice, PHY_CTRL_REG, NewPhyCtrl);
5334                        MM_Wait (40);
5335                }
5336        } else {
5337                LM_WritePhy (pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
5338                             PHY_CTRL_RESTART_AUTO_NEG);
5339        }
5340
5341        return LM_STATUS_SUCCESS;
5342}                               /* LM_ForceAutoNegBcm540xPhy */
5343
5344/******************************************************************************/
5345/* Description:                                                               */
5346/*                                                                            */
5347/* Return:                                                                    */
5348/******************************************************************************/
5349static LM_STATUS
5350LM_ForceAutoNeg (PLM_DEVICE_BLOCK pDevice,
5351                 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5352{
5353        LM_STATUS LmStatus;
5354
5355        /* Initialize the phy chip. */
5356        switch (pDevice->PhyId & PHY_ID_MASK) {
5357        case PHY_BCM5400_PHY_ID:
5358        case PHY_BCM5401_PHY_ID:
5359        case PHY_BCM5411_PHY_ID:
5360        case PHY_BCM5701_PHY_ID:
5361        case PHY_BCM5703_PHY_ID:
5362        case PHY_BCM5704_PHY_ID:
5363                LmStatus =
5364                    LM_ForceAutoNegBcm540xPhy (pDevice, RequestedMediaType);
5365                break;
5366
5367        default:
5368                LmStatus = LM_STATUS_FAILURE;
5369                break;
5370        }
5371
5372        return LmStatus;
5373}                               /* LM_ForceAutoNeg */
5374
5375/******************************************************************************/
5376/* Description:                                                               */
5377/*                                                                            */
5378/* Return:                                                                    */
5379/******************************************************************************/
5380LM_STATUS LM_LoadFirmware (PLM_DEVICE_BLOCK pDevice,
5381                           PT3_FWIMG_INFO pFwImg,
5382                           LM_UINT32 LoadCpu, LM_UINT32 StartCpu)
5383{
5384        LM_UINT32 i;
5385        LM_UINT32 address;
5386
5387        if (LoadCpu & T3_RX_CPU_ID) {
5388                if (LM_HaltCpu (pDevice, T3_RX_CPU_ID) != LM_STATUS_SUCCESS) {
5389                        return LM_STATUS_FAILURE;
5390                }
5391
5392                /* First of all clear scrach pad memory */
5393                for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i += 4) {
5394                        LM_RegWrInd (pDevice, T3_RX_CPU_SPAD_ADDR + i, 0);
5395                }
5396
5397                /* Copy code first */
5398                address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5399                for (i = 0; i <= pFwImg->Text.Length; i += 4) {
5400                        LM_RegWrInd (pDevice, address + i,
5401                                     ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
5402                                                                         4]);
5403                }
5404
5405                address =
5406                    T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5407                for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
5408                        LM_RegWrInd (pDevice, address + i,
5409                                     ((LM_UINT32 *) pFwImg->ROnlyData.
5410                                      Buffer)[i / 4]);
5411                }
5412
5413                address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5414                for (i = 0; i <= pFwImg->Data.Length; i += 4) {
5415                        LM_RegWrInd (pDevice, address + i,
5416                                     ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
5417                                                                         4]);
5418                }
5419        }
5420
5421        if (LoadCpu & T3_TX_CPU_ID) {
5422                if (LM_HaltCpu (pDevice, T3_TX_CPU_ID) != LM_STATUS_SUCCESS) {
5423                        return LM_STATUS_FAILURE;
5424                }
5425
5426                /* First of all clear scrach pad memory */
5427                for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i += 4) {
5428                        LM_RegWrInd (pDevice, T3_TX_CPU_SPAD_ADDR + i, 0);
5429                }
5430
5431                /* Copy code first */
5432                address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5433                for (i = 0; i <= pFwImg->Text.Length; i += 4) {
5434                        LM_RegWrInd (pDevice, address + i,
5435                                     ((LM_UINT32 *) pFwImg->Text.Buffer)[i /
5436                                                                         4]);
5437                }
5438
5439                address =
5440                    T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5441                for (i = 0; i <= pFwImg->ROnlyData.Length; i += 4) {
5442                        LM_RegWrInd (pDevice, address + i,
5443                                     ((LM_UINT32 *) pFwImg->ROnlyData.
5444                                      Buffer)[i / 4]);
5445                }
5446
5447                address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5448                for (i = 0; i <= pFwImg->Data.Length; i += 4) {
5449                        LM_RegWrInd (pDevice, address + i,
5450                                     ((LM_UINT32 *) pFwImg->Data.Buffer)[i /
5451                                                                         4]);
5452                }
5453        }
5454
5455        if (StartCpu & T3_RX_CPU_ID) {
5456                /* Start Rx CPU */
5457                REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5458                REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
5459                for (i = 0; i < 5; i++) {
5460                        if (pFwImg->StartAddress ==
5461                            REG_RD (pDevice, rxCpu.reg.PC))
5462                                break;
5463
5464                        REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5465                        REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5466                        REG_WR (pDevice, rxCpu.reg.PC, pFwImg->StartAddress);
5467                        MM_Wait (1000);
5468                }
5469
5470                REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5471                REG_WR (pDevice, rxCpu.reg.mode, 0);
5472        }
5473
5474        if (StartCpu & T3_TX_CPU_ID) {
5475                /* Start Tx CPU */
5476                REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5477                REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
5478                for (i = 0; i < 5; i++) {
5479                        if (pFwImg->StartAddress ==
5480                            REG_RD (pDevice, txCpu.reg.PC))
5481                                break;
5482
5483                        REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5484                        REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
5485                        REG_WR (pDevice, txCpu.reg.PC, pFwImg->StartAddress);
5486                        MM_Wait (1000);
5487                }
5488
5489                REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5490                REG_WR (pDevice, txCpu.reg.mode, 0);
5491        }
5492
5493        return LM_STATUS_SUCCESS;
5494}
5495
5496STATIC LM_STATUS LM_HaltCpu (PLM_DEVICE_BLOCK pDevice, LM_UINT32 cpu_number)
5497{
5498        LM_UINT32 i;
5499
5500        if (cpu_number == T3_RX_CPU_ID) {
5501                for (i = 0; i < 10000; i++) {
5502                        REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5503                        REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5504
5505                        if (REG_RD (pDevice, rxCpu.reg.mode) & CPU_MODE_HALT)
5506                                break;
5507                }
5508
5509                REG_WR (pDevice, rxCpu.reg.state, 0xffffffff);
5510                REG_WR (pDevice, rxCpu.reg.mode, CPU_MODE_HALT);
5511                MM_Wait (10);
5512        } else {
5513                for (i = 0; i < 10000; i++) {
5514                        REG_WR (pDevice, txCpu.reg.state, 0xffffffff);
5515                        REG_WR (pDevice, txCpu.reg.mode, CPU_MODE_HALT);
5516
5517                        if (REG_RD (pDevice, txCpu.reg.mode) & CPU_MODE_HALT)
5518                                break;
5519                }
5520        }
5521
5522        return ((i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
5523}
5524
5525int LM_BlinkLED (PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
5526{
5527        LM_UINT32 Oldcfg;
5528        int j;
5529        int ret = 0;
5530
5531        if (BlinkDurationSec == 0) {
5532                return 0;
5533        }
5534        if (BlinkDurationSec > 120) {
5535                BlinkDurationSec = 120;
5536        }
5537
5538        Oldcfg = REG_RD (pDevice, MacCtrl.LedCtrl);
5539        for (j = 0; j < BlinkDurationSec * 2; j++) {
5540                if (j % 2) {
5541                        /* Turn on the LEDs. */
5542                        REG_WR (pDevice, MacCtrl.LedCtrl,
5543                                LED_CTRL_OVERRIDE_LINK_LED |
5544                                LED_CTRL_1000MBPS_LED_ON |
5545                                LED_CTRL_100MBPS_LED_ON |
5546                                LED_CTRL_10MBPS_LED_ON |
5547                                LED_CTRL_OVERRIDE_TRAFFIC_LED |
5548                                LED_CTRL_BLINK_TRAFFIC_LED |
5549                                LED_CTRL_TRAFFIC_LED);
5550                } else {
5551                        /* Turn off the LEDs. */
5552                        REG_WR (pDevice, MacCtrl.LedCtrl,
5553                                LED_CTRL_OVERRIDE_LINK_LED |
5554                                LED_CTRL_OVERRIDE_TRAFFIC_LED);
5555                }
5556
5557#ifndef EMBEDDED
5558                current->state = TASK_INTERRUPTIBLE;
5559                if (schedule_timeout (HZ / 2) != 0) {
5560                        ret = -EINTR;
5561                        break;
5562                }
5563#else
5564                udelay (100000);        /* 1s sleep */
5565#endif
5566        }
5567        REG_WR (pDevice, MacCtrl.LedCtrl, Oldcfg);
5568        return ret;
5569}
5570
5571int t3_do_dma (PLM_DEVICE_BLOCK pDevice,
5572               LM_PHYSICAL_ADDRESS host_addr_phy, int length, int dma_read)
5573{
5574        T3_DMA_DESC dma_desc;
5575        int i;
5576        LM_UINT32 dma_desc_addr;
5577        LM_UINT32 value32;
5578
5579        REG_WR (pDevice, BufMgr.Mode, 0);
5580        REG_WR (pDevice, Ftq.Reset, 0);
5581
5582        dma_desc.host_addr.High = host_addr_phy.High;
5583        dma_desc.host_addr.Low = host_addr_phy.Low;
5584        dma_desc.nic_mbuf = 0x2100;
5585        dma_desc.len = length;
5586        dma_desc.flags = 0x00000004;    /* Generate Rx-CPU event */
5587
5588        if (dma_read) {
5589                dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
5590                    T3_QID_DMA_HIGH_PRI_READ;
5591                REG_WR (pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
5592        } else {
5593                dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
5594                    T3_QID_DMA_HIGH_PRI_WRITE;
5595                REG_WR (pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
5596        }
5597
5598        dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
5599
5600        /* Writing this DMA descriptor to DMA memory */
5601        for (i = 0; i < sizeof (T3_DMA_DESC); i += 4) {
5602                value32 = *((PLM_UINT32) (((PLM_UINT8) & dma_desc) + i));
5603                MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG,
5604                                  dma_desc_addr + i);
5605                MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_DATA_REG,
5606                                  cpu_to_le32 (value32));
5607        }
5608        MM_WriteConfig32 (pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
5609
5610        if (dma_read)
5611                REG_WR (pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue,
5612                        dma_desc_addr);
5613        else
5614                REG_WR (pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue,
5615                        dma_desc_addr);
5616
5617        for (i = 0; i < 40; i++) {
5618                if (dma_read)
5619                        value32 =
5620                            REG_RD (pDevice,
5621                                    Ftq.RcvBdCompFtqFifoEnqueueDequeue);
5622                else
5623                        value32 =
5624                            REG_RD (pDevice,
5625                                    Ftq.RcvDataCompFtqFifoEnqueueDequeue);
5626
5627                if ((value32 & 0xffff) == dma_desc_addr)
5628                        break;
5629
5630                MM_Wait (10);
5631        }
5632
5633        return LM_STATUS_SUCCESS;
5634}
5635
5636STATIC LM_STATUS
5637LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
5638            LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
5639{
5640        int j;
5641        LM_UINT32 *ptr;
5642        int dma_success = 0;
5643
5644        if (T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
5645            T3_ASIC_REV (pDevice->ChipRevId) != T3_ASIC_REV_5701) {
5646                return LM_STATUS_SUCCESS;
5647        }
5648        while (!dma_success) {
5649                /* Fill data with incremental patterns */
5650                ptr = (LM_UINT32 *) pBufferVirt;
5651                for (j = 0; j < BufferSize / 4; j++)
5652                        *ptr++ = j;
5653
5654                if (t3_do_dma (pDevice, BufferPhy, BufferSize, 1) ==
5655                    LM_STATUS_FAILURE) {
5656                        return LM_STATUS_FAILURE;
5657                }
5658
5659                MM_Wait (40);
5660                ptr = (LM_UINT32 *) pBufferVirt;
5661                /* Fill data with zero */
5662                for (j = 0; j < BufferSize / 4; j++)
5663                        *ptr++ = 0;
5664
5665                if (t3_do_dma (pDevice, BufferPhy, BufferSize, 0) ==
5666                    LM_STATUS_FAILURE) {
5667                        return LM_STATUS_FAILURE;
5668                }
5669
5670                MM_Wait (40);
5671                /* Check for data */
5672                ptr = (LM_UINT32 *) pBufferVirt;
5673                for (j = 0; j < BufferSize / 4; j++) {
5674                        if (*ptr++ != j) {
5675                                if ((pDevice->
5676                                     DmaReadWriteCtrl &
5677                                     DMA_CTRL_WRITE_BOUNDARY_MASK)
5678                                    == DMA_CTRL_WRITE_BOUNDARY_DISABLE) {
5679                                        pDevice->DmaReadWriteCtrl =
5680                                            (pDevice->
5681                                             DmaReadWriteCtrl &
5682                                             ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
5683                                            DMA_CTRL_WRITE_BOUNDARY_16;
5684                                        REG_WR (pDevice,
5685                                                PciCfg.DmaReadWriteCtrl,
5686                                                pDevice->DmaReadWriteCtrl);
5687                                        break;
5688                                } else {
5689                                        return LM_STATUS_FAILURE;
5690                                }
5691                        }
5692                }
5693                if (j == (BufferSize / 4))
5694                        dma_success = 1;
5695        }
5696        return LM_STATUS_SUCCESS;
5697}
5698