1/******************************************************************************/
2/*                                                                            */
3/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 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
14#include "mm.h"
15
16
17
18/******************************************************************************/
19/* Local functions. */
20/******************************************************************************/
21
22LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
23LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
24
25static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
26static LM_VOID LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice);
27
28LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
29LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
30
31static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice);
32static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
33STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
34    LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
35#if INCLUDE_TBI_SUPPORT
36STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
37STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
38#endif
39STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
40STATIC LM_VOID LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice);
41STATIC LM_STATUS LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice);
42STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
43LM_VOID LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2);
44STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
45           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
46STATIC LM_STATUS LM_DisableChip(PLM_DEVICE_BLOCK pDevice);
47STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
48STATIC LM_STATUS LM_DisableFW(PLM_DEVICE_BLOCK pDevice);
49STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
50    PT3_SND_BD pSendBd);
51STATIC LM_VOID LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice,
52    LM_RESET_TYPE Mode);
53STATIC LM_VOID LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice,
54    LM_RESET_TYPE Mode);
55STATIC LM_VOID LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice,
56    LM_RESET_TYPE Mode);
57STATIC void LM_GetPhyId(LM_DEVICE_BLOCK *pDevice);
58
59/******************************************************************************/
60/* External functions. */
61/******************************************************************************/
62
63LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
64#if INCLUDE_TCP_SEG_SUPPORT
65LM_STATUS LM_LoadStkOffLdFirmware(PLM_DEVICE_BLOCK pDevice);
66LM_UINT32 LM_GetStkOffLdFirmwareSize(PLM_DEVICE_BLOCK pDevice);
67#endif
68
69LM_UINT32
70LM_RegRd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
71{
72#if PCIX_TARGET_WORKAROUND
73    if (pDevice->Flags & UNDI_FIX_FLAG)
74    {
75        return (LM_RegRdInd(pDevice, Register));
76    }
77    else
78#endif
79    {
80        return (REG_RD_OFFSET(pDevice, Register));
81    }
82}
83
84/* Mainly used to flush posted write before delaying */
85LM_VOID
86LM_RegRdBack(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
87{
88    LM_UINT32 dummy;
89
90#if PCIX_TARGET_WORKAROUND
91    if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
92    {
93        return;
94    }
95    else
96#endif
97    {
98        if (pDevice->Flags & REG_RD_BACK_FLAG)
99            return;
100
101        dummy = REG_RD_OFFSET(pDevice, Register);
102    }
103}
104
105LM_VOID
106LM_RegWr(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32,
107    LM_UINT32 ReadBack)
108{
109#if PCIX_TARGET_WORKAROUND
110    if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
111    {
112        LM_RegWrInd(pDevice, Register, Value32);
113    }
114    else
115#endif
116    {
117        LM_UINT32 dummy;
118
119        REG_WR_OFFSET(pDevice, Register, Value32);
120        if (ReadBack && (pDevice->Flags & REG_RD_BACK_FLAG))
121        {
122            dummy = REG_RD_OFFSET(pDevice, Register);
123        }
124    }
125}
126
127/******************************************************************************/
128/* Description:                                                               */
129/*                                                                            */
130/* Return:                                                                    */
131/******************************************************************************/
132LM_UINT32
133LM_RegRdInd(
134PLM_DEVICE_BLOCK pDevice,
135LM_UINT32 Register) {
136    LM_UINT32 Value32;
137
138    MM_ACQUIRE_UNDI_LOCK(pDevice);
139    MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
140    MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
141    MM_RELEASE_UNDI_LOCK(pDevice);
142
143    return MM_SWAP_LE32(Value32);
144} /* LM_RegRdInd */
145
146
147
148/******************************************************************************/
149/* Description:                                                               */
150/*                                                                            */
151/* Return:                                                                    */
152/******************************************************************************/
153LM_VOID
154LM_RegWrInd(
155PLM_DEVICE_BLOCK pDevice,
156LM_UINT32 Register,
157LM_UINT32 Value32) {
158
159    MM_ACQUIRE_UNDI_LOCK(pDevice);
160    MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
161    MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, MM_SWAP_LE32(Value32));
162    MM_RELEASE_UNDI_LOCK(pDevice);
163} /* LM_RegWrInd */
164
165
166
167/******************************************************************************/
168/* Description:                                                               */
169/*                                                                            */
170/* Return:                                                                    */
171/******************************************************************************/
172LM_UINT32
173LM_MemRdInd(
174PLM_DEVICE_BLOCK pDevice,
175LM_UINT32 MemAddr) {
176    LM_UINT32 Value32;
177
178    MM_ACQUIRE_UNDI_LOCK(pDevice);
179    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
180    MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
181    MM_RELEASE_UNDI_LOCK(pDevice);
182
183    return MM_SWAP_LE32(Value32);
184} /* LM_MemRdInd */
185
186
187
188/******************************************************************************/
189/* Description:                                                               */
190/*                                                                            */
191/* Return:                                                                    */
192/******************************************************************************/
193LM_VOID
194LM_MemWrInd(
195PLM_DEVICE_BLOCK pDevice,
196LM_UINT32 MemAddr,
197LM_UINT32 Value32) {
198    MM_ACQUIRE_UNDI_LOCK(pDevice);
199    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
200    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, MM_SWAP_LE32(Value32));
201    MM_RELEASE_UNDI_LOCK(pDevice);
202} /* LM_MemWrInd */
203
204
205/******************************************************************************/
206/* Description:                                                               */
207/*                                                                            */
208/* Return:                                                                    */
209/******************************************************************************/
210LM_STATUS
211LM_QueueRxPackets(
212PLM_DEVICE_BLOCK pDevice) {
213    LM_STATUS Lmstatus;
214    PLM_PACKET pPacket;
215    PT3_RCV_BD pRcvBd = 0;
216    LM_UINT32 StdBdAdded = 0;
217#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
218    LM_UINT32 JumboBdAdded = 0;
219#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
220    LM_UINT32 ConIdx, Idx;
221    LM_UINT32 Diff = 0;
222
223    Lmstatus = LM_STATUS_SUCCESS;
224
225    if (pDevice->Flags & RX_BD_LIMIT_64_FLAG)
226    {
227        ConIdx = pDevice->pStatusBlkVirt->RcvStdConIdx;
228        Diff = (pDevice->RxStdProdIdx - ConIdx) &
229            T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
230        if (Diff >= 56)
231        {
232            if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
233            {
234                pDevice->QueueAgain = TRUE;
235            }
236            return LM_STATUS_SUCCESS;
237        }
238    }
239
240    pDevice->QueueAgain = FALSE;
241
242    pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
243    while(pPacket) {
244        switch(pPacket->u.Rx.RcvProdRing) {
245#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
246            case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
247                /* Initialize the buffer descriptor. */
248                Idx = pDevice->RxJumboProdIdx;
249                pRcvBd = &pDevice->pRxJumboBdVirt[Idx];
250
251                pPacket->u.Rx.RcvRingProdIdx = Idx;
252                pDevice->RxJumboRing[Idx] = pPacket;
253                /* Update the producer index. */
254                pDevice->RxJumboProdIdx = (Idx + 1) &
255                    T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
256
257                JumboBdAdded++;
258                break;
259#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
260
261            case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
262                /* Initialize the buffer descriptor. */
263                Idx = pDevice->RxStdProdIdx;
264                pRcvBd = &pDevice->pRxStdBdVirt[Idx];
265
266                pPacket->u.Rx.RcvRingProdIdx = Idx;
267                pDevice->RxStdRing[Idx] = pPacket;
268                /* Update the producer index. */
269                pDevice->RxStdProdIdx = (Idx + 1) &
270                    T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
271
272                StdBdAdded++;
273                break;
274
275            case T3_UNKNOWN_RCV_PROD_RING:
276            default:
277                Lmstatus = LM_STATUS_FAILURE;
278                break;
279        } /* switch */
280
281        /* Bail out if there is any error. */
282        if(Lmstatus != LM_STATUS_SUCCESS)
283        {
284            break;
285        }
286
287        /* Initialize the receive buffer pointer */
288        MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
289
290        /* The opaque field may point to an offset from a fix addr. */
291        pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
292            MM_UINT_PTR(pDevice->pPacketDescBase));
293
294        if ((pDevice->Flags & RX_BD_LIMIT_64_FLAG) &&
295            ((Diff + StdBdAdded) >= 63))
296        {
297            if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
298            {
299                pDevice->QueueAgain = TRUE;
300            }
301            break;
302        }
303        pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
304    } /* while */
305
306    MM_WMB();
307    /* Update the procedure index. */
308    if(StdBdAdded)
309    {
310        MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low,
311            pDevice->RxStdProdIdx);
312        if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
313        {
314            MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
315        }
316    }
317#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
318    if(JumboBdAdded)
319    {
320        MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
321            pDevice->RxJumboProdIdx);
322        if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
323        {
324            MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
325        }
326    }
327#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
328
329    return Lmstatus;
330} /* LM_QueueRxPackets */
331
332
333/******************************************************************************/
334/* Description:                                                               */
335/*                                                                            */
336/* Return:                                                                    */
337/******************************************************************************/
338STATIC LM_VOID
339LM_NvramInit(
340    PLM_DEVICE_BLOCK pDevice)
341{
342    LM_UINT32 Value32;
343
344    pDevice->NvramSize = 0;
345    /* Intialize clock period and state machine. */
346    Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
347        SEEPROM_ADDR_FSM_RESET;
348    REG_WR(pDevice, Grc.EepromAddr, Value32);
349    REG_RD_BACK(pDevice, Grc.EepromAddr);
350
351    MM_Wait(100);
352
353    /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
354    Value32 = REG_RD(pDevice, Grc.LocalCtrl);
355    REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
356
357    /* Set the 5701 compatibility mode if we are using EEPROM. */
358    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
359        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
360    {
361        Value32 = REG_RD(pDevice, Nvram.Config1);
362        if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
363        {
364            if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
365            {
366                REG_WR(pDevice, Nvram.NvmAccess,
367                    REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
368            }
369            /* Use the new interface to read EEPROM. */
370            Value32 &= ~FLASH_COMPAT_BYPASS;
371
372            REG_WR(pDevice, Nvram.Config1, Value32);
373
374            if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
375            {
376                REG_WR(pDevice, Nvram.NvmAccess,
377                    REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
378            }
379        }
380        else {
381            pDevice->NvramSize = 0x20000;
382            pDevice->Flags |= FLASH_DETECTED_FLAG;
383        }
384    }
385
386    if (pDevice->NvramSize == 0)
387    {
388        Value32 = 0;
389        LM_NvramRead(pDevice, 0, &Value32);
390        Value32 = MM_SWAP_BE32(Value32);
391        if (Value32 != 0x669955aa) {
392            pDevice->NvramSize = SEEPROM_CHIP_SIZE;
393            return;
394        }
395
396        /* size eeprom */
397        pDevice->NvramSize = 0x800;
398        while (pDevice->NvramSize < SEEPROM_CHIP_SIZE) {
399            if (LM_NvramRead(pDevice, pDevice->NvramSize, &Value32) !=
400                LM_STATUS_SUCCESS) {
401                pDevice->NvramSize = SEEPROM_CHIP_SIZE;
402                break;
403            }
404            Value32 = MM_SWAP_BE32(Value32);
405            if (Value32 == 0x669955aa)
406                break;
407            pDevice->NvramSize <<= 1;
408        }
409    }
410} /* LM_NvRamInit */
411
412
413/******************************************************************************/
414/* Description:                                                               */
415/*                                                                            */
416/* Return:                                                                    */
417/******************************************************************************/
418STATIC LM_STATUS
419LM_EepromRead(
420    PLM_DEVICE_BLOCK pDevice,
421    LM_UINT32 Offset,
422    LM_UINT32 *pData)
423{
424    LM_UINT32 Value32;
425    LM_UINT32 Addr;
426    LM_UINT32 Dev;
427    LM_UINT32 j;
428
429    if(Offset > SEEPROM_CHIP_SIZE)
430    {
431        return LM_STATUS_FAILURE;
432    }
433
434    Dev = Offset / SEEPROM_CHIP_SIZE;
435    Addr = Offset % SEEPROM_CHIP_SIZE;
436
437    Value32 = REG_RD(pDevice, Grc.EepromAddr);
438    Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
439        SEEPROM_ADDR_RW_MASK);
440    REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
441        SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
442
443    for(j = 0; j < 1000; j++)
444    {
445        Value32 = REG_RD(pDevice, Grc.EepromAddr);
446        if(Value32 & SEEPROM_ADDR_COMPLETE)
447        {
448            break;
449        }
450        MM_Wait(20);
451    }
452
453    if(Value32 & SEEPROM_ADDR_COMPLETE)
454    {
455        Value32 = REG_RD(pDevice, Grc.EepromData);
456        /* The endianess of the eeprom and flash interface is different */
457        *pData = MM_SWAP_LE32(Value32);
458
459        return LM_STATUS_SUCCESS;
460    }
461
462    return LM_STATUS_FAILURE;
463} /* LM_EepromRead */
464
465#ifdef ETHTOOL_SEEPROM
466
467STATIC LM_STATUS
468LM_EepromWriteBlock(
469    PLM_DEVICE_BLOCK pDevice,
470    LM_UINT32 Offset,
471    LM_UINT32 *pData,
472    LM_UINT32 Size)
473{
474    LM_UINT32 Value32 = 0;
475    LM_UINT32 Addr;
476    LM_UINT32 Dev;
477    LM_UINT32 i, j;
478
479    if(Offset > SEEPROM_CHIP_SIZE)
480    {
481        return LM_STATUS_FAILURE;
482    }
483
484    /* Enable EEPROM write. */
485    if (pDevice->Flags & EEPROM_WP_FLAG)
486    {
487        REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
488                    GRC_MISC_LOCAL_CTRL_GPIO_OE1);
489        REG_RD_BACK(pDevice, Grc.LocalCtrl);
490        MM_Wait(40);
491
492        Value32 = REG_RD(pDevice, Grc.LocalCtrl);
493        if(Value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1)
494        {
495            return LM_STATUS_FAILURE;
496        }
497    }
498
499    for (i = 0; i < Size ; i++, pData++, Offset += 4) {
500
501        Dev = Offset / SEEPROM_CHIP_SIZE;
502        Addr = Offset % SEEPROM_CHIP_SIZE;
503
504        /* Set the write value to the eeprom */
505        REG_WR(pDevice, Grc.EepromData, MM_SWAP_LE32(*pData));
506
507        Value32 = REG_RD(pDevice, Grc.EepromAddr);
508        Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
509                            SEEPROM_ADDR_RW_MASK);
510
511        REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
512                        SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_WRITE);
513
514        for(j = 0; j < 1000; j++)
515        {
516            Value32 = REG_RD(pDevice, Grc.EepromAddr);
517            if(Value32 & SEEPROM_ADDR_COMPLETE)
518            {
519                break;
520            }
521            MM_Wait(10);
522        }
523    }
524
525    /* Write-protect EEPROM. */
526    if (pDevice->Flags & EEPROM_WP_FLAG)
527    {
528        REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
529            GRC_MISC_LOCAL_CTRL_GPIO_OE1 | GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
530        REG_RD_BACK(pDevice, Grc.LocalCtrl);
531        MM_Wait(40);
532    }
533
534    if(Value32 & SEEPROM_ADDR_COMPLETE)
535    {
536        return LM_STATUS_SUCCESS;
537    }
538
539    return LM_STATUS_FAILURE;
540} /* LM_EepromWriteBlock */
541#endif
542
543#define NVRAM_MAXWAIT 8000
544LM_STATUS
545LM_NvramGetLock(LM_DEVICE_BLOCK *pDevice)
546{
547    int j;
548
549    REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
550    /* worst case wait time for Nvram arbitration using serial eprom is */
551    /* about 45 msec on a 5704 with the other channel loading boot code */
552    for (j = 0; j < NVRAM_MAXWAIT; j++)
553    {
554        if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
555        {
556            break;
557        }
558        MM_Wait(20);
559    }
560    if (j == NVRAM_MAXWAIT)
561    {
562        return LM_STATUS_FAILURE;
563    }
564    return LM_STATUS_SUCCESS;
565}
566
567LM_STATUS
568LM_NvramReleaseLock(LM_DEVICE_BLOCK *pDevice)
569{
570    REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
571    return LM_STATUS_SUCCESS;
572}
573
574/******************************************************************************/
575/* Description:                                                               */
576/*                                                                            */
577/* Return:                                                                    */
578/******************************************************************************/
579LM_STATUS
580LM_NvramRead(
581    PLM_DEVICE_BLOCK pDevice,
582    LM_UINT32 Offset,
583    LM_UINT32 *pData)
584{
585    LM_UINT32 Value32;
586    LM_STATUS Status;
587    LM_UINT32 j;
588
589    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
590        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
591    {
592        Status = LM_EepromRead(pDevice, Offset, pData);
593    }
594    else
595    {
596        /* Determine if we have flash or EEPROM. */
597        Value32 = REG_RD(pDevice, Nvram.Config1);
598        if(Value32 & FLASH_INTERFACE_ENABLE)
599        {
600            if(Value32 & FLASH_SSRAM_BUFFERED_MODE)
601            {
602                Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
603                    BUFFERED_FLASH_PAGE_POS) +
604                    (Offset % BUFFERED_FLASH_PAGE_SIZE);
605            }
606        }
607
608        if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
609        {
610            return LM_STATUS_FAILURE;
611	}
612
613        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
614        {
615            REG_WR(pDevice, Nvram.NvmAccess,
616                REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
617        }
618
619        /* Read from flash or EEPROM with the new 5703/02 interface. */
620        REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
621
622        REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
623            NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
624
625        /* Wait for the done bit to clear. */
626        for(j = 0; j < 1000; j++)
627        {
628            MM_Wait(10);
629
630            Value32 = REG_RD(pDevice, Nvram.Cmd);
631            if(Value32 & NVRAM_CMD_DONE)
632            {
633                MM_Wait(10);
634
635                *pData = REG_RD(pDevice, Nvram.ReadData);
636
637                /* Data is swapped so that the byte stream is the same */
638                /* in big and little endian systems. */
639                /* Caller will do additional swapping depending on */
640                /* how it wants to look at the data. */
641                *pData = MM_SWAP_BE32(*pData);
642
643                break;
644            }
645        }
646
647        LM_NvramReleaseLock(pDevice);
648        if(Value32 & NVRAM_CMD_DONE)
649        {
650            Status = LM_STATUS_SUCCESS;
651        }
652        else
653        {
654            Status = LM_STATUS_FAILURE;
655        }
656    }
657
658    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
659    {
660        REG_WR(pDevice, Nvram.NvmAccess,
661            REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
662    }
663
664    return Status;
665} /* LM_NvramRead */
666
667
668#ifdef ETHTOOL_SEEPROM
669/******************************************************************************/
670/* Description:                                                               */
671/*                                                                            */
672/* Return:                                                                    */
673/******************************************************************************/
674LM_STATUS
675LM_NvramWriteBlock(
676    PLM_DEVICE_BLOCK pDevice,
677    LM_UINT32 Offset,
678    LM_UINT32 *pData,
679    LM_UINT32 Size)
680{
681    LM_UINT32 Value32 = 0;
682    LM_UINT32 ControlReg;
683    LM_UINT32 AddrOffset;
684    LM_STATUS Status;
685    LM_UINT32  i , j;
686    LM_UINT32 BufferedFlash;
687
688    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
689        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
690    {
691        Status = LM_EepromWriteBlock(pDevice, Offset, pData, Size);
692    }
693    else
694    {
695        if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
696        {
697            return LM_STATUS_FAILURE;
698	}
699
700        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
701        {
702            REG_WR(pDevice, Nvram.NvmAccess,
703                REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
704        }
705
706        /* Enable EEPROM write. */
707        if (pDevice->Flags & EEPROM_WP_FLAG)
708        {
709            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
710                        GRC_MISC_LOCAL_CTRL_GPIO_OE1);
711            REG_RD_BACK(pDevice, Grc.LocalCtrl);
712            MM_Wait(40);
713
714            Value32 = REG_RD(pDevice, Grc.LocalCtrl);
715            if(Value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1)
716            {
717                if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
718                {
719                    REG_WR(pDevice, Nvram.NvmAccess,
720                        REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
721                }
722                return LM_STATUS_FAILURE;
723             }
724        }
725
726        REG_WR(pDevice, Grc.Mode, pDevice->GrcMode |
727            GRC_MODE_NVRAM_WRITE_ENABLE);
728
729        BufferedFlash = FALSE;
730        Value32 = REG_RD(pDevice, Nvram.Config1);
731        if(Value32 & FLASH_INTERFACE_ENABLE)
732        {
733            if(Value32 & FLASH_SSRAM_BUFFERED_MODE)
734            {
735                BufferedFlash = TRUE;
736            }
737        }
738
739        for (i = 0 ; i < Size ; i++, pData++, Offset += 4) {
740
741            /* Swap the data so that the byte stream will */
742            /* be written the same in little and big endian systems */
743            Value32 = MM_SWAP_BE32(*pData);
744
745            /* set the desired write data value to the flash */
746            REG_WR(pDevice, Nvram.WriteData, Value32);
747
748            /* set targeted address */
749            AddrOffset = Offset;
750
751            /* Determine if we have flash or buffered flash. */
752            if(BufferedFlash)
753            {
754                AddrOffset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
755                                        BUFFERED_FLASH_PAGE_POS) +
756                                    (Offset % BUFFERED_FLASH_PAGE_SIZE);
757            }
758
759            /* Write to flash or EEPROM with the new 5703/02 interface. */
760            REG_WR(pDevice, Nvram.Addr, AddrOffset & NVRAM_ADDRESS_MASK);
761
762            ControlReg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_WR;
763            if(i == 0)
764            {
765                ControlReg |= NVRAM_CMD_FIRST;
766            }
767            if(i == (Size - 1))
768            {
769                ControlReg |= NVRAM_CMD_LAST;
770            }
771
772            if(BufferedFlash)
773            {
774                /* Set CMD_FIRST when we are at the beginning of a page. */
775                if(!(AddrOffset & BUFFERED_FLASH_BYTE_ADDR_MASK))
776                {
777                    ControlReg |= NVRAM_CMD_FIRST;
778                }
779                else if((AddrOffset & BUFFERED_FLASH_BYTE_ADDR_MASK) ==
780                    (BUFFERED_FLASH_PAGE_SIZE - 4))
781                {
782                    ControlReg |=  NVRAM_CMD_LAST;
783                }
784            }
785
786            REG_WR(pDevice, Nvram.Cmd,  ControlReg);
787
788            /* Wait for the done bit to go High. */
789            for(j = 0; j < 4000 ; j++)
790            {
791                MM_Wait(10);
792
793                Value32 = REG_RD(pDevice, Nvram.Cmd);
794
795                if(Value32 & NVRAM_CMD_DONE)
796                {
797                    MM_Wait(5);
798                    break;
799                }
800            }
801        }
802
803        REG_WR(pDevice, Grc.Mode, pDevice->GrcMode);
804
805        /* Write-protect EEPROM. */
806        if(pDevice->Flags & EEPROM_WP_FLAG)
807        {
808            REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
809                GRC_MISC_LOCAL_CTRL_GPIO_OE1 | GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
810            REG_RD_BACK(pDevice, Grc.LocalCtrl);
811            MM_Wait(40);
812        }
813
814        /* Relinquish nvram interface. */
815        LM_NvramReleaseLock(pDevice);
816
817        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
818        {
819            REG_WR(pDevice, Nvram.NvmAccess,
820                REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
821        }
822
823        if(Value32 & NVRAM_CMD_DONE)
824        {
825            Status = LM_STATUS_SUCCESS;
826        }
827        else
828        {
829            Status = LM_STATUS_FAILURE;
830        }
831    }
832
833    return Status;
834} /* LM_NvramWriteBlock */
835#endif
836
837STATIC void
838LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
839{
840#ifdef BCM_PROC_FS
841    LM_UINT32 Vpd_arr[256/4];
842    LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
843    LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
844    LM_UINT32 Value32;
845    unsigned int j;
846
847    /* Read PN from VPD */
848    for (j = 0; j < 256; j += 4, Vpd_dptr++ )
849    {
850        if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
851            printf("VPD read failed\n");
852            return;
853        }
854        *Vpd_dptr = Value32;
855    }
856    for (j = 0; j < 256; )
857    {
858        unsigned int Vpd_r_len;
859        unsigned int Vpd_r_end;
860
861        if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
862        {
863            j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
864        }
865        else if (Vpd[j] == 0x90)
866        {
867            Vpd_r_len =  Vpd[j + 1] + (Vpd[j + 2] << 8);
868            j += 3;
869            Vpd_r_end = Vpd_r_len + j;
870            while (j < Vpd_r_end)
871            {
872                if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
873                {
874                    unsigned int len = Vpd[j + 2];
875
876                    if (len <= 24)
877                    {
878                        memcpy(pDevice->PartNo, &Vpd[j + 3], len);
879                    }
880                    break;
881                }
882                else
883                {
884                    if (Vpd[j + 2] == 0)
885                    {
886                        break;
887                    }
888                    j = j + Vpd[j + 2];
889                }
890            }
891            break;
892        }
893        else {
894            break;
895        }
896    }
897#endif
898}
899
900STATIC void
901LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
902{
903#ifdef BCM_PROC_FS
904    LM_UINT32 Value32, offset, ver_offset, start_addr;
905    int i;
906
907    if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
908        return;
909    Value32 = MM_SWAP_BE32(Value32);
910    if (Value32 != 0x669955aa)
911        return;
912    if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
913        return;
914
915    offset = MM_SWAP_BE32(offset);
916
917    if((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
918        (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) &&
919        ((REG_RD(pDevice, Nvram.Config1) & BUFFERED_FLASH) == BUFFERED_FLASH))
920    {
921        offset = (offset >> BUFFERED_FLASH_PAGE_POS) *
922            BUFFERED_FLASH_PAGE_SIZE + (offset & BUFFERED_FLASH_BYTE_ADDR_MASK);
923    }
924    if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
925        return;
926
927    Value32 = MM_SWAP_BE32(Value32);
928    if ((((Value32 & ~0x0f00) == 0x0e000003) ||
929        ((Value32 & ~0xff00) == 0x0c000003)) &&
930        (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
931        (Value32 == 0)) {
932
933        if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
934            return;
935        if (LM_NvramRead(pDevice, 4, &start_addr) != LM_STATUS_SUCCESS)
936            return;
937        ver_offset = MM_SWAP_BE32(ver_offset);
938        start_addr = MM_SWAP_BE32(start_addr);
939        offset += ver_offset - start_addr;
940        for (i = 0; i < 16; i += 4) {
941            if (LM_NvramRead(pDevice, offset + i, &Value32) !=
942                LM_STATUS_SUCCESS)
943            {
944                return;
945            }
946            *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = Value32;
947        }
948    }
949    else {
950        char c;
951
952        if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
953            return;
954
955        Value32 = MM_SWAP_BE32(Value32);
956        i = 0;
957        c = ((Value32 & 0xff00) >> 8);
958
959        if (c < 10) {
960            pDevice->BootCodeVer[i++] = c + '0';
961        }
962        else {
963            pDevice->BootCodeVer[i++] = (c / 10) + '0';
964            pDevice->BootCodeVer[i++] = (c % 10) + '0';
965        }
966        pDevice->BootCodeVer[i++] = '.';
967        c = Value32 & 0xff;
968        if (c < 10) {
969            pDevice->BootCodeVer[i++] = '0';
970            pDevice->BootCodeVer[i++] = c + '0';
971        }
972        else {
973            pDevice->BootCodeVer[i++] = (c / 10) + '0';
974            pDevice->BootCodeVer[i++] = (c % 10) + '0';
975        }
976        pDevice->BootCodeVer[i] = 0;
977    }
978#endif
979}
980
981STATIC void
982LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
983{
984#ifdef BCM_PROC_FS
985    LM_UINT32 PciState = pDevice->PciState;
986    LM_UINT32 ClockCtrl;
987    char *SpeedStr = "";
988
989    if (pDevice->Flags & PCI_EXPRESS_FLAG)
990    {
991        strcpy(pDevice->BusSpeedStr, "PCI Express");
992        return;
993    }
994    if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
995    {
996        strcpy(pDevice->BusSpeedStr, "32-bit ");
997    }
998    else
999    {
1000        strcpy(pDevice->BusSpeedStr, "64-bit ");
1001    }
1002    if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
1003    {
1004        strcat(pDevice->BusSpeedStr, "PCI ");
1005        if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
1006        {
1007            SpeedStr = "66MHz";
1008        }
1009        else
1010        {
1011            SpeedStr = "33MHz";
1012        }
1013    }
1014    else
1015    {
1016        strcat(pDevice->BusSpeedStr, "PCIX ");
1017        if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
1018        {
1019            SpeedStr = "133MHz";
1020        }
1021        else
1022        {
1023            ClockCtrl = pDevice->ClockCtrl & 0x1f;
1024            switch (ClockCtrl)
1025            {
1026            case 0:
1027                SpeedStr = "33MHz";
1028                break;
1029
1030            case 2:
1031                SpeedStr = "50MHz";
1032                break;
1033
1034            case 4:
1035                SpeedStr = "66MHz";
1036                break;
1037
1038            case 6:
1039                SpeedStr = "100MHz";
1040                break;
1041
1042            case 7:
1043                SpeedStr = "133MHz";
1044                break;
1045            }
1046        }
1047    }
1048    strcat(pDevice->BusSpeedStr, SpeedStr);
1049#endif
1050}
1051
1052/******************************************************************************/
1053/* Description:                                                               */
1054/*    This routine initializes default parameters and reads the PCI           */
1055/*    configurations.                                                         */
1056/*                                                                            */
1057/* Return:                                                                    */
1058/*    LM_STATUS_SUCCESS                                                       */
1059/******************************************************************************/
1060LM_STATUS
1061LM_GetAdapterInfo(
1062PLM_DEVICE_BLOCK pDevice)
1063{
1064    PLM_ADAPTER_INFO pAdapterInfo;
1065    LM_UINT32 Value32, LedCfg;
1066    LM_STATUS Status;
1067    LM_UINT32 EeSigFound;
1068    LM_UINT32 EePhyTypeSerdes = 0;
1069    LM_UINT32 EePhyId = 0;
1070
1071    /* Get Device Id and Vendor Id */
1072    Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
1073    if(Status != LM_STATUS_SUCCESS)
1074    {
1075        return Status;
1076    }
1077    pDevice->PciVendorId = (LM_UINT16) Value32;
1078    pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
1079
1080    Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
1081    if(Status != LM_STATUS_SUCCESS)
1082    {
1083        return Status;
1084    }
1085    pDevice->PciRevId = (LM_UINT8) Value32;
1086
1087    /* Get chip revision id. */
1088    Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
1089    pDevice->ChipRevId = Value32 >> 16;
1090
1091    /* detremine if it is PCIE system */
1092    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1093    {
1094        Status = MM_ReadConfig32(pDevice, T3_MSI_CAPABILITY_ID_REG, &Value32);
1095        if (((Value32 >> 8) & 0xff) == T3_PCIE_CAPABILITY_ID_REG)
1096        {
1097            Status = MM_ReadConfig32(pDevice, T3_PCIE_CAPABILITY_ID_REG,
1098                &Value32);
1099            if ((Value32 & 0xff) == T3_PCIE_CAPABILITY_ID)
1100            {
1101                pDevice->Flags |= PCI_EXPRESS_FLAG;
1102	    }
1103        }
1104    }
1105
1106    /* Get subsystem vendor. */
1107    Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
1108    if(Status != LM_STATUS_SUCCESS)
1109    {
1110        return Status;
1111    }
1112    pDevice->SubsystemVendorId = (LM_UINT16) Value32;
1113
1114    /* Get PCI subsystem id. */
1115    pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
1116
1117    /* Get the cache line size. */
1118    MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
1119    pDevice->CacheLineSize = (LM_UINT8) Value32;
1120    pDevice->SavedCacheLineReg = Value32;
1121
1122    if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
1123        pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
1124        pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
1125    {
1126        pDevice->Flags &= ~UNDI_FIX_FLAG;
1127    }
1128#if !PCIX_TARGET_WORKAROUND
1129    pDevice->Flags &= ~UNDI_FIX_FLAG;
1130#endif
1131    /* Map the memory base to system address space. */
1132    if (!(pDevice->Flags & UNDI_FIX_FLAG))
1133    {
1134        Status = MM_MapMemBase(pDevice);
1135        if(Status != LM_STATUS_SUCCESS)
1136        {
1137            return Status;
1138        }
1139        /* Initialize the memory view pointer. */
1140        pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
1141    }
1142
1143    if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) ||
1144        (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
1145    {
1146        pDevice->Flags |= TX_4G_WORKAROUND_FLAG;
1147    }
1148    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1149    {
1150        pDevice->Flags |= REG_RD_BACK_FLAG;
1151    }
1152#ifdef INCLUDE_5750_A0_FIX
1153    if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
1154        (pDevice->ChipRevId == T3_CHIP_ID_5750_A0))
1155    {
1156        pDevice->Flags |= REG_RD_BACK_FLAG;
1157    }
1158#endif
1159#if PCIX_TARGET_WORKAROUND
1160    MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
1161    if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
1162    {
1163        /* Enable PCI-X workaround only if we are running on 5700 BX. */
1164        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
1165        {
1166            pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1167        }
1168    }
1169    if (pDevice->Flags & UNDI_FIX_FLAG)
1170    {
1171        pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1172    }
1173#endif
1174    /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
1175    /* management register may be clobbered which may cause the */
1176    /* BCM5700 to go into D3 state.  While in this state, we will */
1177    /* not have memory mapped register access.  As a workaround, we */
1178    /* need to restore the device to D0 state. */
1179    MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
1180    Value32 |= T3_PM_PME_ASSERTED;
1181    Value32 &= ~T3_PM_POWER_STATE_MASK;
1182    Value32 |= T3_PM_POWER_STATE_D0;
1183    MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
1184
1185    /* read the current PCI command word */
1186    MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
1187
1188    /* Make sure bus-mastering is enabled. */
1189    Value32 |= PCI_BUSMASTER_ENABLE;
1190
1191#if PCIX_TARGET_WORKAROUND
1192    /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
1193        are enabled */
1194    if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG) {
1195        Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
1196                    PCI_PARITY_ERROR_ENABLE);
1197    }
1198    if (pDevice->Flags & UNDI_FIX_FLAG)
1199    {
1200        Value32 &= ~PCI_MEM_SPACE_ENABLE;
1201    }
1202
1203#endif
1204
1205    if (pDevice->Flags & ENABLE_MWI_FLAG)
1206    {
1207        Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
1208    }
1209    else {
1210        Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
1211    }
1212
1213    /* save the value we are going to write into the PCI command word */
1214    pDevice->PciCommandStatusWords = Value32;
1215
1216    Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
1217    if(Status != LM_STATUS_SUCCESS)
1218    {
1219        return Status;
1220    }
1221
1222    /* Setup the mode registers. */
1223    pDevice->MiscHostCtrl =
1224        MISC_HOST_CTRL_MASK_PCI_INT |
1225        MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
1226#ifdef BIG_ENDIAN_HOST
1227        MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
1228#endif /* BIG_ENDIAN_HOST */
1229        MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
1230        MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
1231	/* write to PCI misc host ctr first in order to enable indirect accesses */
1232    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
1233
1234    /* Set power state to D0. */
1235    LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
1236
1237    /* Preserve HOST_STACK_UP bit in case ASF firmware is running */
1238    Value32 = REG_RD(pDevice, Grc.Mode) & GRC_MODE_HOST_STACK_UP;
1239#ifdef BIG_ENDIAN_HOST
1240    Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
1241              GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
1242#else
1243    Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
1244#endif
1245    REG_WR(pDevice, Grc.Mode, Value32);
1246
1247    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1248    {
1249        REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
1250            GRC_MISC_LOCAL_CTRL_GPIO_OE1);
1251        REG_RD_BACK(pDevice, Grc.LocalCtrl);
1252    }
1253    MM_Wait(40);
1254
1255    /* Enable indirect memory access */
1256    REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
1257
1258    LM_SwitchClocks(pDevice);
1259
1260    REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
1261
1262    /* Check to see if PXE ran and did not shutdown properly */
1263    if ((REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE) ||
1264        !(REG_RD(pDevice, PciCfg.MiscHostCtrl) & MISC_HOST_CTRL_MASK_PCI_INT))
1265    {
1266        LM_DisableInterrupt(pDevice);
1267        /* assume ASF is enabled */
1268        pDevice->AsfFlags = ASF_ENABLED;
1269        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1270        {
1271            pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
1272        }
1273        LM_ShutdownChip(pDevice, LM_SHUTDOWN_RESET);
1274        pDevice->AsfFlags = 0;
1275    }
1276#if PCIX_TARGET_WORKAROUND
1277    MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
1278    if (!(pDevice->Flags & ENABLE_PCIX_FIX_FLAG) &&
1279        ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
1280    {
1281        if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1282            pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1283            pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
1284            pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
1285        {
1286            MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300]), 0);
1287            MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]), 0);
1288            MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]),
1289                0xffffffff);
1290            if (MM_MEMREADL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
1291            {
1292                pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1293            }
1294        }
1295    }
1296#endif
1297
1298    LM_NvramInit(pDevice);
1299
1300    Status = LM_STATUS_FAILURE;
1301    /* Get the node address.  First try to get in from the shared memory. */
1302    /* If the signature is not present, then get it from the NVRAM. */
1303    Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
1304    if((Value32 >> 16) == 0x484b)
1305    {
1306        int i;
1307
1308        pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
1309        pDevice->NodeAddress[1] = (LM_UINT8) Value32;
1310
1311        Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
1312
1313        pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
1314        pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
1315        pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
1316        pDevice->NodeAddress[5] = (LM_UINT8) Value32;
1317
1318        /* Check for null MAC address which can happen with older boot code */
1319        for (i = 0; i < 6; i++)
1320        {
1321            if (pDevice->NodeAddress[i] != 0)
1322            {
1323                Status = LM_STATUS_SUCCESS;
1324                break;
1325            }
1326        }
1327    }
1328    if (Status != LM_STATUS_SUCCESS)
1329    {
1330        int MacOffset;
1331
1332        MacOffset = 0x7c;
1333        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
1334        {
1335            if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
1336            {
1337                MacOffset = 0xcc;
1338            }
1339            /* workaround - need to reset nvram if */
1340            /* the boot code is not running */
1341            if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
1342            {
1343                REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
1344            }
1345            else
1346            {
1347                LM_NvramReleaseLock(pDevice);
1348            }
1349        }
1350        Status = LM_NvramRead(pDevice, MacOffset, &Value32);
1351        if(Status == LM_STATUS_SUCCESS)
1352        {
1353            LM_UINT8 *c = (LM_UINT8 *) &Value32;
1354
1355            pDevice->NodeAddress[0] = c[2];
1356            pDevice->NodeAddress[1] = c[3];
1357
1358            Status = LM_NvramRead(pDevice, MacOffset + 4, &Value32);
1359
1360            c = (LM_UINT8 *) &Value32;
1361            pDevice->NodeAddress[2] = c[0];
1362            pDevice->NodeAddress[3] = c[1];
1363            pDevice->NodeAddress[4] = c[2];
1364            pDevice->NodeAddress[5] = c[3];
1365        }
1366    }
1367
1368    if(Status != LM_STATUS_SUCCESS)
1369    {
1370        Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].High);
1371        pDevice->NodeAddress[0] = (Value32 >> 8) & 0xff;
1372        pDevice->NodeAddress[1] = Value32 & 0xff;
1373        Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].Low);
1374        pDevice->NodeAddress[2] = (Value32 >> 24) & 0xff;
1375        pDevice->NodeAddress[3] = (Value32 >> 16) & 0xff;
1376        pDevice->NodeAddress[4] = (Value32 >> 8) & 0xff;
1377        pDevice->NodeAddress[5] = Value32 & 0xff;
1378        printf("WARNING: Cannot get MAC addr from NVRAM, using %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
1379            pDevice->NodeAddress[0], pDevice->NodeAddress[1],
1380            pDevice->NodeAddress[2], pDevice->NodeAddress[3],
1381            pDevice->NodeAddress[4], pDevice->NodeAddress[5]);
1382    }
1383
1384    memcpy(pDevice->PermanentNodeAddress, pDevice->NodeAddress, 6);
1385
1386    /* Initialize the default values. */
1387    pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
1388    pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
1389    pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
1390    pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
1391    pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
1392    pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
1393    pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
1394    pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
1395    pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
1396    pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
1397    pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
1398    pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1399    pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1400    pDevice->DisableAutoNeg = FALSE;
1401    pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
1402    pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
1403
1404    pDevice->PhyFlags = 0;
1405
1406    if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
1407        pDevice->Flags |= DELAY_PCI_GRANT_FLAG;
1408
1409    pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO;
1410    pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
1411    pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1412    pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
1413#if INCLUDE_TBI_SUPPORT
1414    pDevice->TbiFlags = 0;
1415    pDevice->IgnoreTbiLinkChange = FALSE;
1416#endif
1417#if INCLUDE_TCP_SEG_SUPPORT
1418    pDevice->LargeSendMaxSize = T3_TCP_SEG_MAX_OFFLOAD_SIZE;
1419    pDevice->LargeSendMinNumSeg = T3_TCP_SEG_MIN_NUM_SEG;
1420#endif
1421
1422    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
1423        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
1424        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
1425    {
1426        pDevice->PhyFlags |= PHY_RESET_ON_LINKDOWN;
1427        pDevice->PhyFlags |= PHY_CHECK_TAPS_AFTER_RESET;
1428    }
1429    if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5703_AX) ||
1430        (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
1431    {
1432        pDevice->PhyFlags |= PHY_ADC_FIX;
1433    }
1434    if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
1435    {
1436        pDevice->PhyFlags |= PHY_5704_A0_FIX;
1437    }
1438    if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
1439    {
1440        pDevice->PhyFlags |= PHY_5705_5750_FIX;
1441    }
1442    /* Ethernet@Wirespeed is supported on 5701,5702,5703,5704,5705a0,5705a1 */
1443    if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
1444        !((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
1445        (pDevice->ChipRevId != T3_CHIP_ID_5705_A0) &&
1446        (pDevice->ChipRevId != T3_CHIP_ID_5705_A1)))
1447    {
1448        pDevice->PhyFlags |= PHY_ETHERNET_WIRESPEED;
1449    }
1450
1451    switch (T3_ASIC_REV(pDevice->ChipRevId))
1452    {
1453    case T3_ASIC_REV_5704:
1454        pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1455        pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
1456        break;
1457    default:
1458        pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1459        pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
1460        break;
1461    }
1462
1463    pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
1464    pDevice->QueueRxPackets = TRUE;
1465
1466#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1467    pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
1468    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1469    {
1470        pDevice->RxJumboDescCnt = 0;
1471    }
1472#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1473
1474    pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
1475
1476    if(((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
1477        ((pDevice->BondId == 0x10000) || (pDevice->BondId == 0x18000))) ||
1478        ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) &&
1479        ((pDevice->BondId == 0x14000) || (pDevice->BondId == 0x1c000))))
1480    {
1481        return LM_STATUS_UNKNOWN_ADAPTER;
1482    }
1483    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1484    {
1485        if ((pDevice->BondId == 0x8000) || (pDevice->BondId == 0x4000))
1486        {
1487            pDevice->PhyFlags |= PHY_NO_GIGABIT;
1488        }
1489    }
1490    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1491    {
1492        if ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
1493            (pDevice->BondId == GRC_MISC_BD_ID_5788M))
1494        {
1495            pDevice->Flags |= BCM5788_FLAG;
1496        }
1497        if ((pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901)) ||
1498            (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901A2)) ||
1499            (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5705F)))
1500        {
1501            pDevice->PhyFlags |= PHY_NO_GIGABIT;
1502        }
1503    }
1504    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1505    {
1506        if (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5751F))
1507        {
1508            pDevice->PhyFlags |= PHY_NO_GIGABIT;
1509        }
1510    }
1511
1512    /* CIOBE multisplit has a bug */
1513#if 0
1514    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) &&
1515        (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
1516    {
1517        pDevice->Flags |= MULTI_SPLIT_ENABLE_FLAG;
1518        pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
1519    }
1520#endif
1521
1522    /* Get Eeprom info. */
1523    Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
1524    if (Value32 == T3_NIC_DATA_SIG)
1525    {
1526        EeSigFound = TRUE;
1527        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
1528
1529        if (Value32 & T3_NIC_MINI_PCI)
1530        {
1531            pDevice->Flags |= MINI_PCI_FLAG;
1532        }
1533        /* Determine PHY type. */
1534        switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
1535        {
1536            case T3_NIC_CFG_PHY_TYPE_COPPER:
1537                EePhyTypeSerdes = FALSE;
1538                break;
1539
1540            case T3_NIC_CFG_PHY_TYPE_FIBER:
1541                EePhyTypeSerdes = TRUE;
1542                break;
1543
1544            default:
1545                EePhyTypeSerdes = FALSE;
1546                break;
1547        }
1548
1549        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1550        {
1551            LedCfg = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2);
1552            LedCfg = LedCfg & (T3_NIC_CFG_LED_MODE_MASK |
1553                T3_SHASTA_EXT_LED_MODE_MASK);
1554        }
1555        else
1556        {
1557            /* Determine PHY led mode. for legacy devices */
1558            LedCfg = Value32 & T3_NIC_CFG_LED_MODE_MASK;
1559        }
1560
1561        switch (LedCfg)
1562        {
1563            default:
1564            case T3_NIC_CFG_LED_PHY_MODE_1:
1565                pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
1566                break;
1567
1568            case T3_NIC_CFG_LED_PHY_MODE_2:
1569                pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
1570                break;
1571
1572            case T3_NIC_CFG_LED_MAC_MODE:
1573                pDevice->LedCtrl = LED_CTRL_MAC_MODE;
1574                break;
1575
1576	    case T3_SHASTA_EXT_LED_SHARED_TRAFFIC_LINK_MODE:
1577                pDevice->LedCtrl = LED_CTRL_SHARED_TRAFFIC_LINK;
1578                if ((pDevice->ChipRevId != T3_CHIP_ID_5750_A0) &&
1579                    (pDevice->ChipRevId != T3_CHIP_ID_5750_A1))
1580                {
1581                    pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
1582                        LED_CTRL_PHY_MODE_2;
1583		}
1584                break;
1585
1586	    case T3_SHASTA_EXT_LED_MAC_MODE:
1587                pDevice->LedCtrl = LED_CTRL_SHASTA_MAC_MODE;
1588                break;
1589
1590            case T3_SHASTA_EXT_LED_WIRELESS_COMBO_MODE:
1591                pDevice->LedCtrl = LED_CTRL_WIRELESS_COMBO;
1592                if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
1593                {
1594                    pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
1595                        LED_CTRL_PHY_MODE_2;
1596                }
1597                break;
1598
1599        }
1600
1601        if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1602            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)) &&
1603            (pDevice->SubsystemVendorId == T3_SVID_DELL))
1604        {
1605            pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
1606        }
1607
1608        if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
1609            (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
1610            (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
1611        {
1612            /* Enable EEPROM write protection. */
1613            if(Value32 & T3_NIC_EEPROM_WP)
1614            {
1615                pDevice->Flags |= EEPROM_WP_FLAG;
1616            }
1617        }
1618        pDevice->AsfFlags = 0;
1619#ifdef BCM_ASF
1620        if (Value32 & T3_NIC_CFG_ENABLE_ASF)
1621        {
1622            pDevice->AsfFlags |= ASF_ENABLED;
1623            if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1624            {
1625                pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
1626	    }
1627        }
1628#endif
1629        if (Value32 & T3_NIC_FIBER_WOL_CAPABLE)
1630        {
1631            pDevice->Flags |= FIBER_WOL_CAPABLE_FLAG;
1632        }
1633        if (Value32 & T3_NIC_WOL_LIMIT_10)
1634        {
1635            pDevice->Flags |= WOL_LIMIT_10MBPS_FLAG;
1636        }
1637
1638        /* Get the PHY Id. */
1639        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1640        if (Value32)
1641        {
1642            EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1643                PHY_ID1_OUI_MASK) << 10;
1644
1645            Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1646
1647            EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1648              (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1649        }
1650        else
1651        {
1652            EePhyId = 0;
1653            if (!EePhyTypeSerdes && !(pDevice->AsfFlags & ASF_ENABLED))
1654            {
1655                /* reset PHY if boot code couldn't read the PHY ID */
1656                LM_ResetPhy(pDevice);
1657            }
1658        }
1659        if (MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2) & BIT_17)
1660        {
1661            pDevice->PhyFlags |= PHY_CAPACITIVE_COUPLING;
1662        }
1663    }
1664    else
1665    {
1666        EeSigFound = FALSE;
1667    }
1668
1669    /* Set the PHY address. */
1670    pDevice->PhyAddr = PHY_DEVICE_ID;
1671
1672    /* Disable auto polling. */
1673    pDevice->MiMode = 0xc0000;
1674    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
1675    REG_RD_BACK(pDevice, MacCtrl.MiMode);
1676    MM_Wait(80);
1677
1678    if (pDevice->AsfFlags & ASF_ENABLED)
1679    {
1680        /* Reading PHY registers will contend with ASF */
1681        pDevice->PhyId = 0;
1682    }
1683    else
1684    {
1685        /* Get the PHY id. */
1686        LM_GetPhyId(pDevice);
1687    }
1688
1689    /* Set the EnableTbi flag to false if we have a copper PHY. */
1690    switch(pDevice->PhyId & PHY_ID_MASK)
1691    {
1692        case PHY_BCM5400_PHY_ID:
1693        case PHY_BCM5401_PHY_ID:
1694        case PHY_BCM5411_PHY_ID:
1695        case PHY_BCM5701_PHY_ID:
1696        case PHY_BCM5703_PHY_ID:
1697        case PHY_BCM5704_PHY_ID:
1698        case PHY_BCM5705_PHY_ID:
1699        case PHY_BCM5750_PHY_ID:
1700            break;
1701
1702        case PHY_BCM8002_PHY_ID:
1703            pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1704            break;
1705
1706        default:
1707
1708            if (EeSigFound)
1709            {
1710                pDevice->PhyId = EePhyId;
1711                if (EePhyTypeSerdes)
1712                {
1713                    pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1714                }
1715            }
1716            else if ((pAdapterInfo = LM_GetAdapterInfoBySsid(
1717                pDevice->SubsystemVendorId,
1718                pDevice->SubsystemId)))
1719            {
1720                pDevice->PhyId = pAdapterInfo->PhyId;
1721                if (pAdapterInfo->Serdes)
1722                {
1723                    pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1724                }
1725            }
1726            else
1727	    {
1728                if (UNKNOWN_PHY_ID(pDevice->PhyId))
1729                {
1730                    LM_ResetPhy(pDevice);
1731                    LM_GetPhyId(pDevice);
1732                }
1733            }
1734            break;
1735    }
1736
1737    if(UNKNOWN_PHY_ID(pDevice->PhyId) &&
1738        !(pDevice->TbiFlags & ENABLE_TBI_FLAG))
1739    {
1740        pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1741        printf("PHY ID unknown, assume it is SerDes\n");
1742    }
1743
1744    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1745    {
1746        if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
1747        {
1748            pDevice->SavedCacheLineReg &= 0xffff00ff;
1749            pDevice->SavedCacheLineReg |= 0x4000;
1750        }
1751    }
1752
1753    pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1754        LM_ACCEPT_UNICAST;
1755
1756    pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1757        LM_TASK_OFFLOAD_TX_UDP_CHECKSUM | LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |
1758        LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;
1759
1760    if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
1761    {
1762       	pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1763            LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1764    }
1765
1766#if INCLUDE_TCP_SEG_SUPPORT
1767    pDevice->TaskOffloadCap |= LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1768
1769    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
1770        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
1771        (pDevice->ChipRevId == T3_CHIP_ID_5705_A0))
1772    {
1773        pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1774    }
1775#endif
1776
1777#ifdef BCM_ASF
1778    if (pDevice->AsfFlags & ASF_ENABLED)
1779    {
1780        if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
1781        {
1782       	    pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1783	}
1784    }
1785#endif
1786
1787    /* Change driver parameters. */
1788    Status = MM_GetConfig(pDevice);
1789    if(Status != LM_STATUS_SUCCESS)
1790    {
1791        return Status;
1792    }
1793
1794    if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
1795    {
1796        pDevice->Flags &= ~NIC_SEND_BD_FLAG;
1797    }
1798
1799    /* Save the current phy link status. */
1800    if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
1801        !(pDevice->AsfFlags & ASF_ENABLED))
1802    {
1803        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1804        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1805
1806        /* If we don't have link reset the PHY. */
1807        if(!(Value32 & PHY_STATUS_LINK_PASS) ||
1808            (pDevice->PhyFlags & PHY_RESET_ON_INIT))
1809        {
1810
1811            LM_ResetPhy(pDevice);
1812
1813            if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
1814            {
1815                Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1816                    PHY_AN_AD_ALL_SPEEDS;
1817                Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
1818                LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
1819
1820                Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS ;
1821#if INCLUDE_5701_AX_FIX
1822                if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1823                    pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1824                {
1825                    Value32 |= BCM540X_CONFIG_AS_MASTER |
1826                        BCM540X_ENABLE_CONFIG_AS_MASTER;
1827                }
1828#endif
1829                LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
1830
1831                LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
1832                    PHY_CTRL_RESTART_AUTO_NEG);
1833            }
1834
1835        }
1836        LM_SetEthWireSpeed(pDevice);
1837
1838        LM_ReadPhy(pDevice, PHY_AN_AD_REG, &pDevice->advertising);
1839        LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG,
1840            &pDevice->advertising1000);
1841    }
1842    LM_PhyTapPowerMgmt(pDevice);
1843
1844#if INCLUDE_TBI_SUPPORT
1845    if(pDevice->TbiFlags & ENABLE_TBI_FLAG)
1846    {
1847        if (!(pDevice->Flags & FIBER_WOL_CAPABLE_FLAG))
1848        {
1849            pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1850        }
1851        pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1852        if (pDevice->TbiFlags & TBI_PURE_POLLING_FLAG)
1853        {
1854            pDevice->IgnoreTbiLinkChange = TRUE;
1855        }
1856    }
1857    else
1858    {
1859        pDevice->TbiFlags = 0;
1860    }
1861#endif /* INCLUDE_TBI_SUPPORT */
1862
1863    /* UseTaggedStatus is only valid for 5701 and later. */
1864    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
1865        ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
1866        ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
1867        (pDevice->BondId == GRC_MISC_BD_ID_5788M))))
1868    {
1869        pDevice->Flags &= ~USE_TAGGED_STATUS_FLAG;
1870        pDevice->CoalesceMode = 0;
1871    }
1872    else
1873    {
1874        pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1875            HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1876    }
1877
1878    /* Set the status block size. */
1879    if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1880        T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
1881    {
1882        pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1883    }
1884
1885    /* Check the DURING_INT coalescing ticks parameters. */
1886    if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
1887    {
1888        if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1889        {
1890            pDevice->RxCoalescingTicksDuringInt =
1891                DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1892        }
1893
1894        if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1895        {
1896            pDevice->TxCoalescingTicksDuringInt =
1897                DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1898        }
1899
1900        if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1901        {
1902            pDevice->RxMaxCoalescedFramesDuringInt =
1903                DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1904        }
1905
1906        if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1907        {
1908            pDevice->TxMaxCoalescedFramesDuringInt =
1909                DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1910        }
1911    }
1912    else
1913    {
1914        if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1915        {
1916            pDevice->RxCoalescingTicksDuringInt = 0;
1917        }
1918
1919        if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1920        {
1921            pDevice->TxCoalescingTicksDuringInt = 0;
1922        }
1923
1924        if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1925        {
1926            pDevice->RxMaxCoalescedFramesDuringInt = 0;
1927        }
1928
1929        if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1930        {
1931            pDevice->TxMaxCoalescedFramesDuringInt = 0;
1932        }
1933    }
1934
1935#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1936    if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
1937    {
1938        pDevice->RxJumboDescCnt = 0;
1939        if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1940        {
1941            pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1942        }
1943    }
1944    else if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1945    {
1946        pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1947        pDevice->RxJumboDescCnt = 0;
1948    }
1949    else
1950    {
1951        pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
1952            COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
1953
1954        if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
1955        {
1956            pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1957            pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
1958        }
1959        pDevice->TxMtu = pDevice->RxMtu;
1960
1961    }
1962#else
1963    pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1964#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1965
1966    pDevice->RxPacketDescCnt =
1967#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1968        pDevice->RxJumboDescCnt +
1969#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1970        pDevice->RxStdDescCnt;
1971
1972    if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1973    {
1974        pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1975    }
1976
1977    if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
1978    {
1979        pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1980    }
1981
1982    /* Configure the proper ways to get link change interrupt. */
1983    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
1984    {
1985        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1986        {
1987            pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1988        }
1989        else
1990        {
1991            pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1992        }
1993    }
1994    else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
1995    {
1996        /* Auto-polling does not work on 5700_AX and 5700_BX. */
1997        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1998        {
1999            pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
2000        }
2001    }
2002
2003    /* Determine the method to get link change status. */
2004    if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
2005    {
2006        /* The link status bit in the status block does not work on 5700_AX */
2007        /* and 5700_BX chips. */
2008        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2009        {
2010            pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2011        }
2012        else
2013        {
2014            pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
2015        }
2016    }
2017
2018    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
2019        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2020    {
2021        pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2022    }
2023
2024    if (!EeSigFound)
2025    {
2026        pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
2027    }
2028
2029    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2030        T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
2031    {
2032        /* bug? 5701 in LINK10 mode does not seem to work when */
2033        /* PhyIntMode is LINK_READY. */
2034        if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
2035#if INCLUDE_TBI_SUPPORT
2036            !(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
2037#endif
2038            pDevice->LedCtrl == LED_CTRL_PHY_MODE_2)
2039        {
2040            pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
2041            pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2042        }
2043        if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
2044        {
2045            pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
2046        }
2047    }
2048
2049#ifdef BCM_WOL
2050    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2051        pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
2052        pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
2053        pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
2054    {
2055        pDevice->WolSpeed = WOL_SPEED_10MB;
2056    }
2057    else
2058    {
2059        if (pDevice->Flags & WOL_LIMIT_10MBPS_FLAG)
2060        {
2061            pDevice->WolSpeed = WOL_SPEED_10MB;
2062        }
2063	else
2064        {
2065            pDevice->WolSpeed = WOL_SPEED_100MB;
2066        }
2067    }
2068#endif
2069
2070    pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
2071
2072    pDevice->DmaReadFifoSize = 0;
2073    if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
2074        (pDevice->ChipRevId != T3_CHIP_ID_5705_A0)) ||
2075        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750))
2076    {
2077#if INCLUDE_TCP_SEG_SUPPORT
2078        if ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION) &&
2079            ((pDevice->ChipRevId == T3_CHIP_ID_5705_A1) ||
2080            (pDevice->ChipRevId == T3_CHIP_ID_5705_A2)))
2081        {
2082            pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_SIZE_128;
2083        }
2084        else
2085#endif
2086        {
2087            if (!(pDevice->PciState & T3_PCI_STATE_HIGH_BUS_SPEED) &&
2088                !(pDevice->Flags & BCM5788_FLAG) &&
2089                !(pDevice->Flags & PCI_EXPRESS_FLAG))
2090            {
2091                pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
2092                if (pDevice->ChipRevId == T3_CHIP_ID_5705_A1)
2093                {
2094                    pDevice->Flags |= RX_BD_LIMIT_64_FLAG;
2095                }
2096                pDevice->Flags |= DMA_WR_MODE_RX_ACCELERATE_FLAG;
2097            }
2098	    else if (pDevice->Flags & PCI_EXPRESS_FLAG)
2099            {
2100                pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
2101            }
2102        }
2103    }
2104
2105    LM_ReadVPD(pDevice);
2106    LM_ReadBootCodeVersion(pDevice);
2107    LM_GetBusSpeed(pDevice);
2108
2109    return LM_STATUS_SUCCESS;
2110} /* LM_GetAdapterInfo */
2111
2112STATIC PLM_ADAPTER_INFO
2113LM_GetAdapterInfoBySsid(
2114    LM_UINT16 Svid,
2115    LM_UINT16 Ssid)
2116{
2117    static LM_ADAPTER_INFO AdapterArr[] =
2118    {
2119        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
2120        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
2121        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
2122        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
2123        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
2124        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
2125        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
2126        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
2127        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
2128        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5703_PHY_ID, 0},
2129        { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5703_PHY_ID, 0},
2130
2131        { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
2132        { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
2133        { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
2134        { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
2135        { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
2136
2137        { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
2138        { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
2139        { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
2140        { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
2141
2142        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
2143        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
2144        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
2145        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
2146        { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
2147
2148        { 0x1014, 0x0281, 0, 1 },
2149    };
2150    LM_UINT32 j;
2151
2152    for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
2153    {
2154        if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
2155        {
2156            return &AdapterArr[j];
2157        }
2158    }
2159
2160    return NULL;
2161}
2162
2163
2164
2165/******************************************************************************/
2166/* Description:                                                               */
2167/*    This routine sets up receive/transmit buffer descriptions queues.       */
2168/*                                                                            */
2169/* Return:                                                                    */
2170/*    LM_STATUS_SUCCESS                                                       */
2171/******************************************************************************/
2172LM_STATUS
2173LM_InitializeAdapter(
2174PLM_DEVICE_BLOCK pDevice)
2175{
2176    LM_PHYSICAL_ADDRESS MemPhy;
2177    PLM_UINT8 pMemVirt;
2178    PLM_PACKET pPacket;
2179    LM_STATUS Status;
2180    LM_UINT32 Size;
2181    LM_UINT32 Value32, j;
2182    LM_UINT32 DmaWrCmd, DmaRdCmd, DmaWrBdry, DmaRdBdry;
2183
2184    MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
2185    j = 0;
2186    while (((Value32 & 0x3ff) != (pDevice->PciCommandStatusWords & 0x3ff)) &&
2187        (j < 1000))
2188    {
2189        /* On PCIE devices, there are some rare cases where the device */
2190        /* is in the process of link-training at this point */
2191        MM_Wait(200);
2192        MM_WriteConfig32(pDevice, PCI_COMMAND_REG, pDevice->PciCommandStatusWords);
2193        MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
2194        j++;
2195    }
2196    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
2197    /* Set power state to D0. */
2198    LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
2199
2200    /* Intialize the queues. */
2201    QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
2202        MAX_RX_PACKET_DESC_COUNT);
2203    QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
2204        MAX_RX_PACKET_DESC_COUNT);
2205
2206    QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
2207    QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
2208
2209    if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2210    {
2211        pDevice->RcvRetRcbEntryCount = 512;
2212        pDevice->RcvRetRcbEntryCountMask = 511;
2213    }
2214    else
2215    {
2216        pDevice->RcvRetRcbEntryCount = T3_RCV_RETURN_RCB_ENTRY_COUNT;
2217        pDevice->RcvRetRcbEntryCountMask = T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
2218    }
2219
2220    /* Allocate shared memory for: status block, the buffers for receive */
2221    /* rings -- standard, mini, jumbo, and return rings. */
2222    Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
2223        T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
2224#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2225        T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
2226#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2227        (pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
2228
2229    /* Memory for host based Send BD. */
2230    if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2231    {
2232        Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
2233    }
2234
2235    /* Allocate the memory block. */
2236    Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
2237    if(Status != LM_STATUS_SUCCESS)
2238    {
2239        return Status;
2240    }
2241
2242    DmaWrCmd = DMA_CTRL_WRITE_CMD;
2243    DmaRdCmd = DMA_CTRL_READ_CMD;
2244    DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_DISABLE;
2245    DmaRdBdry = DMA_CTRL_READ_BOUNDARY_DISABLE;
2246#ifdef BCM_DISCONNECT_AT_CACHELINE
2247    /* This code is intended for PPC64 and other similar architectures */
2248    /* Only the following chips support this */
2249    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
2250        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
2251        (pDevice->Flags & PCI_EXPRESS_FLAG))
2252    {
2253        switch(pDevice->CacheLineSize * 4)
2254        {
2255            case 16:
2256            case 32:
2257            case 64:
2258            case 128:
2259                if (!(pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
2260                    !(pDevice->Flags & PCI_EXPRESS_FLAG))
2261                {
2262                    /* PCI-X */
2263                    /* use 384 which is a multiple of 16,32,64,128 */
2264                    DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_384_PCIX;
2265                    break;
2266                }
2267                else if (pDevice->Flags & PCI_EXPRESS_FLAG)
2268                {
2269                    /* PCI Express */
2270                    /* use 128 which is a multiple of 16,32,64,128 */
2271                    DmaWrCmd = DMA_CTRL_WRITE_BOUNDARY_128_PCIE;
2272                    break;
2273                }
2274                /* fall through */
2275            case 256:
2276                /* use 256 which is a multiple of 16,32,64,128,256 */
2277                if ((pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
2278                    !(pDevice->Flags & PCI_EXPRESS_FLAG))
2279                {
2280                    /* PCI */
2281                    DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256;
2282                }
2283                else if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
2284                {
2285                    /* PCI-X */
2286                    DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256_PCIX;
2287                }
2288                break;
2289        }
2290    }
2291#endif
2292    pDevice->DmaReadWriteCtrl = DmaWrCmd | DmaRdCmd | DmaWrBdry | DmaRdBdry;
2293    /* Program DMA Read/Write */
2294    if (pDevice->Flags & PCI_EXPRESS_FLAG)
2295    {
2296        pDevice->DmaReadWriteCtrl |= 0x001f0000;
2297    }
2298    else if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
2299    {
2300        if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2301        {
2302            pDevice->DmaReadWriteCtrl |= 0x003f0000;
2303        }
2304        else
2305        {
2306            pDevice->DmaReadWriteCtrl |= 0x003f000f;
2307        }
2308    }
2309    else
2310    {
2311        if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2312            (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
2313        {
2314            /* set bit 23 to enable a PCIX hardware fix */
2315            pDevice->DmaReadWriteCtrl |= 0x009f0000;
2316
2317            Value32 = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
2318            if ((Value32 == 0x6) || (Value32 == 0x7))
2319            {
2320                pDevice->Flags |= ONE_DMA_AT_ONCE_FLAG;
2321            }
2322        }
2323        else
2324        {
2325            pDevice->DmaReadWriteCtrl |= 0x001b000f;
2326        }
2327    }
2328    if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2329        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
2330    {
2331        pDevice->DmaReadWriteCtrl &= 0xfffffff0;
2332    }
2333
2334    if (pDevice->Flags & ONE_DMA_AT_ONCE_FLAG)
2335    {
2336        pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
2337    }
2338    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2339
2340    LM_SwitchClocks(pDevice);
2341
2342    if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
2343    {
2344        return LM_STATUS_FAILURE;
2345    }
2346
2347    /* Status block. */
2348    pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
2349    pDevice->StatusBlkPhy = MemPhy;
2350    pMemVirt += T3_STATUS_BLOCK_SIZE;
2351    LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
2352
2353    /* Statistics block. */
2354    pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
2355    pDevice->StatsBlkPhy = MemPhy;
2356    pMemVirt += sizeof(T3_STATS_BLOCK);
2357    LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
2358
2359    /* Receive standard BD buffer. */
2360    pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
2361    pDevice->RxStdBdPhy = MemPhy;
2362
2363    pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
2364    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2365        T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
2366
2367#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2368    /* Receive jumbo BD buffer. */
2369    pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
2370    pDevice->RxJumboBdPhy = MemPhy;
2371
2372    pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
2373    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2374        T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
2375#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2376
2377    /* Receive return BD buffer. */
2378    pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
2379    pDevice->RcvRetBdPhy = MemPhy;
2380
2381    pMemVirt += pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD);
2382    LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2383        pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
2384
2385    /* Set up Send BD. */
2386    if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2387    {
2388        pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
2389        pDevice->SendBdPhy = MemPhy;
2390
2391        pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
2392        LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2393            sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
2394    }
2395#ifdef BCM_NIC_SEND_BD
2396    else
2397    {
2398        pDevice->pSendBdVirt = (PT3_SND_BD)
2399            pDevice->pMemView->uIntMem.First32k.BufferDesc;
2400        pDevice->SendBdPhy.High = 0;
2401        pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
2402    }
2403#endif
2404
2405    /* Allocate memory for packet descriptors. */
2406    Size = (pDevice->RxPacketDescCnt +
2407        pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
2408    Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
2409    if(Status != LM_STATUS_SUCCESS)
2410    {
2411        return Status;
2412    }
2413    pDevice->pPacketDescBase = (PLM_VOID) pPacket;
2414
2415    /* Create transmit packet descriptors from the memory block and add them */
2416    /* to the TxPacketFreeQ for each send ring. */
2417    for(j = 0; j < pDevice->TxPacketDescCnt; j++)
2418    {
2419        /* Ring index. */
2420        pPacket->Flags = 0;
2421
2422        /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
2423        QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
2424
2425        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
2426        /* is the total size of the packet descriptor including the */
2427        /* os-specific extensions in the UM_PACKET structure. */
2428        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2429    } /* for(j.. */
2430
2431    /* Create receive packet descriptors from the memory block and add them */
2432    /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
2433    for(j = 0; j < pDevice->RxStdDescCnt; j++)
2434    {
2435        /* Receive producer ring. */
2436        pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
2437
2438        /* Receive buffer size. */
2439        pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
2440
2441        /* Add the descriptor to RxPacketFreeQ. */
2442        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
2443
2444        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
2445        /* is the total size of the packet descriptor including the */
2446        /* os-specific extensions in the UM_PACKET structure. */
2447        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2448    } /* for */
2449
2450#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2451    /* Create the Jumbo packet descriptors. */
2452    for(j = 0; j < pDevice->RxJumboDescCnt; j++)
2453    {
2454        /* Receive producer ring. */
2455        pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
2456
2457        /* Receive buffer size. */
2458        pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
2459
2460        /* Add the descriptor to RxPacketFreeQ. */
2461        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
2462
2463        /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
2464        /* is the total size of the packet descriptor including the */
2465        /* os-specific extensions in the UM_PACKET structure. */
2466        pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2467    } /* for */
2468#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2469
2470    /* Initialize the rest of the packet descriptors. */
2471    Status = MM_InitializeUmPackets(pDevice);
2472    if(Status != LM_STATUS_SUCCESS)
2473    {
2474        return Status;
2475    } /* if */
2476
2477    /* Default receive mask. */
2478    pDevice->ReceiveMask &= LM_KEEP_VLAN_TAG;
2479    pDevice->ReceiveMask |= LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
2480        LM_ACCEPT_UNICAST;
2481
2482    /* Make sure we are in the first 32k memory window or NicSendBd. */
2483    REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
2484
2485    /* Initialize the hardware. */
2486    Status = LM_ResetAdapter(pDevice);
2487    if(Status != LM_STATUS_SUCCESS)
2488    {
2489        return Status;
2490    }
2491
2492    /* We are done with initialization. */
2493    pDevice->InitDone = TRUE;
2494
2495    return LM_STATUS_SUCCESS;
2496} /* LM_InitializeAdapter */
2497
2498
2499LM_STATUS
2500LM_DisableChip(PLM_DEVICE_BLOCK pDevice)
2501{
2502    LM_UINT32 data;
2503
2504    pDevice->RxMode &= ~RX_MODE_ENABLE;
2505    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2506    if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
2507    {
2508        MM_Wait(20);
2509    }
2510    data = REG_RD(pDevice, RcvBdIn.Mode);
2511    data &= ~RCV_BD_IN_MODE_ENABLE;
2512    REG_WR(pDevice, RcvBdIn.Mode,data);
2513    if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
2514    {
2515        MM_Wait(20);
2516    }
2517    data = REG_RD(pDevice, RcvListPlmt.Mode);
2518    data &= ~RCV_LIST_PLMT_MODE_ENABLE;
2519    REG_WR(pDevice, RcvListPlmt.Mode,data);
2520    if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
2521    {
2522        MM_Wait(20);
2523    }
2524    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2525    {
2526        data = REG_RD(pDevice, RcvListSel.Mode);
2527        data &= ~RCV_LIST_SEL_MODE_ENABLE;
2528        REG_WR(pDevice, RcvListSel.Mode,data);
2529        if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
2530        {
2531            MM_Wait(20);
2532        }
2533    }
2534    data = REG_RD(pDevice, RcvDataBdIn.Mode);
2535    data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
2536    REG_WR(pDevice, RcvDataBdIn.Mode,data);
2537    if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
2538    {
2539        MM_Wait(20);
2540    }
2541    data = REG_RD(pDevice, RcvDataComp.Mode);
2542    data &= ~RCV_DATA_COMP_MODE_ENABLE;
2543    REG_WR(pDevice, RcvDataComp.Mode,data);
2544    if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
2545    {
2546        MM_Wait(20);
2547    }
2548    data = REG_RD(pDevice, RcvBdComp.Mode);
2549    data &= ~RCV_BD_COMP_MODE_ENABLE;
2550    REG_WR(pDevice, RcvBdComp.Mode,data);
2551    if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
2552    {
2553        MM_Wait(20);
2554    }
2555    data = REG_RD(pDevice, SndBdSel.Mode);
2556    data &= ~SND_BD_SEL_MODE_ENABLE;
2557    REG_WR(pDevice, SndBdSel.Mode, data);
2558    if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
2559    {
2560        MM_Wait(20);
2561    }
2562    data = REG_RD(pDevice, SndBdIn.Mode);
2563    data &= ~SND_BD_IN_MODE_ENABLE;
2564    REG_WR(pDevice, SndBdIn.Mode, data);
2565    if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
2566    {
2567        MM_Wait(20);
2568    }
2569    data = REG_RD(pDevice, SndDataIn.Mode);
2570    data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2571    REG_WR(pDevice, SndDataIn.Mode,data);
2572    if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
2573    {
2574        MM_Wait(20);
2575    }
2576    data = REG_RD(pDevice, DmaRead.Mode);
2577    data &= ~DMA_READ_MODE_ENABLE;
2578    REG_WR(pDevice, DmaRead.Mode, data);
2579    if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
2580    {
2581        MM_Wait(20);
2582    }
2583    data = REG_RD(pDevice, SndDataComp.Mode);
2584    data &= ~SND_DATA_COMP_MODE_ENABLE;
2585    REG_WR(pDevice, SndDataComp.Mode, data);
2586    if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
2587    {
2588        MM_Wait(20);
2589    }
2590    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2591    {
2592        data = REG_RD(pDevice,DmaComp.Mode);
2593        data &= ~DMA_COMP_MODE_ENABLE;
2594        REG_WR(pDevice, DmaComp.Mode, data);
2595        if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
2596        {
2597            MM_Wait(20);
2598        }
2599    }
2600    data = REG_RD(pDevice, SndBdComp.Mode);
2601    data &= ~SND_BD_COMP_MODE_ENABLE;
2602    REG_WR(pDevice, SndBdComp.Mode, data);
2603    if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
2604    {
2605        MM_Wait(20);
2606    }
2607    /* Clear TDE bit */
2608    pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
2609    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
2610    pDevice->TxMode &= ~TX_MODE_ENABLE;
2611    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2612    if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
2613    {
2614        MM_Wait(20);
2615    }
2616    data = REG_RD(pDevice, HostCoalesce.Mode);
2617    data &= ~HOST_COALESCE_ENABLE;
2618    REG_WR(pDevice, HostCoalesce.Mode, data);
2619    if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
2620    {
2621        MM_Wait(20);
2622    }
2623    data = REG_RD(pDevice, DmaWrite.Mode);
2624    data &= ~DMA_WRITE_MODE_ENABLE;
2625    REG_WR(pDevice, DmaWrite.Mode,data);
2626    if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
2627    {
2628        MM_Wait(20);
2629    }
2630    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2631    {
2632        data = REG_RD(pDevice, MbufClusterFree.Mode);
2633        data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
2634        REG_WR(pDevice, MbufClusterFree.Mode,data);
2635        if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
2636        {
2637            MM_Wait(20);
2638        }
2639    }
2640    /* Reset all FTQs */
2641    REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2642    REG_WR(pDevice, Ftq.Reset, 0x0);
2643
2644    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2645    {
2646        data = REG_RD(pDevice, BufMgr.Mode);
2647        data &= ~BUFMGR_MODE_ENABLE;
2648        REG_WR(pDevice, BufMgr.Mode,data);
2649        if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
2650        {
2651            MM_Wait(20);
2652        }
2653        data = REG_RD(pDevice, MemArbiter.Mode);
2654        data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2655        REG_WR(pDevice, MemArbiter.Mode, data);
2656        if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
2657        {
2658            MM_Wait(20);
2659        }
2660    }
2661    return LM_STATUS_SUCCESS;
2662}
2663
2664LM_STATUS
2665LM_DisableFW(PLM_DEVICE_BLOCK pDevice)
2666{
2667#ifdef BCM_ASF
2668    int j;
2669    LM_UINT32 Value32;
2670
2671    if (pDevice->AsfFlags & ASF_ENABLED)
2672    {
2673        MEM_WR_OFFSET(pDevice, T3_CMD_MAILBOX, T3_CMD_NICDRV_PAUSE_FW);
2674        Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
2675        REG_WR(pDevice, Grc.RxCpuEvent, Value32 | BIT_14);
2676        for (j = 0; j < 100; j++)
2677        {
2678            Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
2679            if (!(Value32 & BIT_14))
2680            {
2681                break;
2682            }
2683            MM_Wait(1);
2684        }
2685    }
2686#endif
2687    return LM_STATUS_SUCCESS;
2688}
2689
2690/******************************************************************************/
2691/* Description:                                                               */
2692/*    This function reinitializes the adapter.                                */
2693/*                                                                            */
2694/* Return:                                                                    */
2695/*    LM_STATUS_SUCCESS                                                       */
2696/******************************************************************************/
2697LM_STATUS
2698LM_ResetAdapter(
2699PLM_DEVICE_BLOCK pDevice)
2700{
2701    LM_UINT32 Value32;
2702    LM_UINT32 j, k;
2703    int reset_count = 0;
2704
2705    /* Disable interrupt. */
2706    LM_DisableInterrupt(pDevice);
2707
2708restart_reset:
2709    LM_DisableFW(pDevice);
2710
2711    /* May get a spurious interrupt */
2712    pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2713
2714    LM_WritePreResetSignatures(pDevice, LM_INIT_RESET);
2715    /* Disable transmit and receive DMA engines.  Abort all pending requests. */
2716    if(pDevice->InitDone)
2717    {
2718        LM_Abort(pDevice);
2719    }
2720
2721    pDevice->ShuttingDown = FALSE;
2722
2723    LM_ResetChip(pDevice);
2724
2725    LM_WriteLegacySignatures(pDevice, LM_INIT_RESET);
2726
2727    /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
2728    /* in other chip revisions except 5750 */
2729    if ((pDevice->Flags & DELAY_PCI_GRANT_FLAG) &&
2730        !(pDevice->Flags & PCI_EXPRESS_FLAG))
2731    {
2732        REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | BIT_31);
2733    }
2734
2735    if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2736    {
2737        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2738        {
2739            Value32 = REG_RD(pDevice, PciCfg.PciState);
2740            Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2741            REG_WR(pDevice, PciCfg.PciState, Value32);
2742        }
2743    }
2744    if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_BX)
2745    {
2746        /* New bits defined in register 0x64 to enable some h/w fixes */
2747        /* These new bits are 'write-only' */
2748        Value32 = REG_RD(pDevice, PciCfg.MsiData);
2749        REG_WR(pDevice, PciCfg.MsiData, Value32 | BIT_26 | BIT_28 | BIT_29);
2750    }
2751
2752    /* Enable TaggedStatus mode. */
2753    if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
2754    {
2755        pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2756    }
2757
2758    /* Restore PCI configuration registers. */
2759    MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
2760        pDevice->SavedCacheLineReg);
2761//    LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2762//        (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2763    MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2764        (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2765
2766    /* Initialize the statistis Block */
2767    pDevice->pStatusBlkVirt->Status = 0;
2768    pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2769    pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2770    pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2771
2772    for(j = 0; j < 16; j++)
2773    {
2774       pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2775       pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2776    }
2777
2778    for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
2779    {
2780       pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2781       pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2782       pDevice->pRxStdBdVirt[k].Flags = RCV_BD_FLAG_END;
2783       pDevice->pRxStdBdVirt[k].Len = MAX_STD_RCV_BUFFER_SIZE;
2784    }
2785
2786#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2787    /* Receive jumbo BD buffer. */
2788    for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
2789    {
2790        pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2791        pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2792        pDevice->pRxJumboBdVirt[k].Flags = RCV_BD_FLAG_END |
2793            RCV_BD_FLAG_JUMBO_RING;
2794        pDevice->pRxJumboBdVirt[k].Len = (LM_UINT16) pDevice->RxJumboBufferSize;
2795    }
2796#endif
2797
2798    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2799
2800    /* GRC mode control register. */
2801    Value32 =
2802#ifdef BIG_ENDIAN_HOST
2803        GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2804        GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2805        GRC_MODE_BYTE_SWAP_DATA |
2806        GRC_MODE_WORD_SWAP_DATA |
2807#else
2808        GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2809        GRC_MODE_BYTE_SWAP_DATA |
2810        GRC_MODE_WORD_SWAP_DATA |
2811#endif
2812        GRC_MODE_INT_ON_MAC_ATTN |
2813        GRC_MODE_HOST_STACK_UP;
2814
2815    /* Configure send BD mode. */
2816    if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2817    {
2818        Value32 |= GRC_MODE_HOST_SEND_BDS;
2819    }
2820#ifdef BCM_NIC_SEND_BD
2821    else
2822    {
2823        Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2824    }
2825#endif
2826
2827    /* Configure pseudo checksum mode. */
2828    if (pDevice->Flags & NO_TX_PSEUDO_HDR_CSUM_FLAG)
2829    {
2830        Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2831    }
2832
2833    if (pDevice->Flags & NO_RX_PSEUDO_HDR_CSUM_FLAG)
2834    {
2835        Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2836    }
2837
2838    pDevice->GrcMode = Value32;
2839    REG_WR(pDevice, Grc.Mode, Value32);
2840
2841    /* Setup the timer prescalar register. */
2842    Value32 = REG_RD(pDevice, Grc.MiscCfg) & ~0xff;
2843    /* Clock is always 66Mhz. */
2844    REG_WR(pDevice, Grc.MiscCfg, Value32 | (65 << 1));
2845
2846    /* Set up the MBUF pool base address and size. */
2847    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
2848    {
2849#if INCLUDE_TCP_SEG_SUPPORT
2850        if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
2851        {
2852            Value32 = LM_GetStkOffLdFirmwareSize(pDevice);
2853            Value32 = (Value32 + 0x7f) & ~0x7f;
2854            pDevice->MbufBase = T3_NIC_BCM5705_MBUF_POOL_ADDR + Value32;
2855            pDevice->MbufSize = T3_NIC_BCM5705_MBUF_POOL_SIZE - Value32 - 0xa00;
2856            REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2857            REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2858        }
2859#endif
2860    }
2861    else if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
2862    {
2863        REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2864        REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2865
2866        /* Set up the DMA descriptor pool base address and size. */
2867        REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2868        REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2869
2870    }
2871
2872    /* Configure MBUF and Threshold watermarks */
2873    /* Configure the DMA read MBUF low water mark. */
2874    if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2875    {
2876        if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2877        {
2878            REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2879                T3_DEF_DMA_MBUF_LOW_WMARK_5705);
2880            REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2881                T3_DEF_RX_MAC_MBUF_LOW_WMARK_5705);
2882            REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2883                T3_DEF_MBUF_HIGH_WMARK_5705);
2884        }
2885        else
2886        {
2887            REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2888                T3_DEF_DMA_MBUF_LOW_WMARK);
2889            REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2890                T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2891            REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2892                T3_DEF_MBUF_HIGH_WMARK);
2893        }
2894    }
2895    else
2896    {
2897        REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2898            T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2899        REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2900            T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2901        REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2902            T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2903    }
2904
2905    REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2906    REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2907
2908    /* Enable buffer manager. */
2909    REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2910
2911    for(j = 0 ;j < 2000; j++)
2912    {
2913        if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2914            break;
2915        MM_Wait(10);
2916    }
2917
2918    if(j >= 2000)
2919    {
2920        return LM_STATUS_FAILURE;
2921    }
2922
2923/* GRC reset will reset FTQ */
2924#if 0
2925    /* Enable the FTQs. */
2926    REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2927    REG_WR(pDevice, Ftq.Reset, 0);
2928
2929    /* Wait until FTQ is ready */
2930    for(j = 0; j < 2000; j++)
2931    {
2932        if(REG_RD(pDevice, Ftq.Reset) == 0)
2933            break;
2934        MM_Wait(10);
2935    }
2936
2937    if(j >= 2000)
2938    {
2939        return LM_STATUS_FAILURE;
2940    }
2941#endif
2942
2943    /* Receive BD Ring replenish threshold. */
2944    REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
2945
2946    /* Initialize the Standard Receive RCB. */
2947    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2948        pDevice->RxStdBdPhy.High);
2949    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2950        pDevice->RxStdBdPhy.Low);
2951    REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2952        (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2953
2954    if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2955    {
2956        REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2957            512 << 16);
2958    }
2959    else
2960    {
2961        REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2962            MAX_STD_RCV_BUFFER_SIZE << 16);
2963
2964        /* Initialize the Jumbo Receive RCB. */
2965        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2966            T3_RCB_FLAG_RING_DISABLED);
2967#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2968        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2969            pDevice->RxJumboBdPhy.High);
2970        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2971            pDevice->RxJumboBdPhy.Low);
2972        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2973        REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2974            (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2975
2976        REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
2977
2978#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2979
2980        /* Initialize the Mini Receive RCB. */
2981        REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2982            T3_RCB_FLAG_RING_DISABLED);
2983
2984        /* Disable all the unused rings. */
2985        for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2986            MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags,
2987                T3_RCB_FLAG_RING_DISABLED);
2988        } /* for */
2989
2990    }
2991
2992    /* Initialize the indices. */
2993    pDevice->SendProdIdx = 0;
2994    pDevice->SendConIdx = 0;
2995
2996    MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2997    MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
2998    MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2999    MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
3000
3001    /* Set up host or NIC based send RCB. */
3002    if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3003    {
3004        MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
3005            pDevice->SendBdPhy.High);
3006        MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
3007            pDevice->SendBdPhy.Low);
3008
3009        /* Setup the RCB. */
3010        MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
3011            T3_SEND_RCB_ENTRY_COUNT << 16);
3012
3013        if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3014        {
3015            /* Set up the NIC ring address in the RCB. */
3016            MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
3017        }
3018        for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
3019        {
3020            pDevice->pSendBdVirt[k].HostAddr.High = 0;
3021            pDevice->pSendBdVirt[k].HostAddr.Low = 0;
3022        }
3023    }
3024#ifdef BCM_NIC_SEND_BD
3025    else
3026    {
3027        MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
3028        MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
3029        MEM_WR(pDevice, SendRcb[0].NicRingAddr,
3030            pDevice->SendBdPhy.Low);
3031
3032        for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
3033        {
3034            MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.High), 0);
3035            MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.Low), 0);
3036            MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].u1.Len_Flags), 0);
3037            pDevice->ShadowSendBd[k].HostAddr.High = 0;
3038            pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
3039        }
3040    }
3041#endif
3042    MM_ATOMIC_SET(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
3043
3044    /* Configure the receive return rings. */
3045    for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
3046    {
3047        MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
3048    }
3049
3050    pDevice->RcvRetConIdx = 0;
3051
3052    MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
3053        pDevice->RcvRetBdPhy.High);
3054    MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
3055        pDevice->RcvRetBdPhy.Low);
3056
3057    MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
3058
3059    /* Setup the RCB. */
3060    MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
3061        pDevice->RcvRetRcbEntryCount << 16);
3062
3063    /* Reinitialize RX ring producer index */
3064    MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
3065    MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
3066    MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
3067    MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
3068    MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
3069    MB_REG_RD(pDevice, Mailbox.RcvMiniProdIdx.Low);
3070
3071#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3072    pDevice->RxJumboProdIdx = 0;
3073    pDevice->RxJumboQueuedCnt = 0;
3074#endif
3075
3076    /* Reinitialize our copy of the indices. */
3077    pDevice->RxStdProdIdx = 0;
3078    pDevice->RxStdQueuedCnt = 0;
3079
3080#if T3_JUMBO_RCV_ENTRY_COUNT
3081    pDevice->RxJumboProdIdx = 0;
3082#endif /* T3_JUMBO_RCV_ENTRY_COUNT */
3083
3084    /* Configure the MAC address. */
3085    LM_SetMacAddress(pDevice, pDevice->NodeAddress);
3086
3087    /* Initialize the transmit random backoff seed. */
3088    Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
3089        pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
3090        pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
3091        MAC_TX_BACKOFF_SEED_MASK;
3092    REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
3093
3094    /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
3095    REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);   /* CRC + VLAN. */
3096
3097    /* Configure Time slot/IPG per 802.3 */
3098    REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
3099
3100    /*
3101     * Configure Receive Rules so that packets don't match
3102     * Programmble rule will be queued to Return Ring 1
3103     */
3104    REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
3105
3106    /*
3107     * Configure to have 16 Classes of Services (COS) and one
3108     * queue per class.  Bad frames are queued to RRR#1.
3109     * And frames don't match rules are also queued to COS#1.
3110     */
3111    REG_WR(pDevice, RcvListPlmt.Config, 0x181);
3112
3113    /* Enable Receive Placement Statistics */
3114    if ((pDevice->DmaReadFifoSize == DMA_READ_MODE_FIFO_LONG_BURST) &&
3115        (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION))
3116    {
3117        Value32 = REG_RD(pDevice, RcvListPlmt.StatsEnableMask);
3118        Value32 &= ~T3_DISABLE_LONG_BURST_READ_DYN_FIX;
3119        REG_WR(pDevice, RcvListPlmt.StatsEnableMask, Value32);
3120    }
3121    else
3122    {
3123        REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
3124    }
3125    REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
3126
3127    /* Enable Send Data Initator Statistics */
3128    REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
3129    REG_WR(pDevice, SndDataIn.StatsCtrl,
3130        T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
3131        T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
3132
3133    /* Disable the host coalescing state machine before configuring it's */
3134    /* parameters. */
3135    REG_WR(pDevice, HostCoalesce.Mode, 0);
3136    for(j = 0; j < 2000; j++)
3137    {
3138        Value32 = REG_RD(pDevice, HostCoalesce.Mode);
3139        if(!(Value32 & HOST_COALESCE_ENABLE))
3140        {
3141            break;
3142        }
3143        MM_Wait(10);
3144    }
3145
3146    /* Host coalescing configurations. */
3147    REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
3148    REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
3149    REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
3150        pDevice->RxMaxCoalescedFrames);
3151    REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
3152        pDevice->TxMaxCoalescedFrames);
3153    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3154    {
3155        REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
3156            pDevice->RxCoalescingTicksDuringInt);
3157        REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
3158            pDevice->TxCoalescingTicksDuringInt);
3159    }
3160    REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
3161        pDevice->RxMaxCoalescedFramesDuringInt);
3162    REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
3163        pDevice->TxMaxCoalescedFramesDuringInt);
3164
3165    /* Initialize the address of the status block.  The NIC will DMA */
3166    /* the status block to this memory which resides on the host. */
3167    REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
3168        pDevice->StatusBlkPhy.High);
3169    REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
3170        pDevice->StatusBlkPhy.Low);
3171
3172    /* Initialize the address of the statistics block.  The NIC will DMA */
3173    /* the statistics to this block of memory. */
3174    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3175    {
3176        REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
3177            pDevice->StatsBlkPhy.High);
3178        REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
3179            pDevice->StatsBlkPhy.Low);
3180
3181        REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
3182            pDevice->StatsCoalescingTicks);
3183
3184        REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
3185        REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
3186    }
3187
3188    /* Enable Host Coalesing state machine */
3189    REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
3190        pDevice->CoalesceMode);
3191
3192    /* Enable the Receive BD Completion state machine. */
3193    REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
3194        RCV_BD_COMP_MODE_ATTN_ENABLE);
3195
3196    /* Enable the Receive List Placement state machine. */
3197    REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
3198
3199    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3200    {
3201        /* Enable the Receive List Selector state machine. */
3202        REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
3203            RCV_LIST_SEL_MODE_ATTN_ENABLE);
3204    }
3205
3206    /* Clear the statistics block. */
3207    for(j = 0x0300; j < 0x0b00; j = j + 4)
3208    {
3209        MEM_WR_OFFSET(pDevice, j, 0);
3210    }
3211
3212    /* Enable transmit DMA, clear statistics. */
3213    pDevice->MacMode =  MAC_MODE_ENABLE_TX_STATISTICS |
3214        MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
3215        MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
3216    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
3217        MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
3218
3219    /* GRC miscellaneous local control register. */
3220    pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
3221        GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
3222
3223    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3224    {
3225        pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
3226            GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
3227    }
3228    else if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) &&
3229        !(pDevice->Flags & EEPROM_WP_FLAG))
3230    {
3231        /* Make sure we're on Vmain */
3232        /* The other port may cause us to be on Vaux */
3233        pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
3234            GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2;
3235    }
3236
3237    RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
3238    MM_Wait(40);
3239
3240    /* Reset RX counters. */
3241    for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
3242    {
3243        ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
3244    }
3245
3246    /* Reset TX counters. */
3247    for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
3248    {
3249        ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
3250    }
3251
3252    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
3253    MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3254    pDevice->LastTag = 0;
3255
3256    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3257    {
3258        /* Enable the DMA Completion state machine. */
3259        REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
3260    }
3261
3262    /* Enable the DMA Write state machine. */
3263    Value32 = DMA_WRITE_MODE_ENABLE |
3264        DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
3265        DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
3266        DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
3267        DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
3268        DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
3269        DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
3270        DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
3271        DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
3272
3273    if (pDevice->Flags & DMA_WR_MODE_RX_ACCELERATE_FLAG)
3274    {
3275        Value32 |= DMA_WRITE_MODE_RECEIVE_ACCELERATE;
3276    }
3277    REG_WR(pDevice, DmaWrite.Mode, Value32);
3278
3279    if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
3280    {
3281        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
3282        {
3283            Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
3284            Value32 &= ~PCIX_CMD_MAX_BURST_MASK;
3285            Value32 |= PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL;
3286            REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
3287        }
3288        else if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3289        {
3290            Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
3291            Value32 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
3292            Value32 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
3293                PCIX_CMD_MAX_BURST_MASK);
3294            if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
3295            {
3296                Value32 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
3297                   & PCIX_CMD_MAX_SPLIT_MASK;
3298            }
3299            REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
3300        }
3301    }
3302
3303    /* Enable the Read DMA state machine. */
3304    Value32 = DMA_READ_MODE_ENABLE |
3305        DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
3306        DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
3307        DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
3308        DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
3309        DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
3310        DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
3311        DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
3312        DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
3313
3314    if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
3315    {
3316        Value32 |= DMA_READ_MODE_MULTI_SPLIT_ENABLE;
3317    }
3318
3319    if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3320    {
3321        Value32 |= pDevice->DmaReadFifoSize;
3322    }
3323#if INCLUDE_TCP_SEG_SUPPORT
3324    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3325    {
3326        Value32 |= BIT_27;
3327    }
3328#endif
3329
3330
3331    REG_WR(pDevice, DmaRead.Mode, Value32);
3332
3333    /* Enable the Receive Data Completion state machine. */
3334    REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
3335        RCV_DATA_COMP_MODE_ATTN_ENABLE);
3336
3337    if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3338    {
3339        /* Enable the Mbuf Cluster Free state machine. */
3340        REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
3341    }
3342
3343    /* Enable the Send Data Completion state machine. */
3344    REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
3345
3346    /* Enable the Send BD Completion state machine. */
3347    REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
3348        SND_BD_COMP_MODE_ATTN_ENABLE);
3349
3350    /* Enable the Receive BD Initiator state machine. */
3351    REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
3352        RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
3353
3354    /* Enable the Receive Data and Receive BD Initiator state machine. */
3355    REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
3356        RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
3357
3358    /* Enable the Send Data Initiator state machine. */
3359    REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
3360
3361#if INCLUDE_TCP_SEG_SUPPORT
3362    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3363    {
3364        REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE | 0x8);
3365    }
3366#endif
3367
3368    /* Enable the Send BD Initiator state machine. */
3369    REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
3370        SND_BD_IN_MODE_ATTN_ENABLE);
3371
3372    /* Enable the Send BD Selector state machine. */
3373    REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
3374        SND_BD_SEL_MODE_ATTN_ENABLE);
3375
3376#if INCLUDE_5701_AX_FIX
3377    /* Load the firmware for the 5701_A0 workaround. */
3378    if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
3379    {
3380        LM_LoadRlsFirmware(pDevice);
3381    }
3382#endif
3383
3384    /* Queue Rx packet buffers. */
3385    if(pDevice->QueueRxPackets)
3386    {
3387        LM_QueueRxPackets(pDevice);
3388    }
3389
3390    if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
3391    {
3392        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
3393        j = 0;
3394        while ((Value32 != MAX_STD_RCV_BUFFER_SIZE) && (j < 10))
3395        {
3396            MM_Wait(20);
3397            Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
3398            j++;
3399        }
3400        if (j >= 10)
3401        {
3402            reset_count++;
3403            LM_Abort(pDevice);
3404            if (reset_count > 5)
3405                return LM_STATUS_FAILURE;
3406            goto restart_reset;
3407        }
3408    }
3409
3410    /* Enable the transmitter. */
3411    pDevice->TxMode = TX_MODE_ENABLE;
3412    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
3413
3414    /* Enable the receiver. */
3415    pDevice->RxMode = (pDevice->RxMode & RX_MODE_KEEP_VLAN_TAG) |
3416        RX_MODE_ENABLE;
3417    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
3418
3419#ifdef BCM_WOL
3420    if (pDevice->RestoreOnWakeUp)
3421    {
3422        pDevice->RestoreOnWakeUp = FALSE;
3423        pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
3424        pDevice->RequestedLineSpeed = pDevice->WakeUpRequestedLineSpeed;
3425        pDevice->RequestedDuplexMode = pDevice->WakeUpRequestedDuplexMode;
3426    }
3427#endif
3428
3429    /* Disable auto polling. */
3430    pDevice->MiMode = 0xc0000;
3431    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
3432
3433    REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
3434
3435    /* Activate Link to enable MAC state machine */
3436    REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
3437
3438    if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
3439    {
3440        REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
3441        REG_RD_BACK(pDevice, MacCtrl.RxMode);
3442        MM_Wait(10);
3443        REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
3444        if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
3445        {
3446            REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
3447        }
3448        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3449        {
3450            /* Set SerDes drive transmission level to 1.2V */
3451            Value32 = REG_RD(pDevice, MacCtrl.SerdesCfg) & 0xfffff000;
3452            REG_WR(pDevice, MacCtrl.SerdesCfg, Value32 | 0x880);
3453        }
3454    }
3455
3456    REG_WR(pDevice, MacCtrl.LowWaterMarkMaxRxFrame, 2);
3457
3458    if (!pDevice->InitDone)
3459    {
3460        pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
3461    }
3462
3463    if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
3464        ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5401_PHY_ID))
3465    {
3466        /* 5401 PHY needs a delay of about 1 second after PHY reset */
3467        /* Without the delay, it has problem linking at forced 10 half */
3468        /* So skip the reset... */
3469        LM_ResetPhy(pDevice);
3470    }
3471
3472    /* Setup the phy chip. */
3473    LM_SetupPhy(pDevice);
3474
3475    if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG)) {
3476        /* Clear CRC stats */
3477        LM_ReadPhy(pDevice, 0x1e, &Value32);
3478        LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
3479        LM_ReadPhy(pDevice, 0x14, &Value32);
3480    }
3481
3482    /* Set up the receive mask. */
3483    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
3484
3485#if INCLUDE_TCP_SEG_SUPPORT
3486    if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
3487    {
3488        if (LM_LoadStkOffLdFirmware(pDevice) == LM_STATUS_FAILURE)
3489        {
3490            return LM_STATUS_FAILURE;
3491        }
3492    }
3493#endif
3494    LM_WritePostResetSignatures(pDevice, LM_INIT_RESET);
3495
3496    return LM_STATUS_SUCCESS;
3497} /* LM_ResetAdapter */
3498
3499
3500/******************************************************************************/
3501/* Description:                                                               */
3502/*    This routine disables the adapter from generating interrupts.           */
3503/*                                                                            */
3504/* Return:                                                                    */
3505/*    LM_STATUS_SUCCESS                                                       */
3506/******************************************************************************/
3507LM_STATUS
3508LM_DisableInterrupt(
3509    PLM_DEVICE_BLOCK pDevice)
3510{
3511    REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
3512        MISC_HOST_CTRL_MASK_PCI_INT);
3513    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
3514    if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3515    {
3516        MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3517    }
3518
3519    return LM_STATUS_SUCCESS;
3520}
3521
3522
3523
3524/******************************************************************************/
3525/* Description:                                                               */
3526/*    This routine enables the adapter to generate interrupts.                */
3527/*                                                                            */
3528/* Return:                                                                    */
3529/*    LM_STATUS_SUCCESS                                                       */
3530/******************************************************************************/
3531LM_STATUS
3532LM_EnableInterrupt(
3533    PLM_DEVICE_BLOCK pDevice)
3534{
3535    MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, pDevice->LastTag << 24);
3536    if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3537    {
3538        MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3539    }
3540
3541    REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
3542        ~MISC_HOST_CTRL_MASK_PCI_INT);
3543
3544    REG_WR(pDevice, HostCoalesce.Mode, pDevice->CoalesceMode |
3545        HOST_COALESCE_ENABLE | HOST_COALESCE_NOW);
3546
3547    return LM_STATUS_SUCCESS;
3548}
3549
3550
3551
3552/******************************************************************************/
3553/* Description:                                                               */
3554/*    This routine puts a packet on the wire if there is a transmit DMA       */
3555/*    descriptor available; otherwise the packet is queued for later          */
3556/*    transmission.  If the second argue is NULL, this routine will put       */
3557/*    the queued packet on the wire if possible.                              */
3558/*                                                                            */
3559/* Return:                                                                    */
3560/*    LM_STATUS_SUCCESS                                                       */
3561/******************************************************************************/
3562LM_STATUS
3563LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3564{
3565    LM_UINT32 FragCount;
3566    PT3_SND_BD pSendBd, pTmpSendBd;
3567#ifdef BCM_NIC_SEND_BD
3568    PT3_SND_BD pShadowSendBd;
3569    T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
3570#endif
3571    LM_UINT32 StartIdx, Idx;
3572
3573    while (1)
3574    {
3575        /* Initalize the send buffer descriptors. */
3576        StartIdx = Idx = pDevice->SendProdIdx;
3577
3578#ifdef BCM_NIC_SEND_BD
3579        if (pDevice->Flags & NIC_SEND_BD_FLAG)
3580        {
3581            pTmpSendBd = pSendBd = &NicSendBdArr[0];
3582        }
3583        else
3584#endif
3585        {
3586            pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
3587        }
3588
3589        /* Next producer index. */
3590        for(FragCount = 0; ; )
3591        {
3592            LM_UINT32 Value32, Len;
3593
3594            /* Initialize the pointer to the send buffer fragment. */
3595            MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3596
3597            pSendBd->u2.VlanTag = pPacket->VlanTag;
3598
3599            /* Setup the control flags and send buffer size. */
3600            Value32 = (Len << 16) | pPacket->Flags;
3601
3602#if INCLUDE_TCP_SEG_SUPPORT
3603            if (Value32 & (SND_BD_FLAG_CPU_PRE_DMA | SND_BD_FLAG_CPU_POST_DMA))
3604            {
3605                if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3606                {
3607                    pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
3608                }
3609		else if (FragCount == 0)
3610                {
3611                    pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
3612                }
3613                else
3614                {
3615                    pSendBd->u2.s2.Reserved = 0;
3616                    Value32 &= 0xffff0fff;
3617                }
3618            }
3619#endif
3620            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3621
3622            FragCount++;
3623            if (FragCount >= pPacket->u.Tx.FragCount)
3624            {
3625                pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3626                break;
3627            }
3628            else
3629            {
3630                pSendBd->u1.Len_Flags = Value32;
3631            }
3632
3633            pSendBd++;
3634            if ((Idx == 0) &&
3635                !(pDevice->Flags & NIC_SEND_BD_FLAG))
3636            {
3637                pSendBd = &pDevice->pSendBdVirt[0];
3638            }
3639
3640            pDevice->SendRing[Idx] = 0;
3641
3642        } /* for */
3643        if (pDevice->Flags & TX_4G_WORKAROUND_FLAG)
3644        {
3645            if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
3646                LM_STATUS_SUCCESS)
3647            {
3648                if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
3649                {
3650                    QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
3651                    return LM_STATUS_FAILURE;
3652                }
3653                continue;
3654            }
3655        }
3656        break;
3657    }
3658    /* Put the packet descriptor in the ActiveQ. */
3659    pDevice->SendRing[StartIdx] = pPacket;
3660
3661#ifdef BCM_NIC_SEND_BD
3662    if (pDevice->Flags & NIC_SEND_BD_FLAG)
3663    {
3664        pSendBd = &pDevice->pSendBdVirt[StartIdx];
3665        pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
3666
3667        while (StartIdx != Idx)
3668        {
3669            LM_UINT32 Value32;
3670
3671            if ((Value32 = pTmpSendBd->HostAddr.High) !=
3672                pShadowSendBd->HostAddr.High)
3673            {
3674                MM_MEMWRITEL(&(pSendBd->HostAddr.High), Value32);
3675                pShadowSendBd->HostAddr.High = Value32;
3676            }
3677
3678            MM_MEMWRITEL(&(pSendBd->HostAddr.Low), pTmpSendBd->HostAddr.Low);
3679
3680            if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3681                pShadowSendBd->u1.Len_Flags)
3682            {
3683                MM_MEMWRITEL(&(pSendBd->u1.Len_Flags), Value32);
3684                pShadowSendBd->u1.Len_Flags = Value32;
3685            }
3686
3687            if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
3688            {
3689                MM_MEMWRITEL(&(pSendBd->u2.VlanTag), pTmpSendBd->u2.VlanTag);
3690            }
3691
3692            StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3693            if (StartIdx == 0)
3694            {
3695                pSendBd = &pDevice->pSendBdVirt[0];
3696                pShadowSendBd = &pDevice->ShadowSendBd[0];
3697            }
3698            else
3699            {
3700                pSendBd++;
3701                pShadowSendBd++;
3702            }
3703            pTmpSendBd++;
3704        }
3705        MM_WMB();
3706        MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3707
3708        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3709        {
3710            MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3711        }
3712        if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3713        {
3714            MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
3715        }
3716    }
3717    else
3718#endif
3719    {
3720        MM_WMB();
3721        MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3722
3723        if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3724        {
3725            MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3726        }
3727        if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3728        {
3729            MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
3730        }
3731    }
3732
3733    /* Update the SendBdLeft count. */
3734    MM_ATOMIC_SUB(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
3735
3736    /* Update the producer index. */
3737    pDevice->SendProdIdx = Idx;
3738
3739    return LM_STATUS_SUCCESS;
3740}
3741
3742STATIC LM_STATUS
3743LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3744    PT3_SND_BD pSendBd)
3745{
3746    int FragCount;
3747    LM_UINT32 Idx, Base, Len;
3748
3749    Idx = pDevice->SendProdIdx;
3750    for(FragCount = 0; ; )
3751    {
3752        Len = pSendBd->u1.Len_Flags >> 16;
3753        if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3754            ((Base + 8 + Len) < Base))
3755        {
3756            return LM_STATUS_SUCCESS;
3757        }
3758        FragCount++;
3759        if (FragCount >= pPacket->u.Tx.FragCount)
3760        {
3761            break;
3762        }
3763        pSendBd++;
3764        if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3765        {
3766            Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3767            if (Idx == 0)
3768            {
3769                pSendBd = &pDevice->pSendBdVirt[0];
3770            }
3771        }
3772    }
3773    return LM_STATUS_FAILURE;
3774}
3775
3776/******************************************************************************/
3777/* Description:                                                               */
3778/*                                                                            */
3779/* Return:                                                                    */
3780/******************************************************************************/
3781LM_UINT32
3782ComputeCrc32(LM_UINT8 *pBuffer, LM_UINT32 BufferSize)
3783{
3784    LM_UINT32 Reg;
3785    LM_UINT32 Tmp;
3786    int j, k;
3787
3788    Reg = 0xffffffff;
3789
3790    for(j = 0; j < BufferSize; j++)
3791    {
3792        Reg ^= pBuffer[j];
3793
3794        for(k = 0; k < 8; k++)
3795        {
3796            Tmp = Reg & 0x01;
3797
3798            Reg >>= 1;
3799
3800            if(Tmp)
3801            {
3802                Reg ^= 0xedb88320;
3803            }
3804        }
3805    }
3806
3807    return ~Reg;
3808} /* ComputeCrc32 */
3809
3810
3811
3812/******************************************************************************/
3813/* Description:                                                               */
3814/*    This routine sets the receive control register according to ReceiveMask */
3815/*                                                                            */
3816/* Return:                                                                    */
3817/*    LM_STATUS_SUCCESS                                                       */
3818/******************************************************************************/
3819LM_STATUS
3820LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
3821{
3822    LM_UINT32 ReceiveMask;
3823    LM_UINT32 RxMode;
3824    LM_UINT32 j, k;
3825
3826    ReceiveMask = Mask;
3827
3828    RxMode = pDevice->RxMode;
3829
3830    if(Mask & LM_ACCEPT_UNICAST)
3831    {
3832        Mask &= ~LM_ACCEPT_UNICAST;
3833    }
3834
3835    if(Mask & LM_ACCEPT_MULTICAST)
3836    {
3837        Mask &= ~LM_ACCEPT_MULTICAST;
3838    }
3839
3840    if(Mask & LM_ACCEPT_ALL_MULTICAST)
3841    {
3842        Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3843    }
3844
3845    if(Mask & LM_ACCEPT_BROADCAST)
3846    {
3847        Mask &= ~LM_ACCEPT_BROADCAST;
3848    }
3849
3850    RxMode &= ~RX_MODE_KEEP_VLAN_TAG;
3851    if (Mask & LM_KEEP_VLAN_TAG)
3852    {
3853        RxMode |= RX_MODE_KEEP_VLAN_TAG;
3854        Mask &= ~LM_KEEP_VLAN_TAG;
3855    }
3856
3857    RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3858    if(Mask & LM_PROMISCUOUS_MODE)
3859    {
3860        RxMode |= RX_MODE_PROMISCUOUS_MODE;
3861        Mask &= ~LM_PROMISCUOUS_MODE;
3862    }
3863
3864    RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3865    if(Mask & LM_ACCEPT_ERROR_PACKET)
3866    {
3867        RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3868        Mask &= ~LM_ACCEPT_ERROR_PACKET;
3869    }
3870
3871    /* Make sure all the bits are valid before committing changes. */
3872    if(Mask)
3873    {
3874        return LM_STATUS_FAILURE;
3875    }
3876
3877    /* Commit the new filter. */
3878    pDevice->ReceiveMask = ReceiveMask;
3879
3880    pDevice->RxMode = RxMode;
3881
3882    if (pDevice->PowerLevel != LM_POWER_STATE_D0)
3883    {
3884        return LM_STATUS_SUCCESS;
3885    }
3886
3887    REG_WR(pDevice, MacCtrl.RxMode, RxMode);
3888
3889    /* Set up the MC hash table. */
3890    if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
3891    {
3892        for(k = 0; k < 4; k++)
3893        {
3894            REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
3895        }
3896    }
3897    else if(ReceiveMask & LM_ACCEPT_MULTICAST)
3898    {
3899        for(k = 0; k < 4; k++)
3900        {
3901            REG_WR(pDevice, MacCtrl.HashReg[k], pDevice->MulticastHash[k]);
3902        }
3903    }
3904    else
3905    {
3906        /* Reject all multicast frames. */
3907        for(j = 0; j < 4; j++)
3908        {
3909            REG_WR(pDevice, MacCtrl.HashReg[j], 0);
3910        }
3911    }
3912
3913    /* By default, Tigon3 will accept broadcast frames.  We need to setup */
3914    if(ReceiveMask & LM_ACCEPT_BROADCAST)
3915    {
3916        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3917            REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3918        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3919            REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3920        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3921            REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3922        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3923            REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3924    }
3925    else
3926    {
3927        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3928            REJECT_BROADCAST_RULE1_RULE);
3929        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3930            REJECT_BROADCAST_RULE1_VALUE);
3931        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3932            REJECT_BROADCAST_RULE2_RULE);
3933        REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3934            REJECT_BROADCAST_RULE2_VALUE);
3935    }
3936
3937    if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3938    {
3939        k = 16;
3940    }
3941    else
3942    {
3943        k = 8;
3944    }
3945#ifdef BCM_ASF
3946    if (pDevice->AsfFlags & ASF_ENABLED)
3947    {
3948        k -= 4;
3949    }
3950#endif
3951
3952    /* disable the rest of the rules. */
3953    for(j = RCV_LAST_RULE_IDX; j < k; j++)
3954    {
3955        REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
3956        REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
3957    }
3958
3959    return LM_STATUS_SUCCESS;
3960} /* LM_SetReceiveMask */
3961
3962
3963
3964/******************************************************************************/
3965/* Description:                                                               */
3966/*    Disable the interrupt and put the transmitter and receiver engines in   */
3967/*    an idle state.  Also aborts all pending send requests and receive       */
3968/*    buffers.                                                                */
3969/*                                                                            */
3970/* Return:                                                                    */
3971/*    LM_STATUS_SUCCESS                                                       */
3972/******************************************************************************/
3973LM_STATUS
3974LM_Abort(
3975PLM_DEVICE_BLOCK pDevice)
3976{
3977    PLM_PACKET pPacket;
3978    LM_UINT Idx;
3979
3980    LM_DisableInterrupt(pDevice);
3981
3982    LM_DisableChip(pDevice);
3983
3984    /* Abort packets that have already queued to go out. */
3985    Idx = pDevice->SendConIdx;
3986    for ( ; ; )
3987    {
3988        if ((pPacket = pDevice->SendRing[Idx]))
3989        {
3990            pDevice->SendRing[Idx] = 0;
3991            pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3992            pDevice->TxCounters.TxPacketAbortedCnt++;
3993
3994            MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
3995            Idx = (Idx + pPacket->u.Tx.FragCount) &
3996                T3_SEND_RCB_ENTRY_COUNT_MASK;
3997
3998            QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
3999	}
4000        else
4001	{
4002            break;
4003	}
4004    }
4005
4006    /* Cleanup the receive return rings. */
4007#ifdef BCM_NAPI_RXPOLL
4008    LM_ServiceRxPoll(pDevice, T3_RCV_RETURN_RCB_ENTRY_COUNT);
4009#else
4010    LM_ServiceRxInterrupt(pDevice);
4011#endif
4012
4013    /* Indicate packets to the protocol. */
4014    MM_IndicateTxPackets(pDevice);
4015
4016#ifdef BCM_NAPI_RXPOLL
4017
4018    /* Move the receive packet descriptors in the ReceivedQ to the */
4019    /* free queue. */
4020    for(; ;)
4021    {
4022        pPacket = (PLM_PACKET) QQ_PopHead(
4023            &pDevice->RxPacketReceivedQ.Container);
4024        if(pPacket == NULL)
4025        {
4026            break;
4027        }
4028        MM_UnmapRxDma(pDevice, pPacket);
4029        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4030    }
4031#else
4032    /* Indicate received packets to the protocols. */
4033    MM_IndicateRxPackets(pDevice);
4034#endif
4035
4036    /* Clean up the Std Receive Producer ring. */
4037    /* Don't always trust the consumer idx in the status block in case of  */
4038    /* hw failure */
4039    Idx = 0;
4040
4041    while(Idx < T3_STD_RCV_RCB_ENTRY_COUNT)
4042    {
4043        if ((pPacket = pDevice->RxStdRing[Idx]))
4044        {
4045            MM_UnmapRxDma(pDevice, pPacket);
4046            QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4047            pDevice->RxStdRing[Idx] = 0;
4048        }
4049
4050        Idx++;
4051    } /* while */
4052
4053    /* Reinitialize our copy of the indices. */
4054    pDevice->RxStdProdIdx = 0;
4055
4056#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4057    /* Clean up the Jumbo Receive Producer ring. */
4058    Idx = 0;
4059
4060    while(Idx < T3_JUMBO_RCV_RCB_ENTRY_COUNT)
4061    {
4062        if ((pPacket = pDevice->RxJumboRing[Idx]))
4063        {
4064            MM_UnmapRxDma(pDevice, pPacket);
4065            QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4066            pDevice->RxJumboRing[Idx] = 0;
4067        }
4068        Idx++;
4069    } /* while */
4070
4071    /* Reinitialize our copy of the indices. */
4072    pDevice->RxJumboProdIdx = 0;
4073#endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
4074
4075    /* Initialize the statistis Block */
4076    pDevice->pStatusBlkVirt->Status = 0;
4077    pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
4078    pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
4079    pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
4080
4081    return LM_STATUS_SUCCESS;
4082} /* LM_Abort */
4083
4084
4085
4086/******************************************************************************/
4087/* Description:                                                               */
4088/*    Disable the interrupt and put the transmitter and receiver engines in   */
4089/*    an idle state.  Aborts all pending send requests and receive buffers.   */
4090/*    Also free all the receive buffers.                                      */
4091/*                                                                            */
4092/* Return:                                                                    */
4093/*    LM_STATUS_SUCCESS                                                       */
4094/******************************************************************************/
4095LM_STATUS
4096LM_DoHalt(LM_DEVICE_BLOCK *pDevice)
4097{
4098    PLM_PACKET pPacket;
4099    LM_UINT32 EntryCnt;
4100
4101    LM_DisableFW(pDevice);
4102
4103    LM_WritePreResetSignatures(pDevice, LM_SHUTDOWN_RESET);
4104    LM_Abort(pDevice);
4105
4106    /* Get the number of entries in the queue. */
4107    EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
4108
4109    /* Make sure all the packets have been accounted for. */
4110    for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
4111    {
4112        pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
4113        if (pPacket == 0)
4114            break;
4115
4116        MM_FreeRxBuffer(pDevice, pPacket);
4117
4118        QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4119    }
4120
4121    LM_ResetChip(pDevice);
4122    LM_WriteLegacySignatures(pDevice, LM_SHUTDOWN_RESET);
4123
4124    /* Restore PCI configuration registers. */
4125    MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
4126        pDevice->SavedCacheLineReg);
4127    LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
4128        (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
4129
4130    /* Reprogram the MAC address. */
4131    LM_SetMacAddress(pDevice, pDevice->NodeAddress);
4132
4133    return LM_STATUS_SUCCESS;
4134} /* LM_DoHalt */
4135
4136
4137LM_STATUS
4138LM_Halt(LM_DEVICE_BLOCK *pDevice)
4139{
4140    LM_STATUS status;
4141
4142    status = LM_DoHalt(pDevice);
4143    LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
4144    return status;
4145}
4146
4147
4148STATIC LM_VOID
4149LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4150{
4151    MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,T3_MAGIC_NUM_FIRMWARE_INIT_DONE);
4152#ifdef BCM_ASF
4153    if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
4154    {
4155        if (Mode == LM_INIT_RESET)
4156        {
4157            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
4158        }
4159	else if (Mode == LM_SHUTDOWN_RESET)
4160        {
4161            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
4162        }
4163	else if (Mode == LM_SUSPEND_RESET)
4164        {
4165            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
4166        }
4167    }
4168#endif
4169}
4170
4171STATIC LM_VOID
4172LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4173{
4174#ifdef BCM_ASF
4175    if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
4176    {
4177        if (Mode == LM_INIT_RESET)
4178        {
4179            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
4180                T3_DRV_STATE_START_DONE);
4181        }
4182	else if (Mode == LM_SHUTDOWN_RESET)
4183        {
4184            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
4185                T3_DRV_STATE_UNLOAD_DONE);
4186        }
4187    }
4188#endif
4189}
4190
4191STATIC LM_VOID
4192LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4193{
4194#ifdef BCM_ASF
4195    if (pDevice->AsfFlags & ASF_ENABLED)
4196    {
4197        if (Mode == LM_INIT_RESET)
4198        {
4199            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
4200        }
4201	else if (Mode == LM_SHUTDOWN_RESET)
4202        {
4203            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
4204        }
4205	else if (Mode == LM_SUSPEND_RESET)
4206        {
4207            MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
4208        }
4209    }
4210#endif
4211}
4212
4213STATIC LM_STATUS
4214LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
4215{
4216    LM_UINT32 Value32;
4217    LM_UINT32 j, MaxWait;
4218
4219    /* Wait for access to the nvram interface before resetting.  This is */
4220    /* a workaround to prevent EEPROM corruption. */
4221    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
4222        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
4223    {
4224        /* Request access to the flash interface. */
4225        LM_NvramGetLock(pDevice);
4226    }
4227
4228    Value32 = GRC_MISC_CFG_CORE_CLOCK_RESET;
4229    if (pDevice->Flags & PCI_EXPRESS_FLAG)
4230    {
4231        if (REG_RD_OFFSET(pDevice, 0x7e2c) == 0x60)    /* PCIE 1.0 system */
4232        {
4233            REG_WR_OFFSET(pDevice, 0x7e2c, 0x20);
4234	}
4235        if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
4236        {
4237            /* This bit prevents PCIE link training during GRC reset */
4238            REG_WR(pDevice, Grc.MiscCfg, BIT_29);    /* Write bit 29 first */
4239            Value32 |= BIT_29;       /* and keep bit 29 set during GRC reset */
4240        }
4241    }
4242    if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
4243    {
4244        Value32 |= GRC_MISC_GPHY_KEEP_POWER_DURING_RESET;
4245    }
4246    /* Global reset. */
4247    RAW_REG_WR(pDevice, Grc.MiscCfg, Value32);
4248    MM_Wait(40); MM_Wait(40); MM_Wait(40);
4249
4250#ifdef INCLUDE_5750_A0_FIX
4251    if (pDevice->Flags & PCI_EXPRESS_FLAG)
4252    {
4253        if (pDevice->ChipRevId == T3_CHIP_ID_5750_A0)
4254        {
4255            /* 500 msec wait for link training to complete */
4256            for (j = 0; j < 5000; j++)
4257            {
4258                MM_Wait(100);
4259	    }
4260            MM_ReadConfig32(pDevice, 0xc4, &Value32);
4261            MM_WriteConfig32(pDevice, 0xc4, Value32 | BIT_15);
4262        }
4263        /* Set PCIE max payload size and clear error status */
4264        MM_WriteConfig32(pDevice, 0xd8, 0xf5000);
4265    }
4266#endif
4267
4268    /* make sure we re-enable indirect accesses */
4269    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
4270        pDevice->MiscHostCtrl);
4271
4272    /* Set MAX PCI retry to zero. */
4273    Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
4274    if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
4275    {
4276        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
4277        {
4278            Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
4279        }
4280    }
4281    MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
4282
4283    /* Restore PCI command register. */
4284    MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
4285        pDevice->PciCommandStatusWords);
4286
4287    /* Disable PCI-X relaxed ordering bit. */
4288    MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
4289    Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
4290    MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
4291
4292    /* Enable memory arbiter. */
4293    REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
4294
4295    if (pDevice->ChipRevId == T3_CHIP_ID_5750_A3)
4296    {
4297        /* Because of chip bug on A3, we need to kill the CPU */
4298        LM_DisableFW(pDevice);
4299        REG_WR_OFFSET(pDevice, 0x5000, 0x400);
4300    }
4301#ifdef BIG_ENDIAN_HOST
4302    /* Reconfigure the mode register. */
4303    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
4304              GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
4305              GRC_MODE_BYTE_SWAP_DATA |
4306              GRC_MODE_WORD_SWAP_DATA;
4307#else
4308    /* Reconfigure the mode register. */
4309    Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
4310#endif
4311    REG_WR(pDevice, Grc.Mode, Value32);
4312
4313#ifdef INCLUDE_5750_A0_FIX
4314    if (pDevice->ChipRevId == T3_CHIP_ID_5750_A0)
4315    {
4316        Value32 = REG_RD_OFFSET(pDevice, 0xc4);
4317        REG_WR_OFFSET(pDevice, 0xc4, Value32 | BIT_15);
4318    }
4319#endif
4320    if ((pDevice->Flags & MINI_PCI_FLAG) &&
4321        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
4322    {
4323        pDevice->ClockCtrl |= T3_PCI_CLKRUN_OUTPUT_EN;
4324        if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
4325        {
4326            pDevice->ClockCtrl |= T3_PCI_FORCE_CLKRUN;
4327        }
4328        REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
4329    }
4330
4331    if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
4332        pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
4333        REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
4334    }
4335    else {
4336        REG_WR(pDevice, MacCtrl.Mode, 0);
4337    }
4338
4339    /* Wait for the firmware to finish initialization. */
4340    if (pDevice->Flags & FLASH_DETECTED_FLAG)
4341    {
4342        MaxWait = 1000;
4343    }
4344    else
4345    {
4346        MaxWait = 10000;
4347    }
4348    for(j = 0; j < MaxWait; j++)
4349    {
4350        MM_Wait(100);
4351
4352        if (j < 50)
4353            continue;
4354
4355        Value32 = MEM_RD_OFFSET(pDevice, T3_FIRMWARE_MAILBOX);
4356        if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
4357        {
4358            break;
4359        }
4360    }
4361    if ((j >= MaxWait) && (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
4362    {
4363        /* workaround - need to reset nvram of both devices at the same time */
4364        /* if the boot code is not running */
4365        if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
4366        {
4367            LM_DEVICE_BLOCK *pDevice2;
4368
4369            REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
4370            pDevice2 = MM_FindPeerDev(pDevice);
4371            if (pDevice2 && !pDevice2->InitDone)
4372            {
4373                REG_WR(pDevice2, Nvram.Cmd, NVRAM_CMD_RESET);
4374	    }
4375	}
4376        else
4377        {
4378            LM_NvramReleaseLock(pDevice);
4379        }
4380    }
4381
4382    if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
4383        (pDevice->ChipRevId != T3_CHIP_ID_5750_A0))
4384    {
4385        /* Enable PCIE bug fix */
4386        Value32 = REG_RD_OFFSET(pDevice, 0x7c00);
4387        REG_WR_OFFSET(pDevice, 0x7c00, Value32 | BIT_25);
4388    }
4389#ifdef BCM_ASF
4390    pDevice->AsfFlags = 0;
4391    Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
4392    if (Value32 == T3_NIC_DATA_SIG)
4393    {
4394        Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
4395        if (Value32 & T3_NIC_CFG_ENABLE_ASF)
4396        {
4397            pDevice->AsfFlags = ASF_ENABLED;
4398            if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
4399            {
4400                pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
4401	    }
4402        }
4403    }
4404#endif
4405
4406    return LM_STATUS_SUCCESS;
4407}
4408
4409
4410LM_STATUS
4411LM_ShutdownChip(PLM_DEVICE_BLOCK pDevice, LM_RESET_TYPE Mode)
4412{
4413    LM_DisableFW(pDevice);
4414    LM_WritePreResetSignatures(pDevice, Mode);
4415    if (pDevice->InitDone)
4416    {
4417        LM_Abort(pDevice);
4418    }
4419    else
4420    {
4421        LM_DisableChip(pDevice);
4422    }
4423    LM_ResetChip(pDevice);
4424    LM_WriteLegacySignatures(pDevice, Mode);
4425    LM_WritePostResetSignatures(pDevice, Mode);
4426    return LM_STATUS_SUCCESS;
4427}
4428
4429/******************************************************************************/
4430/* Description:                                                               */
4431/*                                                                            */
4432/* Return:                                                                    */
4433/******************************************************************************/
4434void
4435LM_ServiceTxInterrupt(
4436PLM_DEVICE_BLOCK pDevice) {
4437    PLM_PACKET pPacket;
4438    LM_UINT32 HwConIdx;
4439    LM_UINT32 SwConIdx;
4440
4441    HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
4442
4443    /* Get our copy of the consumer index.  The buffer descriptors */
4444    /* that are in between the consumer indices are freed. */
4445    SwConIdx = pDevice->SendConIdx;
4446
4447    /* Move the packets from the TxPacketActiveQ that are sent out to */
4448    /* the TxPacketXmittedQ.  Packets that are sent use the */
4449    /* descriptors that are between SwConIdx and HwConIdx. */
4450    while(SwConIdx != HwConIdx)
4451    {
4452        pPacket = pDevice->SendRing[SwConIdx];
4453        pDevice->SendRing[SwConIdx] = 0;
4454
4455        /* Set the return status. */
4456        pPacket->PacketStatus = LM_STATUS_SUCCESS;
4457
4458        /* Put the packet in the TxPacketXmittedQ for indication later. */
4459        QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
4460
4461        /* Move to the next packet's BD. */
4462        SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
4463            T3_SEND_RCB_ENTRY_COUNT_MASK;
4464
4465        /* Update the number of unused BDs. */
4466        MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
4467
4468        /* Get the new updated HwConIdx. */
4469        HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
4470    } /* while */
4471
4472    /* Save the new SwConIdx. */
4473    pDevice->SendConIdx = SwConIdx;
4474
4475} /* LM_ServiceTxInterrupt */
4476
4477
4478#ifdef BCM_NAPI_RXPOLL
4479/******************************************************************************/
4480/* Description:                                                               */
4481/*                                                                            */
4482/* Return:                                                                    */
4483/******************************************************************************/
4484int
4485LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit)
4486{
4487    PLM_PACKET pPacket;
4488    PT3_RCV_BD pRcvBd;
4489    LM_UINT32 HwRcvRetProdIdx;
4490    LM_UINT32 SwRcvRetConIdx;
4491    int received = 0;
4492
4493    /* Loop thru the receive return rings for received packets. */
4494    HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
4495
4496    SwRcvRetConIdx = pDevice->RcvRetConIdx;
4497    MM_RMB();
4498    while (SwRcvRetConIdx != HwRcvRetProdIdx)
4499    {
4500        pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
4501
4502        /* Get the received packet descriptor. */
4503        pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
4504            MM_UINT_PTR(pRcvBd->Opaque));
4505
4506        switch(pPacket->u.Rx.RcvProdRing) {
4507#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4508        case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
4509            pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4510	    break;
4511#endif
4512        case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
4513            pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4514	    break;
4515        }
4516
4517        /* Check the error flag. */
4518        if(pRcvBd->ErrorFlag &&
4519            pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4520        {
4521            pPacket->PacketStatus = LM_STATUS_FAILURE;
4522
4523            pDevice->RxCounters.RxPacketErrCnt++;
4524
4525            if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
4526            {
4527                pDevice->RxCounters.RxErrCrcCnt++;
4528            }
4529
4530            if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
4531            {
4532                pDevice->RxCounters.RxErrCollCnt++;
4533            }
4534
4535            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
4536            {
4537                pDevice->RxCounters.RxErrLinkLostCnt++;
4538            }
4539
4540            if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
4541            {
4542                pDevice->RxCounters.RxErrPhyDecodeCnt++;
4543            }
4544
4545            if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4546            {
4547                pDevice->RxCounters.RxErrOddNibbleCnt++;
4548            }
4549
4550            if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
4551            {
4552                pDevice->RxCounters.RxErrMacAbortCnt++;
4553            }
4554
4555            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
4556            {
4557                pDevice->RxCounters.RxErrShortPacketCnt++;
4558            }
4559
4560            if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
4561            {
4562                pDevice->RxCounters.RxErrNoResourceCnt++;
4563            }
4564
4565            if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
4566            {
4567                pDevice->RxCounters.RxErrLargePacketCnt++;
4568            }
4569        }
4570        else
4571        {
4572            pPacket->PacketStatus = LM_STATUS_SUCCESS;
4573            pPacket->PacketSize = pRcvBd->Len - 4;
4574
4575            pPacket->Flags = pRcvBd->Flags;
4576            if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
4577            {
4578                pPacket->VlanTag = pRcvBd->VlanTag;
4579            }
4580
4581            pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
4582        }
4583
4584        /* Put the packet descriptor containing the received packet */
4585        /* buffer in the RxPacketReceivedQ for indication later. */
4586        QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
4587
4588        /* Go to the next buffer descriptor. */
4589        SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
4590            pDevice->RcvRetRcbEntryCountMask;
4591
4592        if (++received >= limit)
4593        {
4594            break;
4595        }
4596    } /* while */
4597
4598    pDevice->RcvRetConIdx = SwRcvRetConIdx;
4599
4600    /* Update the receive return ring consumer index. */
4601    MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
4602    if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4603    {
4604        MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
4605    }
4606    return received;
4607} /* LM_ServiceRxPoll */
4608#endif /* BCM_NAPI_RXPOLL */
4609
4610
4611/******************************************************************************/
4612/* Description:                                                               */
4613/*                                                                            */
4614/* Return:                                                                    */
4615/******************************************************************************/
4616void
4617LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice)
4618{
4619#ifndef BCM_NAPI_RXPOLL
4620    PLM_PACKET pPacket;
4621    PT3_RCV_BD pRcvBd;
4622#endif
4623    LM_UINT32 HwRcvRetProdIdx;
4624    LM_UINT32 SwRcvRetConIdx;
4625
4626    /* Loop thru the receive return rings for received packets. */
4627    HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
4628
4629    SwRcvRetConIdx = pDevice->RcvRetConIdx;
4630#ifdef BCM_NAPI_RXPOLL
4631    if (!pDevice->RxPoll)
4632    {
4633        if (SwRcvRetConIdx != HwRcvRetProdIdx)
4634        {
4635            if (MM_ScheduleRxPoll(pDevice) == LM_STATUS_SUCCESS)
4636            {
4637                pDevice->RxPoll = TRUE;
4638                REG_WR(pDevice, Grc.Mode,
4639                    pDevice->GrcMode | GRC_MODE_NO_INTERRUPT_ON_RECEIVE);
4640            }
4641        }
4642    }
4643#else
4644    MM_RMB();
4645    while(SwRcvRetConIdx != HwRcvRetProdIdx)
4646    {
4647        pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
4648
4649        /* Get the received packet descriptor. */
4650        pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
4651            MM_UINT_PTR(pRcvBd->Opaque));
4652
4653        switch(pPacket->u.Rx.RcvProdRing) {
4654#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4655        case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
4656            pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4657	    break;
4658#endif
4659        case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
4660            pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4661	    break;
4662        }
4663
4664        /* Check the error flag. */
4665        if(pRcvBd->ErrorFlag &&
4666            pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4667        {
4668            pPacket->PacketStatus = LM_STATUS_FAILURE;
4669
4670            pDevice->RxCounters.RxPacketErrCnt++;
4671
4672            if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
4673            {
4674                pDevice->RxCounters.RxErrCrcCnt++;
4675            }
4676
4677            if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
4678            {
4679                pDevice->RxCounters.RxErrCollCnt++;
4680            }
4681
4682            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
4683            {
4684                pDevice->RxCounters.RxErrLinkLostCnt++;
4685            }
4686
4687            if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
4688            {
4689                pDevice->RxCounters.RxErrPhyDecodeCnt++;
4690            }
4691
4692            if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4693            {
4694                pDevice->RxCounters.RxErrOddNibbleCnt++;
4695            }
4696
4697            if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
4698            {
4699                pDevice->RxCounters.RxErrMacAbortCnt++;
4700            }
4701
4702            if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
4703            {
4704                pDevice->RxCounters.RxErrShortPacketCnt++;
4705            }
4706
4707            if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
4708            {
4709                pDevice->RxCounters.RxErrNoResourceCnt++;
4710            }
4711
4712            if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
4713            {
4714                pDevice->RxCounters.RxErrLargePacketCnt++;
4715            }
4716        }
4717        else
4718        {
4719            pPacket->PacketStatus = LM_STATUS_SUCCESS;
4720            pPacket->PacketSize = pRcvBd->Len - 4;
4721
4722            pPacket->Flags = pRcvBd->Flags;
4723            if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
4724            {
4725                pPacket->VlanTag = pRcvBd->VlanTag;
4726            }
4727
4728            pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
4729        }
4730
4731        /* Put the packet descriptor containing the received packet */
4732        /* buffer in the RxPacketReceivedQ for indication later. */
4733        QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
4734
4735        /* Go to the next buffer descriptor. */
4736        SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
4737            pDevice->RcvRetRcbEntryCountMask;
4738
4739    } /* while */
4740
4741    pDevice->RcvRetConIdx = SwRcvRetConIdx;
4742
4743    /* Update the receive return ring consumer index. */
4744    MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
4745    if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4746    {
4747        MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
4748    }
4749#endif
4750} /* LM_ServiceRxInterrupt */
4751
4752
4753
4754/******************************************************************************/
4755/* Description:                                                               */
4756/*    This is the interrupt event handler routine. It acknowledges all        */
4757/*    pending interrupts and process all pending events.                      */
4758/*                                                                            */
4759/* Return:                                                                    */
4760/*    LM_STATUS_SUCCESS                                                       */
4761/******************************************************************************/
4762LM_STATUS
4763LM_ServiceInterrupts(
4764    PLM_DEVICE_BLOCK pDevice)
4765{
4766    LM_UINT32 Value32;
4767    int ServicePhyInt = FALSE;
4768
4769    /* Setup the phy chip whenever the link status changes. */
4770    if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
4771    {
4772        Value32 = REG_RD(pDevice, MacCtrl.Status);
4773        if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
4774        {
4775            if (Value32 & MAC_STATUS_MI_INTERRUPT)
4776            {
4777                ServicePhyInt = TRUE;
4778            }
4779        }
4780        else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
4781        {
4782            ServicePhyInt = TRUE;
4783        }
4784    }
4785    else
4786    {
4787        if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
4788        {
4789            pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4790                (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4791            ServicePhyInt = TRUE;
4792        }
4793    }
4794#if INCLUDE_TBI_SUPPORT
4795    if (pDevice->IgnoreTbiLinkChange == TRUE)
4796    {
4797        ServicePhyInt = FALSE;
4798    }
4799#endif
4800    if (ServicePhyInt == TRUE)
4801    {
4802        MM_ACQUIRE_PHY_LOCK_IN_IRQ(pDevice);
4803        LM_SetupPhy(pDevice);
4804        MM_RELEASE_PHY_LOCK_IN_IRQ(pDevice);
4805    }
4806
4807    /* Service receive and transmit interrupts. */
4808    LM_ServiceRxInterrupt(pDevice);
4809    LM_ServiceTxInterrupt(pDevice);
4810
4811#ifndef BCM_NAPI_RXPOLL
4812    /* No spinlock for this queue since this routine is serialized. */
4813    if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
4814    {
4815        /* Indicate receive packets. */
4816        MM_IndicateRxPackets(pDevice);
4817//        LM_QueueRxPackets(pDevice);
4818    }
4819#endif
4820
4821    /* No spinlock for this queue since this routine is serialized. */
4822    if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
4823    {
4824        MM_IndicateTxPackets(pDevice);
4825    }
4826
4827    return LM_STATUS_SUCCESS;
4828} /* LM_ServiceInterrupts */
4829
4830
4831/******************************************************************************/
4832/* Description:  Add a Multicast address. Note that MC addresses, once added, */
4833/*               cannot be individually deleted. All addresses must be        */
4834/*               cleared.                                                     */
4835/*                                                                            */
4836/* Return:                                                                    */
4837/******************************************************************************/
4838LM_STATUS
4839LM_MulticastAdd(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
4840{
4841
4842    LM_UINT32 RegIndex;
4843    LM_UINT32 Bitpos;
4844    LM_UINT32 Crc32;
4845
4846    Crc32 = ComputeCrc32(pMcAddress, ETHERNET_ADDRESS_SIZE);
4847
4848    /* The most significant 7 bits of the CRC32 (no inversion), */
4849    /* are used to index into one of the possible 128 bit positions. */
4850    Bitpos = ~Crc32 & 0x7f;
4851
4852    /* Hash register index. */
4853    RegIndex = (Bitpos & 0x60) >> 5;
4854
4855    /* Bit to turn on within a hash register. */
4856    Bitpos &= 0x1f;
4857
4858    /* Enable the multicast bit. */
4859    pDevice->MulticastHash[RegIndex] |= (1 << Bitpos);
4860
4861    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
4862
4863    return LM_STATUS_SUCCESS;
4864}
4865
4866
4867/******************************************************************************/
4868/* Description:                                                               */
4869/*                                                                            */
4870/* Return:                                                                    */
4871/******************************************************************************/
4872LM_STATUS
4873LM_MulticastDel(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
4874{
4875    return LM_STATUS_FAILURE;
4876} /* LM_MulticastDel */
4877
4878
4879
4880/******************************************************************************/
4881/* Description:                                                               */
4882/*                                                                            */
4883/* Return:                                                                    */
4884/******************************************************************************/
4885LM_STATUS
4886LM_MulticastClear(LM_DEVICE_BLOCK *pDevice)
4887{
4888    int i;
4889
4890    for (i = 0; i < 4; i++)
4891    {
4892        pDevice->MulticastHash[i] = 0;
4893    }
4894    LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4895
4896    return LM_STATUS_SUCCESS;
4897} /* LM_MulticastClear */
4898
4899
4900
4901/******************************************************************************/
4902/* Description:                                                               */
4903/*                                                                            */
4904/* Return:                                                                    */
4905/******************************************************************************/
4906LM_STATUS
4907LM_SetMacAddress(
4908    PLM_DEVICE_BLOCK pDevice,
4909    PLM_UINT8 pMacAddress)
4910{
4911    LM_UINT32 j;
4912
4913    for(j = 0; j < 4; j++)
4914    {
4915        REG_WR(pDevice, MacCtrl.MacAddr[j].High,
4916            (pMacAddress[0] << 8) | pMacAddress[1]);
4917        REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
4918            (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4919            (pMacAddress[4] << 8) | pMacAddress[5]);
4920    }
4921
4922    if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
4923        (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) &&
4924        (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
4925    {
4926        for (j = 0; j < 12; j++)
4927        {
4928            REG_WR(pDevice, MacCtrl.MacAddrExt[j].High,
4929                (pMacAddress[0] << 8) | pMacAddress[1]);
4930            REG_WR(pDevice, MacCtrl.MacAddrExt[j].Low,
4931                (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4932                (pMacAddress[4] << 8) | pMacAddress[5]);
4933        }
4934    }
4935    return LM_STATUS_SUCCESS;
4936}
4937
4938LM_VOID
4939LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice)
4940{
4941    /* Turn off tap power management. */
4942    if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4943    {
4944        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
4945        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4946        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4947        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4948        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4949        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4950        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4951        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4952        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4953        LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4954        LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4955
4956        MM_Wait(40);
4957    }
4958}
4959
4960/******************************************************************************/
4961/* Description:                                                               */
4962/*                                                                            */
4963/* Return:                                                                    */
4964/*    LM_STATUS_LINK_ACTIVE                                                   */
4965/*    LM_STATUS_LINK_DOWN                                                     */
4966/******************************************************************************/
4967static LM_STATUS
4968LM_InitBcm540xPhy(
4969PLM_DEVICE_BLOCK pDevice)
4970{
4971    LM_LINE_SPEED CurrentLineSpeed;
4972    LM_DUPLEX_MODE CurrentDuplexMode;
4973    LM_STATUS CurrentLinkStatus;
4974    LM_UINT32 Value32;
4975    LM_UINT32 j;
4976
4977    LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
4978
4979    if ((pDevice->PhyFlags & PHY_RESET_ON_LINKDOWN) &&
4980        (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE))
4981    {
4982        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4983        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4984        if(!(Value32 & PHY_STATUS_LINK_PASS))
4985        {
4986            LM_ResetPhy(pDevice);
4987        }
4988    }
4989    if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4990    {
4991        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4992        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4993
4994        if(!pDevice->InitDone)
4995        {
4996            Value32 = 0;
4997        }
4998
4999        if(!(Value32 & PHY_STATUS_LINK_PASS))
5000        {
5001            LM_PhyTapPowerMgmt(pDevice);
5002
5003            LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5004            for(j = 0; j < 1000; j++)
5005            {
5006                MM_Wait(10);
5007
5008                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5009                if(Value32 & PHY_STATUS_LINK_PASS)
5010                {
5011                    MM_Wait(40);
5012                    break;
5013                }
5014            }
5015
5016            if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
5017            {
5018                if(!(Value32 & PHY_STATUS_LINK_PASS) &&
5019                    (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
5020                {
5021                    LM_ResetPhy(pDevice);
5022                }
5023            }
5024        }
5025    }
5026    else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5027        pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
5028    {
5029        /* Bug: 5701 A0, B0 TX CRC workaround. */
5030        LM_WritePhy(pDevice, 0x15, 0x0a75);
5031        LM_WritePhy(pDevice, 0x1c, 0x8c68);
5032        LM_WritePhy(pDevice, 0x1c, 0x8d68);
5033        LM_WritePhy(pDevice, 0x1c, 0x8c68);
5034    }
5035
5036    /* Acknowledge interrupts. */
5037    LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
5038    LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
5039
5040    /* Configure the interrupt mask. */
5041    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5042    {
5043        LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
5044    }
5045
5046    /* Configure PHY led mode. */
5047    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5048        (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
5049    {
5050        if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_1)
5051        {
5052            LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
5053                BCM540X_EXT_CTRL_LINK3_LED_MODE);
5054        }
5055        else
5056        {
5057            LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
5058        }
5059    }
5060
5061    if (pDevice->PhyFlags & PHY_CAPACITIVE_COUPLING)
5062    {
5063        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4007);
5064        LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &Value32);
5065        if (!(Value32 & BIT_10))
5066        {
5067            /* set the bit and re-link */
5068            LM_WritePhy(pDevice, BCM5401_AUX_CTRL, Value32 | BIT_10);
5069            return LM_STATUS_LINK_SETTING_MISMATCH;
5070        }
5071    }
5072
5073    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5074
5075    /* Get current link and duplex mode. */
5076    for(j = 0; j < 100; j++)
5077    {
5078        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5079        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5080
5081        if(Value32 & PHY_STATUS_LINK_PASS)
5082        {
5083            break;
5084        }
5085        MM_Wait(40);
5086    }
5087
5088    if(Value32 & PHY_STATUS_LINK_PASS)
5089    {
5090
5091        /* Determine the current line and duplex settings. */
5092        LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
5093        for(j = 0; j < 2000; j++)
5094        {
5095            MM_Wait(10);
5096
5097            LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
5098            if(Value32)
5099            {
5100                break;
5101            }
5102        }
5103
5104        switch(Value32 & BCM540X_AUX_SPEED_MASK)
5105        {
5106            case BCM540X_AUX_10BASET_HD:
5107                CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
5108                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5109                break;
5110
5111            case BCM540X_AUX_10BASET_FD:
5112                CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
5113                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5114                break;
5115
5116            case BCM540X_AUX_100BASETX_HD:
5117                CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
5118                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5119                break;
5120
5121            case BCM540X_AUX_100BASETX_FD:
5122                CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
5123                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5124                break;
5125
5126            case BCM540X_AUX_100BASET_HD:
5127                CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
5128                CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5129                break;
5130
5131            case BCM540X_AUX_100BASET_FD:
5132                CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
5133                CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5134                break;
5135
5136            default:
5137
5138                CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
5139                CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
5140                break;
5141        }
5142
5143        /* Make sure we are in auto-neg mode. */
5144        for (j = 0; j < 200; j++)
5145        {
5146            LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5147            if(Value32 && Value32 != 0x7fff)
5148            {
5149                break;
5150            }
5151
5152            if(Value32 == 0 &&
5153                pDevice->RequestedLineSpeed == LM_LINE_SPEED_10MBPS &&
5154                pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_HALF)
5155            {
5156                break;
5157            }
5158
5159            MM_Wait(10);
5160        }
5161
5162        /* Use the current line settings for "auto" mode. */
5163        if(pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
5164        {
5165            if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
5166            {
5167                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5168
5169                /* We may be exiting low power mode and the link is in */
5170                /* 10mb.  In this case, we need to restart autoneg. */
5171
5172                if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
5173                {
5174                    CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5175                }
5176            }
5177            else
5178            {
5179                CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5180            }
5181        }
5182        else
5183        {
5184            /* Force line settings. */
5185            /* Use the current setting if it matches the user's requested */
5186            /* setting. */
5187            LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5188            if((pDevice->LineSpeed == CurrentLineSpeed) &&
5189                (pDevice->DuplexMode == CurrentDuplexMode))
5190            {
5191                if ((pDevice->DisableAutoNeg &&
5192                    !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
5193                    (!pDevice->DisableAutoNeg &&
5194                    (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
5195                {
5196                    CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5197                }
5198                else
5199                {
5200                    CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5201                }
5202            }
5203            else
5204            {
5205                CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5206            }
5207        }
5208
5209        /* Save line settings. */
5210        pDevice->LineSpeed = CurrentLineSpeed;
5211        pDevice->DuplexMode = CurrentDuplexMode;
5212    }
5213
5214    return CurrentLinkStatus;
5215} /* LM_InitBcm540xPhy */
5216
5217/******************************************************************************/
5218/* Description:                                                               */
5219/*                                                                            */
5220/* Return:                                                                    */
5221/******************************************************************************/
5222LM_STATUS
5223LM_SetFlowControl(
5224    PLM_DEVICE_BLOCK pDevice,
5225    LM_UINT32 LocalPhyAd,
5226    LM_UINT32 RemotePhyAd)
5227{
5228    LM_FLOW_CONTROL FlowCap;
5229
5230    /* Resolve flow control. */
5231    FlowCap = LM_FLOW_CONTROL_NONE;
5232
5233    /* See Table 28B-3 of 802.3ab-1999 spec. */
5234    if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
5235    {
5236        if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
5237        {
5238            if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5239            {
5240                if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
5241                {
5242                    FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
5243                        LM_FLOW_CONTROL_RECEIVE_PAUSE;
5244                }
5245                else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
5246                {
5247                    FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
5248                }
5249            }
5250            else
5251            {
5252                if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
5253                {
5254                    FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
5255                        LM_FLOW_CONTROL_RECEIVE_PAUSE;
5256                }
5257            }
5258        }
5259        else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5260        {
5261            if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
5262                (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
5263            {
5264                FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
5265            }
5266        }
5267    }
5268    else
5269    {
5270        FlowCap = pDevice->FlowControlCap;
5271    }
5272
5273    pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5274
5275    /* Enable/disable rx PAUSE. */
5276    pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
5277    if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
5278        (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
5279        pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
5280    {
5281        pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
5282        pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
5283
5284    }
5285    REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
5286
5287    /* Enable/disable tx PAUSE. */
5288    pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
5289    if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
5290        (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
5291        pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
5292    {
5293        pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
5294        pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
5295
5296    }
5297    REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
5298
5299    return LM_STATUS_SUCCESS;
5300}
5301
5302
5303#if INCLUDE_TBI_SUPPORT
5304/******************************************************************************/
5305/* Description:                                                               */
5306/*                                                                            */
5307/* Return:                                                                    */
5308/******************************************************************************/
5309STATIC LM_STATUS
5310LM_InitBcm800xPhy(
5311    PLM_DEVICE_BLOCK pDevice)
5312{
5313    LM_UINT32 Value32;
5314    LM_UINT32 j;
5315
5316    Value32 = REG_RD(pDevice, MacCtrl.Status);
5317
5318    /* Reset the SERDES during init and when we have link. */
5319    if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
5320    {
5321        /* Set PLL lock range. */
5322        LM_WritePhy(pDevice, 0x16, 0x8007);
5323
5324        /* Software reset. */
5325        LM_WritePhy(pDevice, 0x00, 0x8000);
5326
5327        /* Wait for reset to complete. */
5328        for(j = 0; j < 500; j++)
5329        {
5330            MM_Wait(10);
5331        }
5332
5333        /* Config mode; seletct PMA/Ch 1 regs. */
5334        LM_WritePhy(pDevice, 0x10, 0x8411);
5335
5336        /* Enable auto-lock and comdet, select txclk for tx. */
5337        LM_WritePhy(pDevice, 0x11, 0x0a10);
5338
5339        LM_WritePhy(pDevice, 0x18, 0x00a0);
5340        LM_WritePhy(pDevice, 0x16, 0x41ff);
5341
5342        /* Assert and deassert POR. */
5343        LM_WritePhy(pDevice, 0x13, 0x0400);
5344        MM_Wait(40);
5345        LM_WritePhy(pDevice, 0x13, 0x0000);
5346
5347        LM_WritePhy(pDevice, 0x11, 0x0a50);
5348        MM_Wait(40);
5349        LM_WritePhy(pDevice, 0x11, 0x0a10);
5350
5351        /* Delay for signal to stabilize. */
5352        for(j = 0; j < 15000; j++)
5353        {
5354            MM_Wait(10);
5355        }
5356
5357        /* Deselect the channel register so we can read the PHY id later. */
5358        LM_WritePhy(pDevice, 0x10, 0x8011);
5359    }
5360
5361    return LM_STATUS_SUCCESS;
5362}
5363
5364
5365
5366/******************************************************************************/
5367/* Description:                                                               */
5368/*                                                                            */
5369/* Return:                                                                    */
5370/******************************************************************************/
5371STATIC LM_STATUS
5372LM_SetupFiberPhy(
5373    PLM_DEVICE_BLOCK pDevice)
5374{
5375    LM_STATUS CurrentLinkStatus;
5376    AUTONEG_STATUS AnStatus = 0;
5377    LM_UINT32 Value32;
5378    LM_UINT32 Cnt;
5379    LM_UINT32 j, k;
5380    LM_UINT32 MacStatus, RemotePhyAd, LocalPhyAd;
5381    LM_FLOW_CONTROL PreviousFlowControl = pDevice->FlowControl;
5382
5383    if (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE)
5384    {
5385        pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
5386        MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
5387        return LM_STATUS_SUCCESS;
5388    }
5389
5390    if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
5391        (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) && pDevice->InitDone)
5392    {
5393        MacStatus = REG_RD(pDevice, MacCtrl.Status);
5394        if ((MacStatus & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED |
5395            MAC_STATUS_CFG_CHANGED | MAC_STATUS_RECEIVING_CFG))
5396            == (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED))
5397        {
5398
5399            REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5400                MAC_STATUS_CFG_CHANGED);
5401            return LM_STATUS_SUCCESS;
5402        }
5403    }
5404    pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
5405
5406    /* Initialize the send_config register. */
5407    REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
5408
5409    /* Enable TBI and full duplex mode. */
5410    pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
5411    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5412
5413    /* Initialize the BCM8002 SERDES PHY. */
5414    switch(pDevice->PhyId & PHY_ID_MASK)
5415    {
5416        case PHY_BCM8002_PHY_ID:
5417            LM_InitBcm800xPhy(pDevice);
5418            break;
5419
5420        default:
5421            break;
5422    }
5423
5424    /* Enable link change interrupt. */
5425    REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5426
5427    /* Default to link down. */
5428    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5429
5430    /* Get the link status. */
5431    MacStatus = REG_RD(pDevice, MacCtrl.Status);
5432
5433    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
5434    {
5435        LM_UINT32 SgDigCtrl, SgDigStatus;
5436        LM_UINT32 SerdesCfg = 0;
5437        LM_UINT32 ExpectedSgDigCtrl = 0;
5438        LM_UINT32 WorkAround = 0;
5439        LM_UINT32 PortA = 1;
5440
5441        if ((pDevice->ChipRevId != T3_CHIP_ID_5704_A0) &&
5442            (pDevice->ChipRevId != T3_CHIP_ID_5704_A1))
5443        {
5444            WorkAround = 1;
5445            if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
5446            {
5447                PortA = 0;
5448            }
5449            /* preserve the voltage regulator bits */
5450            SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
5451                (BIT_23 | BIT_22 | BIT_21 | BIT_20);
5452        }
5453        SgDigCtrl = REG_RD(pDevice, MacCtrl.SgDigControl);
5454        if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
5455            (pDevice->DisableAutoNeg == FALSE))
5456        {
5457
5458            ExpectedSgDigCtrl = 0x81388400;
5459            LocalPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5460            if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
5461            {
5462                ExpectedSgDigCtrl |= BIT_11;
5463            }
5464            if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5465            {
5466                ExpectedSgDigCtrl |= BIT_12;
5467            }
5468            if (SgDigCtrl != ExpectedSgDigCtrl)
5469            {
5470                if (WorkAround)
5471                {
5472                    REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011880 | SerdesCfg);
5473                }
5474                REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl |
5475                    BIT_30);
5476                REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
5477		MM_Wait(5);
5478                REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl);
5479                pDevice->AutoNegJustInited = TRUE;
5480            }
5481            /* If autoneg is off, you only get SD when link is up */
5482            else if(MacStatus & (MAC_STATUS_PCS_SYNCED |
5483                MAC_STATUS_SIGNAL_DETECTED))
5484            {
5485                SgDigStatus = REG_RD(pDevice, MacCtrl.SgDigStatus);
5486                if ((SgDigStatus & BIT_1) &&
5487                    (MacStatus & MAC_STATUS_PCS_SYNCED))
5488                {
5489                    /* autoneg. completed */
5490                    RemotePhyAd = 0;
5491                    if(SgDigStatus & BIT_19)
5492                    {
5493                        RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
5494                    }
5495
5496                    if(SgDigStatus & BIT_20)
5497                    {
5498                        RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
5499                    }
5500
5501                    LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5502                    CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5503                    pDevice->AutoNegJustInited = FALSE;
5504                }
5505                else if (!(SgDigStatus & BIT_1))
5506                {
5507                    if (pDevice->AutoNegJustInited == TRUE)
5508                    {
5509                        /* we may be checking too soon, so check again */
5510                        /* at the next poll interval */
5511                        pDevice->AutoNegJustInited = FALSE;
5512                    }
5513                    else
5514                    {
5515                        /* autoneg. failed */
5516                        if (WorkAround)
5517                        {
5518                            if (PortA)
5519                            {
5520                                REG_WR(pDevice, MacCtrl.SerdesCfg,
5521                                    0xc010880 | SerdesCfg);
5522                            }
5523                            else
5524                            {
5525                                REG_WR(pDevice, MacCtrl.SerdesCfg,
5526                                    0x4010880 | SerdesCfg);
5527                            }
5528                        }
5529                        /* turn off autoneg. to allow traffic to pass */
5530                        REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
5531                        REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
5532                        MM_Wait(40);
5533                        MacStatus = REG_RD(pDevice, MacCtrl.Status);
5534                        if (MacStatus & MAC_STATUS_PCS_SYNCED)
5535                        {
5536                            LM_SetFlowControl(pDevice, 0, 0);
5537                            CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5538                        }
5539                    }
5540                }
5541            }
5542        }
5543        else
5544        {
5545            if (SgDigCtrl & BIT_31) {
5546                if (WorkAround)
5547                {
5548                    if (PortA)
5549                    {
5550                        REG_WR(pDevice, MacCtrl.SerdesCfg,
5551                            0xc010880 | SerdesCfg);
5552                    }
5553                    else
5554                    {
5555                        REG_WR(pDevice, MacCtrl.SerdesCfg,
5556                            0x4010880 | SerdesCfg);
5557                    }
5558                }
5559                REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
5560            }
5561            if(MacStatus & MAC_STATUS_PCS_SYNCED)
5562            {
5563                LM_SetFlowControl(pDevice, 0, 0);
5564                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5565            }
5566        }
5567    }
5568    else if(MacStatus & MAC_STATUS_PCS_SYNCED)
5569    {
5570        if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
5571            (pDevice->DisableAutoNeg == FALSE))
5572        {
5573            /* auto-negotiation mode. */
5574            /* Initialize the autoneg default capaiblities. */
5575            AutonegInit(&pDevice->AnInfo);
5576
5577            /* Set the context pointer to point to the main device structure. */
5578            pDevice->AnInfo.pContext = pDevice;
5579
5580            /* Setup flow control advertisement register. */
5581            Value32 = GetPhyAdFlowCntrlSettings(pDevice);
5582            if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
5583            {
5584                pDevice->AnInfo.mr_adv_sym_pause = 1;
5585            }
5586            else
5587            {
5588                pDevice->AnInfo.mr_adv_sym_pause = 0;
5589            }
5590
5591            if(Value32 & PHY_AN_AD_ASYM_PAUSE)
5592            {
5593                pDevice->AnInfo.mr_adv_asym_pause = 1;
5594            }
5595            else
5596            {
5597                pDevice->AnInfo.mr_adv_asym_pause = 0;
5598            }
5599
5600            /* Try to autoneg up to six times. */
5601            if (pDevice->IgnoreTbiLinkChange)
5602            {
5603                Cnt = 1;
5604            }
5605            else
5606            {
5607                Cnt = 6;
5608            }
5609            for (j = 0; j < Cnt; j++)
5610            {
5611                REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
5612
5613                Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
5614                REG_WR(pDevice, MacCtrl.Mode, Value32);
5615                REG_RD_BACK(pDevice, MacCtrl.Mode);
5616                MM_Wait(20);
5617
5618                REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5619                    MAC_MODE_SEND_CONFIGS);
5620                REG_RD_BACK(pDevice, MacCtrl.Mode);
5621
5622                MM_Wait(20);
5623
5624                pDevice->AnInfo.State = AN_STATE_UNKNOWN;
5625                pDevice->AnInfo.CurrentTime_us = 0;
5626
5627                REG_WR(pDevice, Grc.Timer, 0);
5628                for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
5629                    (k < 75000); k++)
5630                {
5631                    AnStatus = Autoneg8023z(&pDevice->AnInfo);
5632
5633                    if((AnStatus == AUTONEG_STATUS_DONE) ||
5634                        (AnStatus == AUTONEG_STATUS_FAILED))
5635                    {
5636                        break;
5637                    }
5638
5639                    pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
5640
5641                }
5642                if((AnStatus == AUTONEG_STATUS_DONE) ||
5643                    (AnStatus == AUTONEG_STATUS_FAILED))
5644                {
5645                    break;
5646                }
5647                if (j >= 1)
5648                {
5649                    if (!(REG_RD(pDevice, MacCtrl.Status) &
5650                        MAC_STATUS_PCS_SYNCED)) {
5651                        break;
5652                    }
5653                }
5654            }
5655
5656            /* Stop sending configs. */
5657            MM_AnTxIdle(&pDevice->AnInfo);
5658
5659            /* Resolve flow control settings. */
5660            if((AnStatus == AUTONEG_STATUS_DONE) &&
5661                pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
5662                pDevice->AnInfo.mr_lp_adv_full_duplex)
5663                {
5664                LM_UINT32 RemotePhyAd;
5665                LM_UINT32 LocalPhyAd;
5666
5667                LocalPhyAd = 0;
5668                if(pDevice->AnInfo.mr_adv_sym_pause)
5669                {
5670                    LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
5671                }
5672
5673                if(pDevice->AnInfo.mr_adv_asym_pause)
5674                {
5675                    LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
5676                }
5677
5678                RemotePhyAd = 0;
5679                if(pDevice->AnInfo.mr_lp_adv_sym_pause)
5680                {
5681                    RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
5682                }
5683
5684                if(pDevice->AnInfo.mr_lp_adv_asym_pause)
5685                {
5686                    RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
5687                }
5688
5689                LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5690
5691                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5692            }
5693            else
5694            {
5695                LM_SetFlowControl(pDevice, 0, 0);
5696            }
5697            for (j = 0; j < 30; j++)
5698            {
5699                MM_Wait(20);
5700                REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5701                    MAC_STATUS_CFG_CHANGED);
5702                REG_RD_BACK(pDevice, MacCtrl.Status);
5703                MM_Wait(20);
5704                if ((REG_RD(pDevice, MacCtrl.Status) &
5705                    (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
5706                    break;
5707            }
5708            if (pDevice->TbiFlags & TBI_POLLING_FLAGS)
5709            {
5710                Value32 = REG_RD(pDevice, MacCtrl.Status);
5711                if (Value32 & MAC_STATUS_RECEIVING_CFG)
5712                {
5713                    pDevice->IgnoreTbiLinkChange = TRUE;
5714                }
5715                else if (pDevice->TbiFlags & TBI_POLLING_INTR_FLAG)
5716                {
5717                    pDevice->IgnoreTbiLinkChange = FALSE;
5718                }
5719            }
5720            Value32 = REG_RD(pDevice, MacCtrl.Status);
5721            if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
5722                 (Value32 & MAC_STATUS_PCS_SYNCED) &&
5723                 ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
5724            {
5725                CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5726            }
5727        }
5728        else
5729        {
5730            /* We are forcing line speed. */
5731            pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5732            LM_SetFlowControl(pDevice, 0, 0);
5733
5734            CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5735            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5736                MAC_MODE_SEND_CONFIGS);
5737        }
5738    }
5739    /* Set the link polarity bit. */
5740    pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5741    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5742
5743    pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
5744        (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
5745
5746    for (j = 0; j < 100; j++)
5747    {
5748        REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5749            MAC_STATUS_CFG_CHANGED);
5750        REG_RD_BACK(pDevice, MacCtrl.Status);
5751        MM_Wait(5);
5752        if ((REG_RD(pDevice, MacCtrl.Status) &
5753            (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
5754            break;
5755    }
5756
5757    Value32 = REG_RD(pDevice, MacCtrl.Status);
5758    if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
5759    {
5760        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5761        if (pDevice->DisableAutoNeg == FALSE)
5762        {
5763            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5764                MAC_MODE_SEND_CONFIGS);
5765            REG_RD_BACK(pDevice, MacCtrl.Mode);
5766            MM_Wait(1);
5767            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5768        }
5769    }
5770
5771    /* Initialize the current link status. */
5772    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5773    {
5774        pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
5775        pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
5776        REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
5777            LED_CTRL_OVERRIDE_LINK_LED |
5778            LED_CTRL_1000MBPS_LED_ON);
5779    }
5780    else
5781    {
5782        pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
5783        pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
5784        REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
5785            LED_CTRL_OVERRIDE_LINK_LED |
5786            LED_CTRL_OVERRIDE_TRAFFIC_LED);
5787    }
5788
5789    /* Indicate link status. */
5790    if ((pDevice->LinkStatus != CurrentLinkStatus) ||
5791        ((CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
5792        (PreviousFlowControl != pDevice->FlowControl)))
5793    {
5794        pDevice->LinkStatus = CurrentLinkStatus;
5795        MM_IndicateStatus(pDevice, CurrentLinkStatus);
5796    }
5797
5798    return LM_STATUS_SUCCESS;
5799}
5800#endif /* INCLUDE_TBI_SUPPORT */
5801
5802
5803/******************************************************************************/
5804/* Description:                                                               */
5805/*                                                                            */
5806/* Return:                                                                    */
5807/******************************************************************************/
5808LM_STATUS
5809LM_SetupCopperPhy(
5810    PLM_DEVICE_BLOCK pDevice)
5811{
5812    LM_STATUS CurrentLinkStatus;
5813    LM_UINT32 Value32;
5814
5815    /* Assume there is not link first. */
5816    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5817
5818    /* Disable phy link change attention. */
5819    REG_WR(pDevice, MacCtrl.MacEvent, 0);
5820
5821    /* Clear link change attention. */
5822    REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5823        MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
5824        MAC_STATUS_LINK_STATE_CHANGED);
5825
5826    /* Disable auto-polling for the moment. */
5827    pDevice->MiMode = 0xc0000;
5828    REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5829    REG_RD_BACK(pDevice, MacCtrl.MiMode);
5830    MM_Wait(40);
5831
5832    /* Determine the requested line speed and duplex. */
5833    pDevice->OldLineSpeed = pDevice->LineSpeed;
5834    pDevice->LineSpeed = pDevice->RequestedLineSpeed;
5835    pDevice->DuplexMode = pDevice->RequestedDuplexMode;
5836
5837    /* Set the phy to loopback mode. */
5838    if ((pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE) ||
5839        (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE))
5840    {
5841        LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5842        if(!(Value32 & PHY_CTRL_LOOPBACK_MODE) &&
5843            (pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE))
5844        {
5845            /* Disable link change and PHY interrupts. */
5846            REG_WR(pDevice, MacCtrl.MacEvent, 0);
5847
5848            /* Clear link change attention. */
5849            REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5850                MAC_STATUS_CFG_CHANGED);
5851
5852            LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
5853            MM_Wait(40);
5854
5855            pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5856            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5857                T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 ||
5858                T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
5859                T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705 ||
5860                (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 &&
5861                (pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID))
5862            {
5863                pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5864            }
5865
5866            /* Prevent the interrupt handling from being called. */
5867            pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
5868                (pDevice->pStatusBlkVirt->Status &
5869                ~STATUS_BLOCK_LINK_CHANGED_STATUS);
5870
5871            /* GMII interface. */
5872            pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
5873            pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5874            REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5875            REG_RD_BACK(pDevice, MacCtrl.Mode);
5876            MM_Wait(40);
5877
5878            /* Configure PHY led mode. */
5879            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5880                (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
5881            {
5882                LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
5883                    BCM540X_EXT_CTRL_LINK3_LED_MODE);
5884                MM_Wait(40);
5885            }
5886
5887            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5888            {
5889                int j = 0;
5890
5891                while (REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE)
5892                {
5893                    MM_Wait(40);
5894                    j++;
5895                    if (j > 20)
5896                        break;
5897                }
5898
5899                Value32 = DMA_WRITE_MODE_ENABLE |
5900                    DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
5901                    DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
5902                    DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
5903                    DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
5904                    DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
5905                    DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
5906                    DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
5907                    DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
5908                REG_WR(pDevice, DmaWrite.Mode, Value32);
5909            }
5910        }
5911
5912        pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
5913        MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
5914
5915        return LM_STATUS_SUCCESS;
5916    }
5917
5918    LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5919    if(Value32 & PHY_CTRL_LOOPBACK_MODE)
5920    {
5921        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5922
5923        /* Re-enable link change interrupt.  This was disabled when we */
5924        /* enter loopback mode. */
5925        if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5926        {
5927            REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
5928        }
5929        else
5930        {
5931            REG_WR(pDevice, MacCtrl.MacEvent,
5932                MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5933        }
5934    }
5935    else
5936    {
5937        /* Initialize the phy chip. */
5938        CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
5939    }
5940
5941    if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
5942    {
5943        CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5944    }
5945
5946    /* Setup flow control. */
5947    pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5948    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5949    {
5950        LM_FLOW_CONTROL FlowCap;     /* Flow control capability. */
5951
5952        FlowCap = LM_FLOW_CONTROL_NONE;
5953
5954        if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
5955        {
5956            if(pDevice->DisableAutoNeg == FALSE ||
5957                pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
5958            {
5959                LM_UINT32 ExpectedPhyAd;
5960                LM_UINT32 LocalPhyAd;
5961                LM_UINT32 RemotePhyAd;
5962
5963                LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
5964		pDevice->advertising = LocalPhyAd;
5965                LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
5966
5967                ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5968
5969                if(LocalPhyAd != ExpectedPhyAd)
5970                {
5971                    CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5972                }
5973                else
5974                {
5975                    LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
5976                        &RemotePhyAd);
5977
5978                    LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5979                }
5980            }
5981            else
5982            {
5983                pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5984                LM_SetFlowControl(pDevice, 0, 0);
5985            }
5986        }
5987    }
5988
5989    if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
5990    {
5991        LM_ForceAutoNeg(pDevice);
5992
5993        /* If we force line speed, we make get link right away. */
5994        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5995        LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5996        if(Value32 & PHY_STATUS_LINK_PASS)
5997        {
5998            CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5999        }
6000    }
6001
6002    /* GMII interface. */
6003    pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
6004    if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
6005    {
6006        if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
6007            pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
6008        {
6009            pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
6010        }
6011        else
6012        {
6013            pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
6014        }
6015    }
6016    else {
6017        pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
6018    }
6019
6020    /* Set the MAC to operate in the appropriate duplex mode. */
6021    pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
6022    if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
6023    {
6024        pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
6025    }
6026
6027    /* Set the link polarity bit. */
6028    pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
6029    if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
6030    {
6031        if((pDevice->LedCtrl == LED_CTRL_PHY_MODE_2) ||
6032             (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
6033             pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
6034        {
6035            pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
6036        }
6037    }
6038    else
6039    {
6040        if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
6041        {
6042            pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
6043        }
6044    }
6045
6046    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6047
6048    /* Enable auto polling. */
6049    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6050    {
6051        pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
6052        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6053    }
6054    /* if using MAC led mode and not using auto polling, need to configure */
6055    /* mi status register */
6056    else if ((pDevice->LedCtrl &
6057            (LED_CTRL_PHY_MODE_1 | LED_CTRL_PHY_MODE_2)) == 0)
6058    {
6059        if (CurrentLinkStatus != LM_STATUS_LINK_ACTIVE)
6060        {
6061            REG_WR(pDevice, MacCtrl.MiStatus, 0);
6062        }
6063        else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
6064        {
6065            REG_WR(pDevice, MacCtrl.MiStatus,
6066                MI_STATUS_ENABLE_LINK_STATUS_ATTN | MI_STATUS_10MBPS);
6067        }
6068        else
6069        {
6070            REG_WR(pDevice, MacCtrl.MiStatus,
6071                MI_STATUS_ENABLE_LINK_STATUS_ATTN);
6072        }
6073    }
6074
6075    /* Enable phy link change attention. */
6076    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
6077    {
6078        REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
6079    }
6080    else
6081    {
6082        REG_WR(pDevice, MacCtrl.MacEvent,
6083            MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
6084    }
6085    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
6086        (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
6087        (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
6088        (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
6089          (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
6090         !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
6091    {
6092        MM_Wait(120);
6093        REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
6094            MAC_STATUS_CFG_CHANGED);
6095        MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
6096            T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
6097    }
6098
6099    /* Indicate link status. */
6100    if (pDevice->LinkStatus != CurrentLinkStatus) {
6101        pDevice->LinkStatus = CurrentLinkStatus;
6102        MM_IndicateStatus(pDevice, CurrentLinkStatus);
6103    }
6104
6105    return LM_STATUS_SUCCESS;
6106} /* LM_SetupCopperPhy */
6107
6108/******************************************************************************/
6109/* Description:                                                               */
6110/*                                                                            */
6111/* Return:                                                                    */
6112/******************************************************************************/
6113LM_STATUS
6114LM_SetupPhy(
6115    PLM_DEVICE_BLOCK pDevice)
6116{
6117    LM_STATUS LmStatus;
6118    LM_UINT32 Value32;
6119
6120#if INCLUDE_TBI_SUPPORT
6121    if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6122    {
6123        LmStatus = LM_SetupFiberPhy(pDevice);
6124    }
6125    else
6126#endif /* INCLUDE_TBI_SUPPORT */
6127    {
6128        LmStatus = LM_SetupCopperPhy(pDevice);
6129    }
6130    if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
6131    {
6132        if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
6133        {
6134            Value32 = REG_RD(pDevice, PciCfg.PciState);
6135            REG_WR(pDevice, PciCfg.PciState,
6136                Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
6137        }
6138    }
6139    if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
6140        (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
6141    {
6142        REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
6143    }
6144    else
6145    {
6146        REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
6147    }
6148    if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6149    {
6150        if (pDevice->LinkStatus == LM_STATUS_LINK_DOWN)
6151        {
6152            REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks, 0);
6153        }
6154        else
6155        {
6156            REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
6157                pDevice->StatsCoalescingTicks);
6158        }
6159    }
6160
6161    return LmStatus;
6162}
6163
6164
6165/* test data pattern */
6166static LM_UINT32 pattern[4][6] = {
6167    /* For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
6168    For 5705   , each DFE TAP has 19-bits (low word 15, hi word 4)
6169    For simplicity, we check only 19-bits, so we don't have to
6170    distinguish which chip it is.
6171    the LO word contains 15 bits, make sure pattern data is < 0x7fff
6172    the HI word contains  6 bits, make sure pattern data is < 0x003f */
6173    {0x00005555, 0x00000005, /* ch0, TAP 0, LO/HI pattern */
6174    0x00002aaa, 0x0000000a,  /* ch0, TAP 1, LO/HI pattern */
6175    0x00003456, 0x00000003}, /* ch0, TAP 2, LO/HI pattern */
6176
6177    {0x00002aaa, 0x0000000a, /* ch1, TAP 0, LO/HI pattern */
6178    0x00003333, 0x00000003,  /* ch1, TAP 1, LO/HI pattern */
6179    0x0000789a, 0x00000005}, /* ch1, TAP 2, LO/HI pattern */
6180
6181    {0x00005a5a, 0x00000005, /* ch2, TAP 0, LO/HI pattern */
6182    0x00002a6a, 0x0000000a,  /* ch2, TAP 1, LO/HI pattern */
6183    0x00001bcd, 0x00000003}, /* ch2, TAP 2, LO/HI pattern */
6184
6185    {0x00002a5a, 0x0000000a, /* ch3, TAP 0, LO/HI pattern */
6186    0x000033c3, 0x00000003,  /* ch3, TAP 1, LO/HI pattern */
6187    0x00002ef1, 0x00000005}, /* ch3, TAP 2, LO/HI pattern */
6188};
6189
6190/********************************************************/
6191/* Routine to wait for PHY Macro Command to complete    */
6192/*                                                      */
6193/* If PHY's Macro operation keeps stay busy, nothing we */
6194/* can do anyway.  The timeout is there so we won't     */
6195/* stay in this routine indefinitly.                    */
6196/********************************************************/
6197static LM_UINT32 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice);
6198
6199static LM_UINT32
6200LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice)
6201{
6202    LM_UINT32 timeout;
6203    LM_UINT32 val32;
6204
6205    timeout = 100;
6206    while (timeout--)
6207    {
6208        /* make sure the MACRO operation is complete */
6209        LM_ReadPhy(pDevice, 0x16, &val32);
6210        if ((val32 & 0x1000) == 0) break;
6211    }
6212
6213    return( timeout > 0 );
6214}
6215
6216/********************************************************/
6217/* This routine resets the PHY on following chips:      */
6218/*      5703, 04, CIOB-E and 5705                       */
6219/*                                                      */
6220/* This routine will issue PHY_RESET and check if       */
6221/* the reset is sucessful.  If not, another PHY RESET   */
6222/* will be issued, until max "retry" reaches            */
6223/*                                                      */
6224/* Input:                                               */
6225/*      pDevice - device's context                      */
6226/*      retry   - number of retries                     */
6227/*      reset   - TRUE=will cause a PHY reset initially */
6228/*                FALSE = will not issue a PHY reset    */
6229/*                        unless TAP lockup detected    */
6230/*                                                      */
6231/* Output:                                              */
6232/*      TRUE    - PHY Reset is done sucessfully         */
6233/*      FALSE   - PHY Reset had failed, after "retry"   */
6234/*                has reached                           */
6235/*                                                      */
6236/* Dependencies:                                        */
6237/*      void LM_wait_macro_done()                       */
6238/*      u32  pattern[]                                  */
6239/*                                                      */
6240/* Usage:                                               */
6241/*      a. Before calling this routine, caller must     */
6242/*         determine if the chip is a 5702/03/04 or     */
6243/*         CIOB-E, and only call this routine if the    */
6244/*         is one of these.                             */
6245/*         or its derivatives.                          */
6246/*      b. Instead of using MII register write to reset */
6247/*         the PHY, call this routine instead           */
6248/*      c. Upon return from this routine, check return  */
6249/*         value (TRUE/FALSE) to determine if PHY reset */
6250/*         is successful of not and "optionally" take   */
6251/*         appropriate action (such as: event log)      */
6252/*      d. Regardless of the return TRUE or FALSE,      */
6253/*         proceed with PHY setup as you normally would */
6254/*         after a PHY_RESET.                           */
6255/*      e. It is recommended that the caller will give  */
6256/*         10 "retry", however, caller can change to a  */
6257/*         different number, depending on you code.     */
6258/*                                                      */
6259/********************************************************/
6260LM_STATUS LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset);
6261
6262LM_STATUS
6263LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset)
6264{
6265    LM_UINT32 val32, save9;
6266    LM_UINT32 dataLo, dataHi;
6267    int i, channel;
6268    int      reset_success = LM_STATUS_FAILURE;
6269    int      force_reset;
6270
6271    /* to actually do a PHY_RESET or not is dictated by the caller */
6272    force_reset = reset;
6273
6274    while (retry-- && (reset_success != LM_STATUS_SUCCESS))
6275    {
6276        if (force_reset)
6277        {
6278            /* issue a phy reset, and wait for reset to complete */
6279            LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
6280            for(i = 0; i < 100; i++)
6281            {
6282                MM_Wait(10);
6283
6284                LM_ReadPhy(pDevice, PHY_CTRL_REG, &val32);
6285                if(val32 && !(val32 & PHY_CTRL_PHY_RESET))
6286                {
6287                    MM_Wait(20);
6288                    break;
6289                }
6290            }
6291
6292            /* no more phy reset unless lockup detected */
6293            force_reset = FALSE;
6294        }
6295
6296        /* assuming reset is successful first */
6297        reset_success = LM_STATUS_SUCCESS;
6298
6299        /* now go check the DFE TAPs to see if locked up, but
6300           first, we need to set up PHY so we can read DFE TAPs */
6301
6302        /* Disable Transmitter and Interrupt, while we play with
6303           the PHY registers, so the link partner won't see any
6304           strange data and the Driver won't see any interrupts. */
6305        LM_ReadPhy(pDevice, 0x10, &val32);
6306        LM_WritePhy(pDevice, 0x10, val32 | 0x3000);
6307
6308        /* Setup Full-Duplex, 1000 mbps */
6309        LM_WritePhy(pDevice, 0x0, 0x0140);
6310
6311        /* Set to Master mode */
6312        LM_ReadPhy(pDevice, 0x9, &save9);
6313        LM_WritePhy(pDevice, 0x9, 0x1800);
6314
6315        /* Enable SM_DSP_CLOCK & 6dB */
6316        LM_WritePhy(pDevice, 0x18, 0x0c00);
6317
6318        /* blocks the PHY control access */
6319        LM_WritePhy(pDevice, 0x17, 0x8005);
6320        LM_WritePhy(pDevice, 0x15, 0x0800);
6321
6322        /* check TAPs for all 4 channels, as soon
6323           as we see a lockup we'll stop checking */
6324        for (channel=0; (channel<4) && (reset_success == LM_STATUS_SUCCESS);
6325            channel++)
6326        {
6327            /* select channel and set TAP index to 0 */
6328            LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6329            /* freeze filter again just to be safe */
6330            LM_WritePhy(pDevice, 0x16, 0x0002);
6331
6332            /* write fixed pattern to the RAM, 3 TAPs for
6333               each channel, each TAP have 2 WORDs (LO/HI) */
6334            for (i=0; i<6; i++)
6335                LM_WritePhy(pDevice, 0x15, pattern[channel][i]);
6336
6337            /* Activate PHY's Macro operation to write DFE TAP from RAM,
6338               and wait for Macro to complete */
6339            LM_WritePhy(pDevice, 0x16, 0x0202);
6340            if (!LM_wait_macro_done(pDevice))
6341            {
6342                reset_success = LM_STATUS_FAILURE;
6343                force_reset = TRUE;
6344                break;
6345            }
6346
6347            /* --- done with write phase, now begin read phase --- */
6348
6349            /* select channel and set TAP index to 0 */
6350            LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6351
6352            /* Active PHY's Macro operation to load DFE TAP to RAM,
6353               and wait for Macro to complete */
6354            LM_WritePhy(pDevice, 0x16, 0x0082);
6355            if (!LM_wait_macro_done(pDevice))
6356            {
6357                reset_success = LM_STATUS_FAILURE;
6358                force_reset = TRUE;
6359                break;
6360            }
6361
6362            /* enable "pre-fetch" */
6363            LM_WritePhy(pDevice, 0x16, 0x0802);
6364            if (!LM_wait_macro_done(pDevice))
6365            {
6366                reset_success = LM_STATUS_FAILURE;
6367                force_reset = TRUE;
6368                break;
6369            }
6370
6371            /* read back the TAP values.
6372               3 TAPs for each channel, each TAP have 2 WORDs (LO/HI) */
6373            for (i=0; i<6; i+=2)
6374            {
6375                /* read Lo/Hi then wait for 'done' is faster */
6376                LM_ReadPhy(pDevice, 0x15, &dataLo);
6377                LM_ReadPhy(pDevice, 0x15, &dataHi);
6378                if (!LM_wait_macro_done(pDevice))
6379                {
6380                    reset_success = LM_STATUS_FAILURE;
6381                    force_reset = TRUE;
6382                    break;
6383                }
6384
6385                /* For 5703/04, each DFE TAP has 21-bits (low word 15,
6386                 * hi word 6) For 5705, each DFE TAP pas 19-bits (low word 15,
6387                 * hi word 4) For simplicity, we check only 19-bits, so we
6388                 * don't have to distinguish which chip it is. */
6389                dataLo &= 0x7fff;
6390                dataHi &= 0x000f;
6391
6392                /* check if what we wrote is what we read back */
6393                if ( (dataLo != pattern[channel][i]) || (dataHi != pattern[channel][i+1]) )
6394                {
6395                    /* if failed, then the PHY is locked up,
6396                       we need to do PHY reset again */
6397                    reset_success = LM_STATUS_FAILURE;
6398                    force_reset = TRUE;
6399                    /* 04/25/2003. sb. do these writes before issueing a reset. */
6400                    /* these steps will reduce the chance of back-to-back
6401                     * phy lockup after reset */
6402                    LM_WritePhy(pDevice, 0x17, 0x000B);
6403                    LM_WritePhy(pDevice, 0x15, 0x4001);
6404                    LM_WritePhy(pDevice, 0x15, 0x4005);
6405                    break;
6406                }
6407            } /* for i */
6408        } /* for channel */
6409    } /* while */
6410
6411    /* restore dfe coeff back to zeros */
6412    for (channel=0; channel<4 ; channel++)
6413    {
6414        LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6415        LM_WritePhy(pDevice, 0x16, 0x0002);
6416        for (i=0; i<6; i++)
6417            LM_WritePhy(pDevice, 0x15, 0x0000);
6418        LM_WritePhy(pDevice, 0x16, 0x0202);
6419        if (!LM_wait_macro_done(pDevice))
6420        {
6421            reset_success = LM_STATUS_FAILURE;
6422            break;
6423        }
6424    }
6425
6426    /* remove block phy control */
6427    LM_WritePhy(pDevice, 0x17, 0x8005);
6428    LM_WritePhy(pDevice, 0x15, 0x0000);
6429
6430    /* unfreeze DFE TAP filter for all channels */
6431    LM_WritePhy(pDevice, 0x17, 0x8200);
6432    LM_WritePhy(pDevice, 0x16, 0x0000);
6433
6434    /* Restore PHY back to operating state */
6435    LM_WritePhy(pDevice, 0x18, 0x0400);
6436
6437    /* Restore register 9 */
6438    LM_WritePhy(pDevice, 0x9, save9);
6439
6440    /* enable transmitter and interrupt */
6441    LM_ReadPhy(pDevice, 0x10, &val32);
6442    LM_WritePhy(pDevice, 0x10, (val32 & ~0x3000));
6443
6444    return reset_success;
6445}
6446
6447LM_VOID
6448LM_ResetPhy(LM_DEVICE_BLOCK *pDevice)
6449{
6450    int j;
6451    LM_UINT32 miireg;
6452
6453    if (pDevice->PhyFlags & PHY_CHECK_TAPS_AFTER_RESET)
6454    {
6455        LM_ResetPhy_5703_4_5(pDevice, 5, 1);
6456    }
6457    else
6458    {
6459        LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
6460
6461        for(j = 0; j < 100; j++)
6462        {
6463            MM_Wait(10);
6464
6465            LM_ReadPhy(pDevice, PHY_CTRL_REG, &miireg);
6466            if(miireg && !(miireg & PHY_CTRL_PHY_RESET))
6467            {
6468                MM_Wait(20);
6469                break;
6470            }
6471        }
6472        LM_PhyTapPowerMgmt(pDevice);
6473    }
6474    if (pDevice->PhyFlags & PHY_ADC_FIX)
6475    {
6476        LM_WritePhy(pDevice, 0x18, 0x0c00);
6477        LM_WritePhy(pDevice, 0x17, 0x201f);
6478        LM_WritePhy(pDevice, 0x15, 0x2aaa);
6479        LM_WritePhy(pDevice, 0x17, 0x000a);
6480        LM_WritePhy(pDevice, 0x15, 0x0323);
6481        LM_WritePhy(pDevice, 0x18, 0x0400);
6482    }
6483    if (pDevice->PhyFlags & PHY_5705_5750_FIX)
6484    {
6485        LM_WritePhy(pDevice, 0x18, 0x0c00);
6486        LM_WritePhy(pDevice, 0x17, 0x000a);
6487        LM_WritePhy(pDevice, 0x15, 0x310b);
6488        LM_WritePhy(pDevice, 0x17, 0x201f);
6489        LM_WritePhy(pDevice, 0x15, 0x9506);
6490        LM_WritePhy(pDevice, 0x17, 0x401f);
6491        LM_WritePhy(pDevice, 0x15, 0x14e2);
6492        LM_WritePhy(pDevice, 0x18, 0x0400);
6493    }
6494    if (pDevice->PhyFlags & PHY_5704_A0_FIX)
6495    {
6496        LM_WritePhy(pDevice, 0x1c, 0x8d68);
6497        LM_WritePhy(pDevice, 0x1c, 0x8d68);
6498    }
6499    if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6500    {
6501        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
6502    }
6503    else if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6504    {
6505        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
6506        LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &miireg);
6507        miireg |= 0x4000;    /* set extended packet length */
6508        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, miireg);
6509    }
6510
6511    LM_SetEthWireSpeed(pDevice);
6512}
6513
6514STATIC LM_VOID
6515LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice)
6516{
6517    LM_UINT32 Value32;
6518
6519    /* Enable Ethernet@WireSpeed. */
6520    if (pDevice->PhyFlags & PHY_ETHERNET_WIRESPEED)
6521    {
6522        LM_WritePhy(pDevice, 0x18, 0x7007);
6523        LM_ReadPhy(pDevice, 0x18, &Value32);
6524        LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
6525    }
6526}
6527
6528STATIC LM_STATUS
6529LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice)
6530{
6531    LM_UINT32 miireg;
6532
6533    LM_ReadPhy(pDevice, PHY_AN_AD_REG, &miireg);
6534    pDevice->advertising = miireg;
6535    if ((miireg & PHY_AN_AD_ALL_SPEEDS) != PHY_AN_AD_ALL_SPEEDS)
6536    {
6537        return LM_STATUS_FAILURE;
6538    }
6539    if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
6540    {
6541        LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &miireg);
6542        pDevice->advertising1000 = miireg;
6543        if ((miireg & BCM540X_AN_AD_ALL_1G_SPEEDS) !=
6544            BCM540X_AN_AD_ALL_1G_SPEEDS)
6545        {
6546            return LM_STATUS_FAILURE;
6547        }
6548    }
6549    return LM_STATUS_SUCCESS;
6550}
6551
6552/******************************************************************************/
6553/* Description:                                                               */
6554/*                                                                            */
6555/* Return:                                                                    */
6556/******************************************************************************/
6557LM_VOID
6558LM_ReadPhy(
6559PLM_DEVICE_BLOCK pDevice,
6560LM_UINT32 PhyReg,
6561PLM_UINT32 pData32) {
6562    LM_UINT32 Value32;
6563    LM_UINT32 j;
6564
6565    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6566    {
6567        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
6568            ~MI_MODE_AUTO_POLLING_ENABLE);
6569        REG_RD_BACK(pDevice, MacCtrl.MiMode);
6570        MM_Wait(40);
6571    }
6572
6573    Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
6574        ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
6575        MI_COM_CMD_READ | MI_COM_START;
6576
6577    REG_WR(pDevice, MacCtrl.MiCom, Value32);
6578
6579    for(j = 0; j < 200; j++)
6580    {
6581        MM_Wait(1);
6582
6583        Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6584
6585        if(!(Value32 & MI_COM_BUSY))
6586        {
6587            MM_Wait(5);
6588            Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6589            Value32 &= MI_COM_PHY_DATA_MASK;
6590            break;
6591        }
6592    }
6593
6594    if(Value32 & MI_COM_BUSY)
6595    {
6596        Value32 = 0;
6597    }
6598
6599    *pData32 = Value32;
6600
6601    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6602    {
6603        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6604        REG_RD_BACK(pDevice, MacCtrl.MiMode);
6605        MM_Wait(40);
6606    }
6607} /* LM_ReadPhy */
6608
6609
6610
6611/******************************************************************************/
6612/* Description:                                                               */
6613/*                                                                            */
6614/* Return:                                                                    */
6615/******************************************************************************/
6616LM_VOID
6617LM_WritePhy(
6618PLM_DEVICE_BLOCK pDevice,
6619LM_UINT32 PhyReg,
6620LM_UINT32 Data32) {
6621    LM_UINT32 Value32;
6622    LM_UINT32 j;
6623
6624    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6625    {
6626        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
6627            ~MI_MODE_AUTO_POLLING_ENABLE);
6628        REG_RD_BACK(pDevice, MacCtrl.MiMode);
6629        MM_Wait(40);
6630    }
6631
6632    Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
6633        ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
6634        (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
6635
6636    REG_WR(pDevice, MacCtrl.MiCom, Value32);
6637
6638    for(j = 0; j < 200; j++)
6639    {
6640        MM_Wait(1);
6641
6642        Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6643
6644        if(!(Value32 & MI_COM_BUSY))
6645        {
6646            MM_Wait(5);
6647            break;
6648        }
6649    }
6650
6651    if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6652    {
6653        REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6654        REG_RD_BACK(pDevice, MacCtrl.MiMode);
6655        MM_Wait(40);
6656    }
6657} /* LM_WritePhy */
6658
6659STATIC void
6660LM_GetPhyId(LM_DEVICE_BLOCK *pDevice)
6661{
6662    LM_UINT32 Value32;
6663
6664    LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
6665    pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
6666
6667    LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
6668    pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
6669        (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
6670}
6671
6672LM_STATUS
6673LM_EnableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
6674{
6675    pDevice->LoopBackMode = LM_MAC_LOOP_BACK_MODE;
6676    pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
6677    pDevice->MacMode |= MAC_MODE_PORT_INTERNAL_LOOPBACK |
6678        MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
6679    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6680    LM_SetupPhy(pDevice);
6681    return LM_STATUS_SUCCESS;
6682}
6683
6684LM_STATUS
6685LM_DisableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
6686{
6687    pDevice->LoopBackMode = 0;
6688    pDevice->MacMode &= ~(MAC_MODE_PORT_INTERNAL_LOOPBACK |
6689        MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_MASK);
6690    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6691    LM_SetupPhy(pDevice);
6692    return LM_STATUS_SUCCESS;
6693}
6694
6695LM_STATUS
6696LM_EnablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
6697{
6698    pDevice->LoopBackMode = LM_PHY_LOOP_BACK_MODE;
6699    LM_SetupPhy(pDevice);
6700    return LM_STATUS_SUCCESS;
6701}
6702
6703LM_STATUS
6704LM_DisablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
6705{
6706    pDevice->LoopBackMode = 0;
6707    LM_SetupPhy(pDevice);
6708    return LM_STATUS_SUCCESS;
6709}
6710
6711LM_STATUS
6712LM_EnableExtLoopBack(PLM_DEVICE_BLOCK pDevice, LM_LINE_SPEED LineSpeed)
6713{
6714    pDevice->LoopBackMode = LM_EXT_LOOP_BACK_MODE;
6715
6716    pDevice->SavedDisableAutoNeg = pDevice->DisableAutoNeg;
6717    pDevice->SavedRequestedLineSpeed = pDevice->RequestedLineSpeed;
6718    pDevice->SavedRequestedDuplexMode = pDevice->RequestedDuplexMode;
6719
6720    pDevice->DisableAutoNeg = TRUE;
6721    pDevice->RequestedLineSpeed = LineSpeed;
6722    pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
6723    LM_SetupPhy(pDevice);
6724    return LM_STATUS_SUCCESS;
6725}
6726
6727LM_STATUS
6728LM_DisableExtLoopBack(PLM_DEVICE_BLOCK pDevice)
6729{
6730    pDevice->LoopBackMode = 0;
6731
6732    pDevice->DisableAutoNeg = pDevice->SavedDisableAutoNeg;
6733    pDevice->RequestedLineSpeed = pDevice->SavedRequestedLineSpeed;
6734    pDevice->RequestedDuplexMode = pDevice->SavedRequestedDuplexMode;
6735
6736    LM_SetupPhy(pDevice);
6737    return LM_STATUS_SUCCESS;
6738}
6739
6740/******************************************************************************/
6741/* Description:                                                               */
6742/*                                                                            */
6743/* Return:                                                                    */
6744/******************************************************************************/
6745LM_STATUS
6746LM_SetPowerState(
6747PLM_DEVICE_BLOCK pDevice,
6748LM_POWER_STATE PowerLevel)
6749{
6750#ifdef BCM_WOL
6751    LM_UINT32 PmeSupport;
6752    PLM_DEVICE_BLOCK pDevice2 = 0;
6753    int j;
6754#endif
6755    LM_UINT32 Value32;
6756    LM_UINT32 PmCtrl;
6757
6758    /* make sureindirect accesses are enabled*/
6759    MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
6760
6761    /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
6762    /* the PME bit. */
6763    MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
6764
6765    PmCtrl |= T3_PM_PME_ASSERTED;
6766    PmCtrl &= ~T3_PM_POWER_STATE_MASK;
6767
6768    /* Set the appropriate power state. */
6769    if(PowerLevel == LM_POWER_STATE_D0)
6770    {
6771
6772        /* Bring the card out of low power mode. */
6773        PmCtrl |= T3_PM_POWER_STATE_D0;
6774        MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
6775
6776        Value32 = REG_RD(pDevice, Grc.LocalCtrl);
6777        RAW_REG_WR(pDevice, Grc.LocalCtrl, Value32 &
6778            ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
6779              GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
6780              GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
6781              GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
6782              GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
6783              GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2));
6784
6785        MM_Wait(40);    /* Required delay is about 20us. */
6786
6787        pDevice->PowerLevel = PowerLevel;
6788        return LM_STATUS_SUCCESS;
6789    }
6790#ifdef BCM_WOL
6791    else if(PowerLevel == LM_POWER_STATE_D1)
6792    {
6793        PmCtrl |= T3_PM_POWER_STATE_D1;
6794    }
6795    else if(PowerLevel == LM_POWER_STATE_D2)
6796    {
6797        PmCtrl |= T3_PM_POWER_STATE_D2;
6798    }
6799    else if(PowerLevel == LM_POWER_STATE_D3)
6800    {
6801        PmCtrl |= T3_PM_POWER_STATE_D3;
6802    }
6803    else
6804    {
6805        return LM_STATUS_FAILURE;
6806    }
6807    PmCtrl |= T3_PM_PME_ENABLE;
6808
6809    /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
6810    /* setting new line speed. */
6811    Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
6812    REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
6813
6814    if(!pDevice->RestoreOnWakeUp)
6815    {
6816        pDevice->RestoreOnWakeUp = TRUE;
6817        pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
6818        pDevice->WakeUpRequestedLineSpeed = pDevice->RequestedLineSpeed;
6819        pDevice->WakeUpRequestedDuplexMode = pDevice->RequestedDuplexMode;
6820    }
6821
6822    /* Force auto-negotiation to 10 line speed. */
6823    pDevice->DisableAutoNeg = FALSE;
6824
6825    if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
6826    {
6827        pDevice->RequestedLineSpeed = LM_LINE_SPEED_10MBPS;
6828        LM_SetupPhy(pDevice);
6829    }
6830
6831    /* Put the driver in the initial state, and go through the power down */
6832    /* sequence. */
6833    LM_DoHalt(pDevice);
6834
6835    if (!(pDevice->AsfFlags & ASF_ENABLED))
6836    {
6837        for(j = 0; j < 20000; j++)
6838        {
6839            MM_Wait(10);
6840
6841            Value32 = MEM_RD_OFFSET(pDevice, T3_ASF_FW_STATUS_MAILBOX);
6842            if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
6843            {
6844                break;
6845            }
6846        }
6847    }
6848
6849    MEM_WR_OFFSET(pDevice, DRV_WOL_MAILBOX, DRV_WOL_SIGNATURE |
6850        DRV_DOWN_STATE_SHUTDOWN | 0x2 | DRV_WOL_SET_MAGIC_PKT);
6851
6852    MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
6853
6854    if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
6855    {
6856
6857        /* Enable WOL. */
6858        if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
6859        {
6860            LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
6861            MM_Wait(40);
6862        }
6863
6864        if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
6865        {
6866            /* Let boot code deal with LED mode on shasta */
6867            REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
6868        }
6869
6870        if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6871        {
6872            Value32 = MAC_MODE_PORT_MODE_TBI;
6873        }
6874        else
6875        {
6876            Value32 = MAC_MODE_PORT_MODE_MII;
6877            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
6878            {
6879                if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_2 ||
6880                    pDevice->WolSpeed == WOL_SPEED_10MB)
6881                {
6882                    Value32 |= MAC_MODE_LINK_POLARITY;
6883                }
6884            }
6885            else
6886            {
6887                Value32 |= MAC_MODE_LINK_POLARITY;
6888            }
6889        }
6890        REG_WR(pDevice, MacCtrl.Mode, Value32);
6891        REG_RD_BACK(pDevice, MacCtrl.Mode);
6892        MM_Wait(40); MM_Wait(40); MM_Wait(40);
6893
6894        /* Always enable magic packet wake-up if we have vaux. */
6895        if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
6896            (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
6897        {
6898            Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
6899        }
6900
6901#ifdef BCM_ASF
6902        if (pDevice->AsfFlags & ASF_ENABLED)
6903        {
6904            Value32 &= ~MAC_MODE_ACPI_POWER_ON_ENABLE;
6905        }
6906#endif
6907        REG_WR(pDevice, MacCtrl.Mode, Value32);
6908
6909        /* Enable the receiver. */
6910        REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
6911    }
6912    else if (!(pDevice->AsfFlags & ASF_ENABLED))
6913    {
6914        if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6915        {
6916            REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
6917                LED_CTRL_OVERRIDE_TRAFFIC_LED);
6918        }
6919        else
6920        {
6921            LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
6922                BCM540X_EXT_CTRL_FORCE_LED_OFF);
6923            LM_WritePhy(pDevice, 0x18, 0x01b2);
6924            if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
6925                (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
6926                (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
6927            {
6928                LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOWER_POWER_MODE);
6929            }
6930        }
6931    }
6932
6933    /* Disable tx/rx clocks, and select an alternate clock. */
6934    if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
6935        ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
6936        (pDevice->WolSpeed == WOL_SPEED_10MB)))
6937    {
6938        Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6939            T3_PCI_SELECT_ALTERNATE_CLOCK |
6940            T3_PCI_POWER_DOWN_PCI_PLL133;
6941
6942        REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6943    }
6944    /* ASF on 5750 will not run properly on slow core clock */
6945    else if (!((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750) &&
6946        (pDevice->AsfFlags & ASF_ENABLED)))
6947    {
6948        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6949        {
6950            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6951                T3_PCI_SELECT_ALTERNATE_CLOCK;
6952        }
6953        else if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6954        {
6955            Value32 = T3_PCI_625_CORE_CLOCK;
6956        }
6957        else
6958        {
6959            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
6960        }
6961        RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6962
6963        MM_Wait(40);
6964
6965        if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
6966            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6967        {
6968            Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6969                T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
6970        }
6971        else if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6972        {
6973            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_625_CORE_CLOCK;
6974        }
6975        else
6976        {
6977            Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
6978        }
6979
6980        RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6981
6982        if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6983        {
6984            MM_Wait(40);
6985
6986            if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
6987                T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6988            {
6989                Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6990                    T3_PCI_44MHZ_CORE_CLOCK;
6991            }
6992            else
6993            {
6994                Value32 = T3_PCI_44MHZ_CORE_CLOCK;
6995            }
6996
6997            RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6998        }
6999    }
7000
7001    MM_Wait(40);
7002
7003    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
7004    {
7005        pDevice2 = MM_FindPeerDev(pDevice);
7006    }
7007    if (!(pDevice->Flags & EEPROM_WP_FLAG))
7008    {
7009        LM_SwitchVaux(pDevice, pDevice2);
7010    }
7011
7012    LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
7013
7014    /* Set the phy to low power mode. */
7015    /* Put the the hardware in low power mode. */
7016    if (!(pDevice->Flags & DISABLE_D3HOT_FLAG))
7017    {
7018        MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
7019    }
7020
7021    pDevice->PowerLevel = PowerLevel;
7022
7023#else
7024    LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
7025#endif /* BCM_WOL */
7026
7027    return LM_STATUS_SUCCESS;
7028} /* LM_SetPowerState */
7029
7030
7031LM_VOID
7032LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2)
7033{
7034    pDevice->GrcLocalCtrl &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7035                               GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7036                               GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7037                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7038                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7039                               GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7040
7041    /* Switch adapter to auxilliary power if WOL enabled */
7042    if ((pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
7043        (pDevice->AsfFlags & ASF_ENABLED) ||
7044        (pDevice2 && ((pDevice2->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
7045        (pDevice2->AsfFlags & ASF_ENABLED))))
7046    {
7047        if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
7048            T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
7049        {
7050            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
7051            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7052                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7053                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7054                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7055                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7056                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7057            MM_Wait(40);
7058        }
7059        else
7060        {
7061            if (pDevice2 && pDevice2->InitDone)
7062            {
7063                return;
7064            }
7065
7066            /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
7067            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7068                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7069                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7070                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7071                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7072                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7073            MM_Wait(40);
7074
7075            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
7076            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7077                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7078                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7079                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7080                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7081                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7082                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7083            MM_Wait(40);
7084
7085            /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
7086            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7087                GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7088                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7089                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7090                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7091                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7092            MM_Wait(40);
7093        }
7094    }
7095    else /* WOL disabled */
7096    {
7097        if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
7098            (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
7099        {
7100            if (pDevice2 && pDevice2->InitDone)
7101            {
7102                return;
7103            }
7104
7105            /* GPIO1 = 1 */
7106            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7107                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7108                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7109            MM_Wait(40);
7110
7111            /* GPIO1 = 0 */
7112            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7113                GRC_MISC_LOCAL_CTRL_GPIO_OE1);
7114            MM_Wait(40);
7115
7116            /* GPIO1 = 1 */
7117            RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7118                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7119                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7120            MM_Wait(40);
7121        }
7122    }
7123}
7124
7125
7126/******************************************************************************/
7127/* Description:                                                               */
7128/*                                                                            */
7129/* Return:                                                                    */
7130/******************************************************************************/
7131static LM_UINT32
7132GetPhyAdFlowCntrlSettings(
7133    PLM_DEVICE_BLOCK pDevice)
7134{
7135    LM_UINT32 Value32;
7136
7137    Value32 = 0;
7138
7139    /* Auto negotiation flow control only when autonegotiation is enabled. */
7140    if(pDevice->DisableAutoNeg == FALSE ||
7141        pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
7142    {
7143        /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
7144        if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
7145            ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
7146            (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
7147        {
7148            Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
7149        }
7150        else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
7151        {
7152            Value32 |= PHY_AN_AD_ASYM_PAUSE;
7153        }
7154        else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
7155        {
7156            Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
7157        }
7158    }
7159
7160    return Value32;
7161}
7162
7163
7164
7165/******************************************************************************/
7166/* Description:                                                               */
7167/*                                                                            */
7168/* Return:                                                                    */
7169/*    LM_STATUS_FAILURE                                                       */
7170/*    LM_STATUS_SUCCESS                                                       */
7171/*                                                                            */
7172/******************************************************************************/
7173static LM_STATUS
7174LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice)
7175{
7176    LM_LINE_SPEED LineSpeed;
7177    LM_DUPLEX_MODE DuplexMode;
7178    LM_UINT32 NewPhyCtrl;
7179    LM_UINT32 Value32, PhyReg18;
7180    LM_UINT32 Cnt;
7181
7182    /* Get the interface type, line speed, and duplex mode. */
7183    LineSpeed = pDevice->RequestedLineSpeed;
7184    DuplexMode = pDevice->RequestedDuplexMode;
7185
7186    /* Exit ext. loop back, in case it was in ext. loopback mode */
7187    /* Set Extended packet length bit on chips that support jumbo frames */
7188    if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
7189    {
7190        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
7191    }
7192    else
7193    {
7194        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
7195        LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
7196        PhyReg18 &= ~0x8000;       /* clear external loop back */
7197        if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7198        {
7199            PhyReg18 |= 0x4000;    /* set extended packet length */
7200        }
7201        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
7202    }
7203
7204#ifdef BCM_WOL
7205    if (pDevice->RestoreOnWakeUp)
7206    {
7207        LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7208        pDevice->advertising1000 = 0;
7209        Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
7210        if (pDevice->WolSpeed == WOL_SPEED_100MB)
7211        {
7212            Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
7213        }
7214        Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7215        Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7216        LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7217        pDevice->advertising = Value32;
7218    }
7219    /* Setup the auto-negotiation advertisement register. */
7220    else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
7221#else
7222    /* Setup the auto-negotiation advertisement register. */
7223    if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
7224#endif
7225    {
7226        /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
7227        Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD | PHY_AN_AD_ALL_SPEEDS;
7228        Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7229
7230        LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7231        pDevice->advertising = Value32;
7232
7233        /* Advertise 1000Mbps */
7234        if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
7235        {
7236            Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS;
7237
7238#if INCLUDE_5701_AX_FIX
7239            /* Bug: workaround for CRC error in gigabit mode when we are in */
7240            /* slave mode.  This will force the PHY to operate in */
7241            /* master mode. */
7242            if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
7243                pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
7244            {
7245                Value32 |= BCM540X_CONFIG_AS_MASTER |
7246                    BCM540X_ENABLE_CONFIG_AS_MASTER;
7247            }
7248#endif
7249
7250            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
7251            pDevice->advertising1000 = Value32;
7252        }
7253    }
7254    else
7255    {
7256        if ((pDevice->PhyFlags & PHY_NO_GIGABIT) &&
7257            (LineSpeed == LM_LINE_SPEED_1000MBPS))
7258        {
7259            LineSpeed = LM_LINE_SPEED_100MBPS;
7260        }
7261        if(LineSpeed == LM_LINE_SPEED_1000MBPS)
7262        {
7263            Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7264            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7265
7266            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7267            pDevice->advertising = Value32;
7268
7269            if(DuplexMode != LM_DUPLEX_MODE_FULL)
7270            {
7271                Value32 = BCM540X_AN_AD_1000BASET_HALF;
7272            }
7273            else
7274            {
7275                Value32 = BCM540X_AN_AD_1000BASET_FULL;
7276            }
7277
7278#if INCLUDE_5701_AX_FIX
7279            if ((pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE) ||
7280                (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
7281                pDevice->ChipRevId == T3_CHIP_ID_5701_B0))
7282#else
7283            if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
7284#endif
7285            {
7286                Value32 |= BCM540X_CONFIG_AS_MASTER |
7287                    BCM540X_ENABLE_CONFIG_AS_MASTER;
7288            }
7289            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
7290            pDevice->advertising1000 = Value32;
7291            if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
7292            {
7293                if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
7294                {
7295                    LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x8c20);
7296                }
7297                else
7298                {
7299                    LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
7300                    LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
7301                    Value32 |= 0x8000;    /* set loop back */
7302                    LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
7303                }
7304            }
7305        }
7306        else if(LineSpeed == LM_LINE_SPEED_100MBPS)
7307        {
7308            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7309            pDevice->advertising1000 = 0;
7310
7311            if(DuplexMode != LM_DUPLEX_MODE_FULL)
7312            {
7313                Value32 = PHY_AN_AD_100BASETX_HALF;
7314            }
7315            else
7316            {
7317                Value32 = PHY_AN_AD_100BASETX_FULL;
7318            }
7319
7320            Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7321            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7322
7323            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7324            pDevice->advertising = Value32;
7325        }
7326        else if(LineSpeed == LM_LINE_SPEED_10MBPS)
7327        {
7328            LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7329            pDevice->advertising1000 = 0;
7330
7331            if(DuplexMode != LM_DUPLEX_MODE_FULL)
7332            {
7333                Value32 = PHY_AN_AD_10BASET_HALF;
7334            }
7335            else
7336            {
7337                Value32 = PHY_AN_AD_10BASET_FULL;
7338            }
7339
7340            Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7341            Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7342
7343            LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7344            pDevice->advertising = Value32;
7345        }
7346    }
7347
7348    /* Force line speed if auto-negotiation is disabled. */
7349    if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
7350    {
7351        /* This code path is executed only when there is link. */
7352        pDevice->LineSpeed = LineSpeed;
7353        pDevice->DuplexMode = DuplexMode;
7354
7355        /* Force line seepd. */
7356        NewPhyCtrl = 0;
7357        switch(LineSpeed)
7358        {
7359            case LM_LINE_SPEED_10MBPS:
7360                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
7361                break;
7362            case LM_LINE_SPEED_100MBPS:
7363                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
7364                break;
7365            case LM_LINE_SPEED_1000MBPS:
7366                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
7367                break;
7368            default:
7369                NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
7370                break;
7371        }
7372
7373        if(DuplexMode == LM_DUPLEX_MODE_FULL)
7374        {
7375            NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
7376        }
7377
7378        /* Don't do anything if the PHY_CTRL is already what we wanted. */
7379        LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7380        if(Value32 != NewPhyCtrl)
7381        {
7382            /* Temporary bring the link down before forcing line speed. */
7383            LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
7384
7385            /* Wait for link to go down. */
7386            for(Cnt = 0; Cnt < 1500; Cnt++)
7387            {
7388                MM_Wait(10);
7389
7390                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7391                LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7392
7393                if(!(Value32 & PHY_STATUS_LINK_PASS))
7394                {
7395                    MM_Wait(40);
7396                    break;
7397                }
7398            }
7399
7400            LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
7401            MM_Wait(40);
7402        }
7403    }
7404    else
7405    {
7406        LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
7407            PHY_CTRL_RESTART_AUTO_NEG);
7408    }
7409
7410    return LM_STATUS_SUCCESS;
7411} /* LM_ForceAutoNegBcm540xPhy */
7412
7413/******************************************************************************/
7414/* Description:                                                               */
7415/*                                                                            */
7416/* Return:                                                                    */
7417/******************************************************************************/
7418LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
7419                          PT3_FWIMG_INFO pFwImg,
7420                          LM_UINT32 LoadCpu,
7421                          LM_UINT32 StartCpu)
7422{
7423    LM_UINT32 i;
7424    LM_UINT32 address;
7425    LM_VOID (*Wr_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32);
7426    LM_UINT32 (*Rd_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register);
7427    LM_UINT32 len;
7428    LM_UINT32 base_addr;
7429
7430#if INCLUDE_TCP_SEG_SUPPORT
7431    if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
7432      {
7433	Wr_fn = LM_MemWrInd;
7434	Rd_fn = LM_MemRdInd;
7435	len = LM_GetStkOffLdFirmwareSize(pDevice);
7436	base_addr = T3_NIC_BCM5705_MBUF_POOL_ADDR;
7437      }
7438    else
7439#endif
7440      {
7441	Wr_fn = LM_RegWrInd;
7442	Rd_fn = LM_RegRdInd;
7443	len = T3_RX_CPU_SPAD_SIZE;
7444	base_addr = T3_RX_CPU_SPAD_ADDR;
7445      }
7446
7447    if (LoadCpu & T3_RX_CPU_ID)
7448    {
7449        if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
7450        {
7451            return LM_STATUS_FAILURE;
7452        }
7453
7454        /* First of all clear scrach pad memory */
7455        for (i = 0; i < len; i+=4)
7456        {
7457	    Wr_fn(pDevice,base_addr+i,0);
7458        }
7459
7460        /* Copy code first */
7461        address = base_addr + (pFwImg->Text.Offset & 0xffff);
7462        for (i = 0; i <= pFwImg->Text.Length; i+=4)
7463        {
7464            Wr_fn(pDevice,address+i,
7465                        ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
7466        }
7467
7468        address = base_addr + (pFwImg->ROnlyData.Offset & 0xffff);
7469        for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
7470        {
7471            Wr_fn(pDevice,address+i,
7472                        ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
7473        }
7474
7475        address = base_addr + (pFwImg->Data.Offset & 0xffff);
7476        for (i= 0; i <= pFwImg->Data.Length; i+=4)
7477        {
7478            Wr_fn(pDevice,address+i,
7479                        ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
7480        }
7481    }
7482
7483    if ((LoadCpu & T3_TX_CPU_ID) &&
7484        (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
7485    {
7486        if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
7487        {
7488            return LM_STATUS_FAILURE;
7489        }
7490
7491        /* First of all clear scrach pad memory */
7492        for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
7493        {
7494            Wr_fn(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
7495        }
7496
7497        /* Copy code first */
7498        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
7499        for (i= 0; i <= pFwImg->Text.Length; i+=4)
7500        {
7501            Wr_fn(pDevice,address+i,
7502                        ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
7503        }
7504
7505        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
7506        for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
7507        {
7508            Wr_fn(pDevice,address+i,
7509                        ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
7510        }
7511
7512        address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
7513        for (i= 0; i <= pFwImg->Data.Length; i+=4)
7514        {
7515            Wr_fn(pDevice,address+i,
7516                        ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
7517        }
7518    }
7519
7520    if (StartCpu & T3_RX_CPU_ID)
7521    {
7522        /* Start Rx CPU */
7523        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7524        REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
7525        for (i = 0 ; i < 5; i++)
7526        {
7527          if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
7528             break;
7529
7530          REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7531          REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7532          REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
7533          REG_RD_BACK(pDevice,rxCpu.reg.PC);
7534          MM_Wait(1000);
7535        }
7536
7537        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7538        REG_WR(pDevice,rxCpu.reg.mode, 0);
7539    }
7540
7541    if ((StartCpu & T3_TX_CPU_ID) &&
7542        (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
7543    {
7544        /* Start Tx CPU */
7545        REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7546        REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
7547        for (i = 0 ; i < 5; i++)
7548        {
7549          if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
7550             break;
7551
7552          REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7553          REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
7554          REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
7555          REG_RD_BACK(pDevice,txCpu.reg.PC);
7556          MM_Wait(1000);
7557        }
7558
7559        REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7560        REG_WR(pDevice,txCpu.reg.mode, 0);
7561    }
7562
7563    return LM_STATUS_SUCCESS;
7564}
7565
7566LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
7567{
7568    LM_UINT32 i;
7569
7570    if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
7571       (cpu_number != T3_RX_CPU_ID))
7572    {
7573        return LM_STATUS_SUCCESS;
7574    }
7575
7576    if (cpu_number == T3_RX_CPU_ID)
7577    {
7578        for (i = 0 ; i < 10000; i++)
7579        {
7580            REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7581            REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7582
7583            if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
7584              break;
7585        }
7586
7587        REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7588        REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7589        REG_RD_BACK(pDevice,rxCpu.reg.mode);
7590        MM_Wait(10);
7591    }
7592    else
7593    {
7594        for (i = 0 ; i < 10000; i++)
7595        {
7596            REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7597            REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
7598
7599            if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
7600               break;
7601        }
7602    }
7603
7604  return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
7605}
7606
7607
7608LM_STATUS
7609LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
7610{
7611	int j;
7612	int ret = LM_STATUS_SUCCESS;
7613
7614	if(BlinkDurationSec == 0)
7615	{
7616		BlinkDurationSec = 1;
7617        }
7618	if(BlinkDurationSec > 120)
7619        {
7620	        BlinkDurationSec = 120;
7621	}
7622
7623	for(j = 0; j < BlinkDurationSec * 2; j++)
7624	{
7625		if(j % 2)
7626		{
7627			// Turn on the LEDs.
7628			REG_WR(pDevice, MacCtrl.LedCtrl,
7629				LED_CTRL_OVERRIDE_LINK_LED |
7630				LED_CTRL_1000MBPS_LED_ON |
7631				LED_CTRL_100MBPS_LED_ON |
7632				LED_CTRL_10MBPS_LED_ON |
7633				LED_CTRL_OVERRIDE_TRAFFIC_LED |
7634				LED_CTRL_BLINK_TRAFFIC_LED |
7635				LED_CTRL_TRAFFIC_LED);
7636		}
7637		else
7638		{
7639			// Turn off the LEDs.
7640			REG_WR(pDevice, MacCtrl.LedCtrl,
7641				LED_CTRL_OVERRIDE_LINK_LED |
7642				LED_CTRL_OVERRIDE_TRAFFIC_LED);
7643		}
7644                if (MM_Sleep(pDevice, 500) != LM_STATUS_SUCCESS)/* 0.5 second */
7645                {
7646                    ret = LM_STATUS_FAILURE;
7647                    break;
7648                }
7649	}
7650	REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
7651	return ret;
7652}
7653
7654LM_STATUS
7655LM_SwitchClocks(PLM_DEVICE_BLOCK pDevice)
7656{
7657    LM_UINT32 ClockCtrl;
7658
7659    ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl);
7660    pDevice->ClockCtrl = ClockCtrl & (T3_PCI_FORCE_CLKRUN |
7661        T3_PCI_CLKRUN_OUTPUT_EN | 0x1f);
7662    if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7663    {
7664        if (ClockCtrl & T3_PCI_625_CORE_CLOCK)
7665        {
7666            /* clear ALT clock first */
7667            RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7668                T3_PCI_625_CORE_CLOCK);
7669            MM_Wait(40);  /* required delay is 27usec */
7670        }
7671    }
7672    else
7673    {
7674        if (ClockCtrl & T3_PCI_44MHZ_CORE_CLOCK)
7675        {
7676            RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7677                T3_PCI_44MHZ_CORE_CLOCK | T3_PCI_SELECT_ALTERNATE_CLOCK);
7678            MM_Wait(40);  /* required delay is 27usec */
7679            RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7680                T3_PCI_SELECT_ALTERNATE_CLOCK);
7681            MM_Wait(40);  /* required delay is 27usec */
7682        }
7683    }
7684
7685    RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
7686    MM_Wait(40);  /* required delay is 27usec */
7687    return LM_STATUS_SUCCESS;
7688}
7689
7690int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
7691                   LM_PHYSICAL_ADDRESS host_addr_phy, int length,
7692                   int dma_read)
7693{
7694    T3_DMA_DESC dma_desc;
7695    int i;
7696    LM_UINT32 dma_desc_addr;
7697    LM_UINT32 value32;
7698
7699    REG_WR(pDevice, BufMgr.Mode, 0);
7700    REG_WR(pDevice, Ftq.Reset, 0);
7701
7702    dma_desc.host_addr.High = host_addr_phy.High;
7703    dma_desc.host_addr.Low = host_addr_phy.Low;
7704    dma_desc.nic_mbuf = 0x2100;
7705    dma_desc.len = length;
7706    dma_desc.flags = 0x00000005; /* Generate Rx-CPU event */
7707
7708    if (dma_read)
7709    {
7710        dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
7711            T3_QID_DMA_HIGH_PRI_READ;
7712        REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
7713    }
7714    else
7715    {
7716        dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
7717            T3_QID_DMA_HIGH_PRI_WRITE;
7718        REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
7719    }
7720
7721    dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
7722
7723    /* Writing this DMA descriptor to DMA memory */
7724    for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
7725    {
7726        value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
7727        MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
7728        MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG,
7729            MM_SWAP_LE32(value32));
7730    }
7731    MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
7732
7733    if (dma_read)
7734        REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
7735    else
7736        REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
7737
7738    for (i = 0; i < 40; i++)
7739    {
7740        if (dma_read)
7741            value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
7742        else
7743            value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
7744
7745        if ((value32 & 0xffff) == dma_desc_addr)
7746            break;
7747
7748        MM_Wait(10);
7749    }
7750
7751    return LM_STATUS_SUCCESS;
7752}
7753
7754STATIC LM_STATUS
7755LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
7756           LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
7757{
7758    int j;
7759    LM_UINT32 *ptr;
7760    int dma_success = 0;
7761    LM_STATUS ret = LM_STATUS_FAILURE;
7762
7763    if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
7764        T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
7765    {
7766        return LM_STATUS_SUCCESS;
7767    }
7768    while (!dma_success)
7769    {
7770        /* Fill data with incremental patterns */
7771        ptr = (LM_UINT32 *)pBufferVirt;
7772        for (j = 0; j < BufferSize/4; j++)
7773            *ptr++ = j;
7774
7775        if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
7776        {
7777            goto LM_DmaTestDone;
7778        }
7779
7780        MM_Wait(40);
7781        ptr = (LM_UINT32 *)pBufferVirt;
7782        /* Fill data with zero */
7783        for (j = 0; j < BufferSize/4; j++)
7784            *ptr++ = 0;
7785
7786        if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
7787        {
7788            goto LM_DmaTestDone;
7789        }
7790
7791        MM_Wait(40);
7792        /* Check for data */
7793        ptr = (LM_UINT32 *)pBufferVirt;
7794        for (j = 0; j < BufferSize/4; j++)
7795        {
7796            if (*ptr++ != j)
7797            {
7798                if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
7799                    != DMA_CTRL_WRITE_BOUNDARY_16)
7800                {
7801                    pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
7802                         ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
7803                          DMA_CTRL_WRITE_BOUNDARY_16;
7804                    REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
7805                           pDevice->DmaReadWriteCtrl);
7806                    break;
7807                 }
7808                 else
7809                 {
7810                     goto LM_DmaTestDone;
7811                 }
7812            }
7813        }
7814        if (j == (BufferSize/4))
7815            dma_success = 1;
7816    }
7817    ret = LM_STATUS_SUCCESS;
7818LM_DmaTestDone:
7819    memset(pBufferVirt, 0, BufferSize);
7820    return ret;
7821}
7822
7823void
7824LM_Add32To64Counter(LM_UINT32 Counter32, T3_64BIT_REGISTER *Counter64)
7825{
7826    Counter64->Low += Counter32;
7827    if (Counter64->Low < Counter32)
7828    {
7829        Counter64->High++;
7830    }
7831}
7832
7833LM_STATUS
7834LM_GetStats(PLM_DEVICE_BLOCK pDevice)
7835{
7836    PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
7837
7838    if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7839    {
7840        return LM_STATUS_FAILURE;
7841    }
7842
7843    if (pStats == 0)
7844    {
7845        return LM_STATUS_FAILURE;
7846    }
7847    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutOctets),
7848        &pStats->ifHCOutOctets);
7849    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsCollisions),
7850        &pStats->etherStatsCollisions);
7851    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXonSent),
7852        &pStats->outXonSent);
7853    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXoffSent),
7854        &pStats->outXoffSent);
7855    LM_Add32To64Counter(REG_RD(pDevice,
7856	MacCtrl.dot3StatsInternalMacTransmitErrors),
7857        &pStats->dot3StatsInternalMacTransmitErrors);
7858    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsSingleCollisionFrames),
7859        &pStats->dot3StatsSingleCollisionFrames);
7860    LM_Add32To64Counter(REG_RD(pDevice,
7861	MacCtrl.dot3StatsMultipleCollisionFrames),
7862        &pStats->dot3StatsMultipleCollisionFrames);
7863    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsDeferredTransmissions),
7864        &pStats->dot3StatsDeferredTransmissions);
7865    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsExcessiveCollisions),
7866        &pStats->dot3StatsExcessiveCollisions);
7867    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsLateCollisions),
7868        &pStats->dot3StatsLateCollisions);
7869    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutUcastPkts),
7870        &pStats->ifHCOutUcastPkts);
7871    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutMulticastPkts),
7872        &pStats->ifHCOutMulticastPkts);
7873    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutBroadcastPkts),
7874        &pStats->ifHCOutBroadcastPkts);
7875    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInOctets),
7876        &pStats->ifHCInOctets);
7877    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsFragments),
7878        &pStats->etherStatsFragments);
7879    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInUcastPkts),
7880        &pStats->ifHCInUcastPkts);
7881    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInMulticastPkts),
7882        &pStats->ifHCInMulticastPkts);
7883    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInBroadcastPkts),
7884        &pStats->ifHCInBroadcastPkts);
7885    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFCSErrors),
7886        &pStats->dot3StatsFCSErrors);
7887    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsAlignmentErrors),
7888        &pStats->dot3StatsAlignmentErrors);
7889    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xonPauseFramesReceived),
7890        &pStats->xonPauseFramesReceived);
7891    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffPauseFramesReceived),
7892        &pStats->xoffPauseFramesReceived);
7893    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.macControlFramesReceived),
7894        &pStats->macControlFramesReceived);
7895    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffStateEntered),
7896        &pStats->xoffStateEntered);
7897    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFramesTooLong),
7898        &pStats->dot3StatsFramesTooLong);
7899    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsJabbers),
7900        &pStats->etherStatsJabbers);
7901    LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsUndersizePkts),
7902        &pStats->etherStatsUndersizePkts);
7903
7904    return LM_STATUS_SUCCESS;
7905}
7906