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