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