Root/package/broadcom-57xx/src/tigon3.c

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

Archive Download this file



interactive