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