HP NC10xx/67xx/77xx/150x/320x/325x Gigabit Ethernet NIC Driver for Linux
[linux-2.6.git] / drivers / net / bcm5700 / tigon3.c
1 /******************************************************************************/
2 /*                                                                            */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2005 Broadcom  */
4 /* Corporation.                                                               */
5 /* All rights reserved.                                                       */
6 /*                                                                            */
7 /* This program is free software; you can redistribute it and/or modify       */
8 /* it under the terms of the GNU General Public License as published by       */
9 /* the Free Software Foundation, located in the file LICENSE.                 */
10 /*                                                                            */
11 /* History:                                                                   */
12 /******************************************************************************/
13
14 #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_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     {
4871         Value32 = REG_RD_OFFSET(pDevice, 0x5b0);
4872         REG_WR_OFFSET(pDevice, 0x5b0, Value32 | BIT_10 );
4873       
4874          pDevice->GrcLocalCtrl |= BIT_4 ; 
4875         pDevice->GrcLocalCtrl &= ~BIT_5 ; 
4876
4877         REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
4878         Value32 = REG_RD(pDevice, Grc.LocalCtrl);
4879         MM_Wait(40);
4880     }
4881
4882     if (!pDevice->InitDone)
4883     {
4884         pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
4885     }
4886
4887     if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
4888         ( ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5401_PHY_ID)&&
4889          ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5411_PHY_ID) ))
4890     {
4891         /* 5401/5411 PHY needs a delay of about 1 second after PHY reset */
4892         /* Without the delay, it has problem linking at forced 10 half */
4893         /* So skip the reset... */
4894         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5780)
4895             for(j =0; j<0x5000; j++)
4896                 MM_Wait(1);
4897
4898         LM_ResetPhy(pDevice);
4899     }
4900
4901     /* Setup the phy chip. */
4902     LM_SetupPhy(pDevice);
4903
4904     if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG)){
4905         /* Clear CRC stats */
4906         LM_ReadPhy(pDevice, 0x1e, &Value32);
4907         LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
4908         LM_ReadPhy(pDevice, 0x14, &Value32);
4909     }
4910
4911     /* Set up the receive mask. */
4912     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
4913
4914 #ifdef INCLUDE_TCP_SEG_SUPPORT
4915     if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
4916     {
4917         if (LM_LoadStkOffLdFirmware(pDevice) == LM_STATUS_FAILURE)
4918         {
4919             return LM_STATUS_FAILURE;
4920         }
4921     }
4922 #endif
4923     LM_WritePostResetSignatures(pDevice, LM_INIT_RESET);
4924
4925     return LM_STATUS_SUCCESS;
4926 } /* LM_ResetAdapter */
4927
4928
4929 /******************************************************************************/
4930 /* Description:                                                               */
4931 /*    This routine disables the adapter from generating interrupts.           */
4932 /*                                                                            */
4933 /* Return:                                                                    */
4934 /*    LM_STATUS_SUCCESS                                                       */
4935 /******************************************************************************/
4936 LM_STATUS
4937 LM_DisableInterrupt(
4938     PLM_DEVICE_BLOCK pDevice)
4939 {
4940     REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl | 
4941         MISC_HOST_CTRL_MASK_PCI_INT);
4942     MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
4943     if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4944     {
4945         MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
4946     }
4947
4948     return LM_STATUS_SUCCESS;
4949 }
4950
4951
4952
4953 /******************************************************************************/
4954 /* Description:                                                               */
4955 /*    This routine enables the adapter to generate interrupts.                */
4956 /*                                                                            */
4957 /* Return:                                                                    */
4958 /*    LM_STATUS_SUCCESS                                                       */
4959 /******************************************************************************/
4960 LM_STATUS
4961 LM_EnableInterrupt(
4962     PLM_DEVICE_BLOCK pDevice)
4963 {
4964     MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, pDevice->LastTag << 24);
4965     if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4966     {
4967         MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
4968     }
4969
4970     REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
4971         ~MISC_HOST_CTRL_MASK_PCI_INT);
4972
4973     REG_WR(pDevice, HostCoalesce.Mode, pDevice->CoalesceMode |
4974         HOST_COALESCE_ENABLE | HOST_COALESCE_NOW);
4975
4976     return LM_STATUS_SUCCESS;
4977 }
4978
4979
4980
4981 /******************************************************************************/
4982 /* Description:                                                               */
4983 /*    This routine puts a packet on the wire if there is a transmit DMA       */
4984 /*    descriptor available; otherwise the packet is queued for later          */
4985 /*    transmission.  If the second argue is NULL, this routine will put       */
4986 /*    the queued packet on the wire if possible.                              */
4987 /*                                                                            */
4988 /* Return:                                                                    */
4989 /*    LM_STATUS_SUCCESS                                                       */
4990 /******************************************************************************/
4991 LM_STATUS
4992 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
4993 {
4994     LM_UINT32 FragCount;
4995     PT3_SND_BD pSendBd, pTmpSendBd;
4996 #ifdef BCM_NIC_SEND_BD
4997     PT3_SND_BD pShadowSendBd;
4998     T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
4999 #endif
5000     LM_UINT32 StartIdx, Idx;
5001
5002     while (1)
5003     {
5004         /* Initalize the send buffer descriptors. */
5005         StartIdx = Idx = pDevice->SendProdIdx;
5006
5007 #ifdef BCM_NIC_SEND_BD
5008         if (pDevice->Flags & NIC_SEND_BD_FLAG)
5009         {
5010             pTmpSendBd = pSendBd = &NicSendBdArr[0];
5011         }
5012         else
5013 #endif
5014         {
5015             pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
5016         }
5017
5018         /* Next producer index. */
5019         for(FragCount = 0; ; )
5020         {
5021             LM_UINT32 Value32, Len;
5022
5023             /* Initialize the pointer to the send buffer fragment. */
5024             MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
5025
5026             pSendBd->u2.VlanTag = pPacket->VlanTag;
5027
5028             /* Setup the control flags and send buffer size. */
5029             Value32 = (Len << 16) | pPacket->Flags;
5030
5031 #ifdef INCLUDE_TCP_SEG_SUPPORT
5032             if (Value32 & (SND_BD_FLAG_CPU_PRE_DMA | SND_BD_FLAG_CPU_POST_DMA))
5033             {
5034                 if(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))  
5035                 {
5036                     pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
5037                 }
5038                 else if (FragCount == 0)
5039                 {
5040                     pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
5041                 }
5042                 else
5043                 {
5044                     pSendBd->u2.s2.Reserved = 0;
5045                     Value32 &= 0xffff0fff;
5046                 }
5047             }
5048 #endif
5049             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
5050                 
5051             FragCount++;
5052             if (FragCount >= pPacket->u.Tx.FragCount)
5053             {
5054                 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
5055                 break;
5056             }
5057             else
5058             {
5059                 pSendBd->u1.Len_Flags = Value32;
5060             }
5061
5062             pSendBd++;
5063             if ((Idx == 0) &&
5064                 !(pDevice->Flags & NIC_SEND_BD_FLAG))
5065             {
5066                 pSendBd = &pDevice->pSendBdVirt[0];
5067             }
5068
5069             pDevice->SendRing[Idx] = 0;
5070
5071         } /* for */
5072         if (pDevice->Flags & TX_4G_WORKAROUND_FLAG)
5073         {
5074             if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
5075                 LM_STATUS_SUCCESS)
5076             {
5077                 if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
5078                 {
5079                     QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
5080                     return LM_STATUS_FAILURE;
5081                 }
5082                 continue;
5083             }
5084         }
5085         break;
5086     }
5087     /* Put the packet descriptor in the ActiveQ. */
5088     pDevice->SendRing[StartIdx] = pPacket;
5089
5090 #ifdef BCM_NIC_SEND_BD
5091     if (pDevice->Flags & NIC_SEND_BD_FLAG)
5092     {
5093         pSendBd = &pDevice->pSendBdVirt[StartIdx];
5094         pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
5095
5096         while (StartIdx != Idx)
5097         {
5098             LM_UINT32 Value32;
5099
5100             if ((Value32 = pTmpSendBd->HostAddr.High) !=
5101                 pShadowSendBd->HostAddr.High)
5102             {
5103                 MM_MEMWRITEL(&(pSendBd->HostAddr.High), Value32);
5104                 pShadowSendBd->HostAddr.High = Value32;
5105             }
5106
5107             MM_MEMWRITEL(&(pSendBd->HostAddr.Low), pTmpSendBd->HostAddr.Low);
5108
5109             if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
5110                 pShadowSendBd->u1.Len_Flags)
5111             {
5112                 MM_MEMWRITEL(&(pSendBd->u1.Len_Flags), Value32);
5113                 pShadowSendBd->u1.Len_Flags = Value32;
5114             }
5115
5116             if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
5117             {
5118                 MM_MEMWRITEL(&(pSendBd->u2.VlanTag), pTmpSendBd->u2.VlanTag);
5119             }
5120
5121             StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
5122             if (StartIdx == 0)
5123             {
5124                 pSendBd = &pDevice->pSendBdVirt[0];
5125                 pShadowSendBd = &pDevice->ShadowSendBd[0];
5126             }
5127             else
5128             {
5129                 pSendBd++;
5130                 pShadowSendBd++;
5131             }
5132             pTmpSendBd++;
5133         }
5134         MM_WMB();
5135         MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
5136
5137         if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
5138         {
5139             MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
5140         }
5141         if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
5142         {
5143             MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
5144         }
5145          else
5146         {
5147             MM_MMIOWB();
5148         }       
5149     }
5150     else
5151 #endif
5152     {
5153         MM_WMB();
5154         MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
5155
5156         if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
5157         {
5158             MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
5159         }
5160         if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
5161         {
5162             MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
5163         }
5164         else
5165         {
5166             MM_MMIOWB();
5167         }       
5168     }
5169
5170     /* Update the SendBdLeft count. */
5171     MM_ATOMIC_SUB(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
5172
5173     /* Update the producer index. */
5174     pDevice->SendProdIdx = Idx;
5175
5176     return LM_STATUS_SUCCESS;
5177 }
5178
5179 STATIC LM_STATUS
5180 LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
5181     PT3_SND_BD pSendBd)
5182 {
5183     int FragCount;
5184     LM_UINT32 Idx, Base, Len;
5185
5186     Idx = pDevice->SendProdIdx;
5187     for(FragCount = 0; ; )
5188     {
5189         Len = pSendBd->u1.Len_Flags >> 16;
5190         if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
5191             ((Base + 8 + Len) < Base))
5192         {
5193             return LM_STATUS_SUCCESS;
5194         }
5195         FragCount++;
5196         if (FragCount >= pPacket->u.Tx.FragCount)
5197         {
5198             break;
5199         }
5200         pSendBd++;
5201         if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
5202         {
5203             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
5204             if (Idx == 0)
5205             {
5206                 pSendBd = &pDevice->pSendBdVirt[0];
5207             }
5208         }
5209     }
5210     return LM_STATUS_FAILURE;
5211 }
5212
5213 /******************************************************************************/
5214 /* Description:                                                               */
5215 /*                                                                            */
5216 /* Return:                                                                    */
5217 /******************************************************************************/
5218 LM_UINT32
5219 ComputeCrc32(LM_UINT8 *pBuffer, LM_UINT32 BufferSize)
5220 {
5221     LM_UINT32 Reg;
5222     LM_UINT32 Tmp;
5223     int j, k;
5224
5225     Reg = 0xffffffff;
5226
5227     for(j = 0; j < BufferSize; j++)
5228     {
5229         Reg ^= pBuffer[j];
5230
5231         for(k = 0; k < 8; k++)
5232         {
5233             Tmp = Reg & 0x01;
5234
5235             Reg >>= 1;
5236
5237             if(Tmp)
5238             {
5239                 Reg ^= 0xedb88320;
5240             }
5241         }
5242     }
5243
5244     return ~Reg;
5245 } /* ComputeCrc32 */
5246
5247
5248
5249 /******************************************************************************/
5250 /* Description:                                                               */
5251 /*    This routine sets the receive control register according to ReceiveMask */
5252 /*                                                                            */
5253 /* Return:                                                                    */
5254 /*    LM_STATUS_SUCCESS                                                       */
5255 /******************************************************************************/
5256 LM_STATUS
5257 LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
5258 {
5259     LM_UINT32 ReceiveMask;
5260     LM_UINT32 RxMode;
5261     LM_UINT32 j, k;
5262
5263     ReceiveMask = Mask;
5264
5265     RxMode = pDevice->RxMode;
5266
5267     if(Mask & LM_ACCEPT_UNICAST)
5268     {
5269         Mask &= ~LM_ACCEPT_UNICAST;
5270     }
5271
5272     if(Mask & LM_ACCEPT_MULTICAST)
5273     {
5274         Mask &= ~LM_ACCEPT_MULTICAST;
5275     }
5276
5277     if(Mask & LM_ACCEPT_ALL_MULTICAST)
5278     {
5279         Mask &= ~LM_ACCEPT_ALL_MULTICAST;
5280     }
5281
5282     if(Mask & LM_ACCEPT_BROADCAST)
5283     {
5284         Mask &= ~LM_ACCEPT_BROADCAST;
5285     }
5286
5287     RxMode &= ~RX_MODE_KEEP_VLAN_TAG;
5288     if (Mask & LM_KEEP_VLAN_TAG)
5289     {
5290         RxMode |= RX_MODE_KEEP_VLAN_TAG;
5291         Mask &= ~LM_KEEP_VLAN_TAG;
5292     }
5293
5294     RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
5295     if(Mask & LM_PROMISCUOUS_MODE)
5296     {
5297         RxMode |= RX_MODE_PROMISCUOUS_MODE;
5298         Mask &= ~LM_PROMISCUOUS_MODE;
5299     }
5300
5301     RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
5302     if(Mask & LM_ACCEPT_ERROR_PACKET)
5303     {
5304         RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
5305         Mask &= ~LM_ACCEPT_ERROR_PACKET;
5306     }
5307
5308     /* Make sure all the bits are valid before committing changes. */
5309     if(Mask)
5310     {
5311         return LM_STATUS_FAILURE;
5312     }
5313
5314     /* Commit the new filter. */
5315     pDevice->ReceiveMask = ReceiveMask;
5316
5317     pDevice->RxMode = RxMode;
5318
5319     if (pDevice->PowerLevel != LM_POWER_STATE_D0)
5320     {
5321         return LM_STATUS_SUCCESS;
5322     }
5323
5324     REG_WR(pDevice, MacCtrl.RxMode, RxMode);
5325
5326     /* Set up the MC hash table. */
5327     if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
5328     {
5329         for(k = 0; k < 4; k++)
5330         {
5331             REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
5332         }
5333     }
5334     else if(ReceiveMask & LM_ACCEPT_MULTICAST)
5335     {
5336         for(k = 0; k < 4; k++)
5337         {
5338             REG_WR(pDevice, MacCtrl.HashReg[k], pDevice->MulticastHash[k]);
5339         }
5340     }
5341     else
5342     {
5343         /* Reject all multicast frames. */
5344         for(j = 0; j < 4; j++)
5345         {
5346             REG_WR(pDevice, MacCtrl.HashReg[j], 0);
5347         }
5348     }
5349
5350     /* By default, Tigon3 will accept broadcast frames.  We need to setup */
5351     if(ReceiveMask & LM_ACCEPT_BROADCAST)
5352     {
5353         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
5354             REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
5355         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
5356             REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
5357         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
5358             REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
5359         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
5360             REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
5361     }
5362     else
5363     {
5364         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule, 
5365             REJECT_BROADCAST_RULE1_RULE);
5366         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value, 
5367             REJECT_BROADCAST_RULE1_VALUE);
5368         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule, 
5369             REJECT_BROADCAST_RULE2_RULE);
5370         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value, 
5371             REJECT_BROADCAST_RULE2_VALUE);
5372     }
5373
5374     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
5375     {
5376         k = 16;
5377     }
5378     else if (!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
5379     {
5380         k = 16;
5381     }
5382     else
5383     {
5384         k = 8;
5385     }
5386 #ifdef BCM_ASF
5387     if (pDevice->AsfFlags & ASF_ENABLED)
5388     {
5389         k -= 4;
5390     }
5391 #endif
5392
5393     /* disable the rest of the rules. */
5394     for(j = RCV_LAST_RULE_IDX; j < k; j++)
5395     {
5396         REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
5397         REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
5398     }
5399
5400     return LM_STATUS_SUCCESS;
5401 } /* LM_SetReceiveMask */
5402
5403
5404
5405 /******************************************************************************/
5406 /* Description:                                                               */
5407 /*    Disable the interrupt and put the transmitter and receiver engines in   */
5408 /*    an idle state.  Also aborts all pending send requests and receive       */
5409 /*    buffers.                                                                */
5410 /*                                                                            */
5411 /* Return:                                                                    */
5412 /*    LM_STATUS_SUCCESS                                                       */
5413 /******************************************************************************/
5414 LM_STATUS
5415 LM_Abort(
5416 PLM_DEVICE_BLOCK pDevice)
5417 {
5418     PLM_PACKET pPacket;
5419     LM_UINT Idx;
5420
5421     LM_DisableInterrupt(pDevice);
5422
5423     LM_DisableChip(pDevice);
5424
5425     /*
5426      * If we do not have a status block pointer, then
5427      * the device hasn't really been opened.  Do not
5428      * attempt to clean up packets.
5429      */
5430     if (pDevice->pStatusBlkVirt == NULL)
5431         return LM_STATUS_SUCCESS;
5432
5433     /* Abort packets that have already queued to go out. */
5434     Idx = pDevice->SendConIdx; 
5435     for ( ; ; )
5436     {
5437         if ((pPacket = pDevice->SendRing[Idx]))
5438         {
5439             pDevice->SendRing[Idx] = 0;
5440             pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
5441             pDevice->TxCounters.TxPacketAbortedCnt++;
5442
5443             MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
5444             Idx = (Idx + pPacket->u.Tx.FragCount) & 
5445                 T3_SEND_RCB_ENTRY_COUNT_MASK;
5446
5447             QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
5448         }
5449         else
5450         {
5451             break;
5452         }
5453     }
5454
5455     /* Cleanup the receive return rings. */
5456 #ifdef BCM_NAPI_RXPOLL
5457     LM_ServiceRxPoll(pDevice, T3_RCV_RETURN_RCB_ENTRY_COUNT);
5458 #else
5459     LM_ServiceRxInterrupt(pDevice);
5460 #endif
5461
5462     /* Indicate packets to the protocol. */
5463     MM_IndicateTxPackets(pDevice);
5464
5465 #ifdef BCM_NAPI_RXPOLL
5466
5467     /* Move the receive packet descriptors in the ReceivedQ to the */
5468     /* free queue. */
5469     for(; ;)
5470     {
5471         pPacket = (PLM_PACKET) QQ_PopHead(
5472             &pDevice->RxPacketReceivedQ.Container);
5473         if(pPacket == NULL)
5474         {
5475             break;
5476         }
5477         MM_UnmapRxDma(pDevice, pPacket);
5478         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5479     }
5480 #else
5481     /* Indicate received packets to the protocols. */
5482     MM_IndicateRxPackets(pDevice);
5483 #endif
5484
5485     /* Clean up the Std Receive Producer ring. */
5486     /* Don't always trust the consumer idx in the status block in case of  */
5487     /* hw failure */
5488     Idx = 0;
5489
5490     while(Idx < T3_STD_RCV_RCB_ENTRY_COUNT)
5491     {
5492         if ((pPacket = pDevice->RxStdRing[Idx]))
5493         {
5494             MM_UnmapRxDma(pDevice, pPacket);
5495             QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5496             pDevice->RxStdRing[Idx] = 0;
5497         }
5498
5499         Idx++;
5500     } /* while */
5501
5502     /* Reinitialize our copy of the indices. */
5503     pDevice->RxStdProdIdx = 0;
5504
5505 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
5506     /* Clean up the Jumbo Receive Producer ring. */
5507     Idx = 0;
5508
5509     while(Idx < T3_JUMBO_RCV_RCB_ENTRY_COUNT)
5510     {
5511         if ((pPacket = pDevice->RxJumboRing[Idx]))
5512         {
5513             MM_UnmapRxDma(pDevice, pPacket);
5514             QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5515             pDevice->RxJumboRing[Idx] = 0;
5516         }
5517         Idx++;
5518     } /* while */
5519
5520     /* Reinitialize our copy of the indices. */
5521     pDevice->RxJumboProdIdx = 0;
5522 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
5523
5524     /* Initialize the statistis Block */
5525     pDevice->pStatusBlkVirt->Status = 0;
5526     pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
5527     pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
5528     pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
5529
5530     return LM_STATUS_SUCCESS;
5531 } /* LM_Abort */
5532
5533
5534
5535 /******************************************************************************/
5536 /* Description:                                                               */
5537 /*    Disable the interrupt and put the transmitter and receiver engines in   */
5538 /*    an idle state.  Aborts all pending send requests and receive buffers.   */
5539 /*    Also free all the receive buffers.                                      */
5540 /*                                                                            */
5541 /* Return:                                                                    */
5542 /*    LM_STATUS_SUCCESS                                                       */
5543 /******************************************************************************/
5544 LM_STATUS
5545 LM_DoHalt(LM_DEVICE_BLOCK *pDevice)
5546 {
5547     PLM_PACKET pPacket;
5548     LM_UINT32 EntryCnt;
5549
5550     LM_DisableFW(pDevice);
5551
5552     LM_WritePreResetSignatures(pDevice, LM_SHUTDOWN_RESET);
5553     LM_Abort(pDevice);
5554
5555     /* Get the number of entries in the queue. */
5556     EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
5557
5558     /* Make sure all the packets have been accounted for. */
5559     for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
5560     {
5561         pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
5562         if (pPacket == 0)
5563             break;
5564
5565         MM_FreeRxBuffer(pDevice, pPacket);
5566
5567         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
5568     }
5569
5570     LM_ResetChip(pDevice);
5571     LM_WriteLegacySignatures(pDevice, LM_SHUTDOWN_RESET);
5572
5573     /* Restore PCI configuration registers. */
5574     MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
5575         pDevice->SavedCacheLineReg);
5576     LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, 
5577         (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
5578
5579     /* Reprogram the MAC address. */
5580     LM_SetMacAddress(pDevice, pDevice->NodeAddress);
5581
5582     return LM_STATUS_SUCCESS;
5583 } /* LM_DoHalt */
5584
5585
5586 LM_STATUS
5587 LM_Halt(LM_DEVICE_BLOCK *pDevice)
5588 {
5589     LM_STATUS status;
5590
5591     status = LM_DoHalt(pDevice);
5592     LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
5593     return status;
5594 }
5595
5596
5597 STATIC LM_VOID
5598 LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5599 {
5600     MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,T3_MAGIC_NUM_FIRMWARE_INIT_DONE);
5601 #ifdef BCM_ASF
5602     if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
5603     {
5604         if (Mode == LM_INIT_RESET)
5605         {
5606             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
5607         }
5608         else if (Mode == LM_SHUTDOWN_RESET)
5609         {
5610             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
5611         }
5612         else if (Mode == LM_SUSPEND_RESET)
5613         {
5614             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
5615         }
5616     }
5617 #endif
5618 }
5619
5620 STATIC LM_VOID
5621 LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5622 {
5623 #ifdef BCM_ASF
5624     if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
5625     {
5626         if (Mode == LM_INIT_RESET)
5627         {
5628             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
5629                 T3_DRV_STATE_START_DONE);
5630         }
5631         else if (Mode == LM_SHUTDOWN_RESET)
5632         {
5633             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
5634                 T3_DRV_STATE_UNLOAD_DONE);
5635         }
5636     }
5637 #endif
5638 }
5639
5640 STATIC LM_VOID
5641 LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
5642 {
5643 #ifdef BCM_ASF
5644     if (pDevice->AsfFlags & ASF_ENABLED)
5645     {
5646         if (Mode == LM_INIT_RESET)
5647         {
5648             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
5649         }
5650         else if (Mode == LM_SHUTDOWN_RESET)
5651         {
5652             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
5653         }
5654         else if (Mode == LM_SUSPEND_RESET)
5655         {
5656             MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
5657         }
5658     }
5659 #endif
5660 }
5661
5662 STATIC LM_STATUS
5663 LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
5664 {
5665     LM_UINT32 Value32;
5666     LM_UINT32 j, tmp1 = 0, tmp2 = 0;
5667
5668     /* Wait for access to the nvram interface before resetting.  This is */
5669     /* a workaround to prevent EEPROM corruption. */
5670     if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
5671         T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
5672     {
5673         /* Request access to the flash interface. */
5674         LM_NVRAM_AcquireLock(pDevice);
5675     }
5676
5677     Value32 = GRC_MISC_CFG_CORE_CLOCK_RESET;
5678     if (pDevice->Flags & PCI_EXPRESS_FLAG)
5679     {
5680         if (REG_RD_OFFSET(pDevice, 0x7e2c) == 0x60)    /* PCIE 1.0 system */
5681         {
5682             REG_WR_OFFSET(pDevice, 0x7e2c, 0x20);
5683         }
5684         if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
5685         {
5686             /* This bit prevents PCIE link training during GRC reset */
5687             REG_WR(pDevice, Grc.MiscCfg, BIT_29);    /* Write bit 29 first */
5688             Value32 |= BIT_29;       /* and keep bit 29 set during GRC reset */
5689         }
5690     }
5691     if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
5692     {
5693         Value32 |= GRC_MISC_GPHY_KEEP_POWER_DURING_RESET;
5694     }
5695
5696     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
5697     {
5698         /* Save the MSI ENABLE bit (may need to save the message as well) */
5699         tmp1 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5700     }
5701
5702     /* Global reset. */
5703     RAW_REG_WR(pDevice, Grc.MiscCfg, Value32);
5704     MM_Wait(120);
5705
5706     MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
5707
5708     MM_Wait(120);
5709
5710     /* make sure we re-enable indirect accesses */
5711     MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
5712         pDevice->MiscHostCtrl);
5713
5714     /* Set MAX PCI retry to zero. */
5715     Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
5716     if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
5717     {
5718         if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
5719         {
5720             Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
5721         }
5722     }
5723     MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
5724
5725     /* Restore PCI command register. */
5726     MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
5727         pDevice->PciCommandStatusWords);
5728
5729     /* Disable PCI-X relaxed ordering bit. */
5730     MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
5731     Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
5732     MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
5733
5734      /* Enable memory arbiter */
5735     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId) )
5736     {
5737         Value32 = REG_RD(pDevice,MemArbiter.Mode);
5738         REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE | Value32);
5739     }
5740     else
5741     {
5742         REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
5743     }
5744
5745     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
5746     {
5747         /* restore the MSI ENABLE bit (may need to restore the message also) */
5748         tmp2 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5749         tmp2 |= (tmp1 & (1 << 16));
5750         LM_RegWr( pDevice, T3_PCI_MSI_ENABLE, tmp2, TRUE );
5751         tmp2 = LM_RegRd( pDevice, T3_PCI_MSI_ENABLE );
5752     }
5753
5754
5755     if (pDevice->ChipRevId == T3_CHIP_ID_5750_A3)
5756     {
5757         /* Because of chip bug on A3, we need to kill the CPU */
5758         LM_DisableFW(pDevice);
5759         REG_WR_OFFSET(pDevice, 0x5000, 0x400);
5760     }
5761 #ifdef BIG_ENDIAN_HOST
5762     /* Reconfigure the mode register. */
5763     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | 
5764               GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
5765               GRC_MODE_BYTE_SWAP_DATA |
5766               GRC_MODE_WORD_SWAP_DATA;
5767 #else
5768     /* Reconfigure the mode register. */
5769     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
5770 #endif
5771     REG_WR(pDevice, Grc.Mode, Value32);
5772
5773     if ((pDevice->Flags & MINI_PCI_FLAG) &&
5774         (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
5775     {
5776         pDevice->ClockCtrl |= T3_PCI_CLKRUN_OUTPUT_EN;
5777         if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
5778         {
5779             pDevice->ClockCtrl |= T3_PCI_FORCE_CLKRUN;
5780         }
5781         REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
5782     }
5783
5784     if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
5785     {
5786         pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
5787     }
5788     else if(pDevice->PhyFlags & PHY_IS_FIBER)
5789     {
5790          pDevice->MacMode = MAC_MODE_PORT_MODE_GMII;
5791     }
5792     else
5793     {
5794         pDevice->MacMode = 0;
5795     }
5796
5797     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5798     REG_RD_BACK(pDevice, MacCtrl.Mode);
5799     MM_Wait(40);
5800
5801     /* Wait for the firmware to finish initialization. */
5802     for(j = 0; j < 100000; j++)
5803     {
5804         MM_Wait(10);
5805
5806         if (j < 100)
5807             continue;
5808
5809         Value32 = MEM_RD_OFFSET(pDevice, T3_FIRMWARE_MAILBOX);
5810         if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
5811         {
5812             break;
5813         }
5814     }
5815     if ((j >= 0x100000) && (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
5816     {
5817         /* workaround - need to reset nvram of both devices at the same time */
5818         /* if the boot code is not running */
5819         if (LM_NVRAM_AcquireLock(pDevice) != LM_STATUS_SUCCESS)
5820         {
5821             LM_DEVICE_BLOCK *pDevice2;
5822
5823             REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
5824             pDevice2 = MM_FindPeerDev(pDevice);
5825             if (pDevice2 && !pDevice2->InitDone)
5826             {
5827                 REG_WR(pDevice2, Nvram.Cmd, NVRAM_CMD_RESET);
5828             }
5829         }
5830         else
5831         {
5832             LM_NVRAM_ReleaseLock(pDevice);
5833         }
5834     }
5835
5836
5837     if ((pDevice->Flags & PCI_EXPRESS_FLAG) && 
5838         (pDevice->ChipRevId != T3_CHIP_ID_5750_A0))
5839     {
5840         /* Enable PCIE bug fix */
5841         Value32 = REG_RD_OFFSET(pDevice, 0x7c00);
5842         REG_WR_OFFSET(pDevice, 0x7c00, Value32 | BIT_25 | BIT_29);
5843     }
5844
5845 #ifdef BCM_ASF
5846     pDevice->AsfFlags = 0;
5847     Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
5848
5849     if (Value32 == T3_NIC_DATA_SIG)
5850     {
5851         Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
5852         if (Value32 & T3_NIC_CFG_ENABLE_ASF)
5853         {
5854             pDevice->AsfFlags = ASF_ENABLED;
5855             if (T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
5856             {
5857                 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
5858             }
5859         }
5860     }
5861 #endif
5862
5863     return LM_STATUS_SUCCESS;
5864 }
5865
5866
5867 LM_STATUS
5868 LM_ShutdownChip(PLM_DEVICE_BLOCK pDevice, LM_RESET_TYPE Mode)
5869 {
5870     LM_DisableFW(pDevice);
5871     LM_WritePreResetSignatures(pDevice, Mode);
5872     if (pDevice->InitDone)
5873     {
5874         LM_Abort(pDevice);
5875     }
5876     else
5877     {
5878         LM_DisableChip(pDevice);
5879     }
5880     LM_ResetChip(pDevice);
5881     LM_WriteLegacySignatures(pDevice, Mode);
5882     LM_WritePostResetSignatures(pDevice, Mode);
5883     return LM_STATUS_SUCCESS;
5884 }
5885
5886 /******************************************************************************/
5887 /* Description:                                                               */
5888 /*                                                                            */
5889 /* Return:                                                                    */
5890 /******************************************************************************/
5891 void
5892 LM_ServiceTxInterrupt(
5893 PLM_DEVICE_BLOCK pDevice) {
5894     PLM_PACKET pPacket;
5895     LM_UINT32 HwConIdx;
5896     LM_UINT32 SwConIdx;
5897
5898     HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
5899
5900     /* Get our copy of the consumer index.  The buffer descriptors */
5901     /* that are in between the consumer indices are freed. */
5902     SwConIdx = pDevice->SendConIdx;
5903
5904     /* Move the packets from the TxPacketActiveQ that are sent out to */
5905     /* the TxPacketXmittedQ.  Packets that are sent use the */
5906     /* descriptors that are between SwConIdx and HwConIdx. */
5907     while(SwConIdx != HwConIdx)
5908     {
5909         pPacket = pDevice->SendRing[SwConIdx];
5910         pDevice->SendRing[SwConIdx] = 0;
5911
5912         /* Set the return status. */
5913         pPacket->PacketStatus = LM_STATUS_SUCCESS;
5914
5915         /* Put the packet in the TxPacketXmittedQ for indication later. */
5916         QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
5917
5918         /* Move to the next packet's BD. */
5919         SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) & 
5920             T3_SEND_RCB_ENTRY_COUNT_MASK;
5921
5922         /* Update the number of unused BDs. */
5923         MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
5924
5925         /* Get the new updated HwConIdx. */
5926         HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
5927     } /* while */
5928
5929     /* Save the new SwConIdx. */
5930     pDevice->SendConIdx = SwConIdx;
5931
5932 } /* LM_ServiceTxInterrupt */
5933
5934
5935 #ifdef BCM_NAPI_RXPOLL
5936 /******************************************************************************/
5937 /* Description:                                                               */
5938 /*                                                                            */
5939 /* Return:                                                                    */
5940 /******************************************************************************/
5941 int
5942 LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit)
5943 {
5944     PLM_PACKET pPacket=NULL;
5945     PT3_RCV_BD pRcvBd;
5946     LM_UINT32 HwRcvRetProdIdx;
5947     LM_UINT32 SwRcvRetConIdx;
5948     int received = 0;
5949
5950     /* Loop thru the receive return rings for received packets. */
5951     HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
5952
5953     SwRcvRetConIdx = pDevice->RcvRetConIdx;
5954     MM_RMB();
5955     while (SwRcvRetConIdx != HwRcvRetProdIdx) 
5956     {
5957         pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
5958
5959         /* Get the received packet descriptor. */
5960         pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
5961             MM_UINT_PTR(pRcvBd->Opaque));
5962
5963         switch(pPacket->u.Rx.RcvProdRing) {
5964 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
5965         case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
5966             pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5967             break;
5968 #endif
5969         case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
5970             pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
5971             break;
5972         }
5973
5974         /* Check the error flag. */
5975         if(pRcvBd->ErrorFlag &&
5976             pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
5977         {
5978             pPacket->PacketStatus = LM_STATUS_FAILURE;
5979
5980             pDevice->RxCounters.RxPacketErrCnt++;
5981
5982             if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
5983             {
5984                 pDevice->RxCounters.RxErrCrcCnt++;
5985             }
5986
5987             if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
5988             {
5989                 pDevice->RxCounters.RxErrCollCnt++;
5990             }
5991
5992             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
5993             {
5994                 pDevice->RxCounters.RxErrLinkLostCnt++;
5995             }
5996
5997             if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
5998             {
5999                 pDevice->RxCounters.RxErrPhyDecodeCnt++;
6000             }
6001
6002             if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
6003             {
6004                 pDevice->RxCounters.RxErrOddNibbleCnt++;
6005             }
6006
6007             if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
6008             {
6009                 pDevice->RxCounters.RxErrMacAbortCnt++;
6010             }
6011
6012             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
6013             {
6014                 pDevice->RxCounters.RxErrShortPacketCnt++;
6015             }
6016
6017             if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
6018             {
6019                 pDevice->RxCounters.RxErrNoResourceCnt++;
6020             }
6021
6022             if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
6023             {
6024                 pDevice->RxCounters.RxErrLargePacketCnt++;
6025             }
6026         }
6027         else
6028         {
6029             pPacket->PacketStatus = LM_STATUS_SUCCESS;
6030             pPacket->PacketSize = pRcvBd->Len - 4;
6031
6032             pPacket->Flags = pRcvBd->Flags;
6033             if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
6034             {
6035                 pPacket->VlanTag = pRcvBd->VlanTag;
6036             }
6037
6038             pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
6039         }
6040
6041         /* Put the packet descriptor containing the received packet */
6042         /* buffer in the RxPacketReceivedQ for indication later. */
6043         QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
6044
6045         /* Go to the next buffer descriptor. */
6046         SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
6047             pDevice->RcvRetRcbEntryCountMask;
6048
6049         if (++received >= limit)
6050         {
6051             break;
6052         }
6053     } /* while */
6054
6055     pDevice->RcvRetConIdx = SwRcvRetConIdx;
6056
6057     /* Update the receive return ring consumer index. */
6058     MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
6059     if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
6060     {
6061         MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
6062     }
6063     else
6064     {
6065         MM_MMIOWB();
6066     }
6067     return received;
6068 } /* LM_ServiceRxPoll */
6069 #endif /* BCM_NAPI_RXPOLL */
6070
6071
6072 /******************************************************************************/
6073 /* Description:                                                               */
6074 /*                                                                            */
6075 /* Return:                                                                    */
6076 /******************************************************************************/
6077 void
6078 LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice)
6079 {
6080 #ifndef BCM_NAPI_RXPOLL
6081     PLM_PACKET pPacket;
6082     PT3_RCV_BD pRcvBd;
6083 #endif
6084     LM_UINT32 HwRcvRetProdIdx;
6085     LM_UINT32 SwRcvRetConIdx;
6086
6087     /* Loop thru the receive return rings for received packets. */
6088     HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
6089
6090     SwRcvRetConIdx = pDevice->RcvRetConIdx;
6091 #ifdef BCM_NAPI_RXPOLL
6092     if (!pDevice->RxPoll)
6093     {
6094         if (SwRcvRetConIdx != HwRcvRetProdIdx)
6095         {
6096             if (MM_ScheduleRxPoll(pDevice) == LM_STATUS_SUCCESS)
6097             {
6098                 pDevice->RxPoll = TRUE;
6099                 REG_WR(pDevice, Grc.Mode,
6100                     pDevice->GrcMode | GRC_MODE_NO_INTERRUPT_ON_RECEIVE);
6101             }
6102         }
6103     }
6104 #else
6105     MM_RMB();
6106     while(SwRcvRetConIdx != HwRcvRetProdIdx)
6107     {
6108         pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
6109
6110         /* Get the received packet descriptor. */
6111         pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
6112             MM_UINT_PTR(pRcvBd->Opaque));
6113
6114         switch(pPacket->u.Rx.RcvProdRing) {
6115 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
6116         case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
6117             pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
6118             break;
6119 #endif
6120         case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
6121             pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
6122             break;
6123         }
6124
6125         /* Check the error flag. */
6126         if(pRcvBd->ErrorFlag &&
6127             pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
6128         {
6129             pPacket->PacketStatus = LM_STATUS_FAILURE;
6130
6131             pDevice->RxCounters.RxPacketErrCnt++;
6132
6133             if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
6134             {
6135                 pDevice->RxCounters.RxErrCrcCnt++;
6136             }
6137
6138             if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
6139             {
6140                 pDevice->RxCounters.RxErrCollCnt++;
6141             }
6142
6143             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
6144             {
6145                 pDevice->RxCounters.RxErrLinkLostCnt++;
6146             }
6147
6148             if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
6149             {
6150                 pDevice->RxCounters.RxErrPhyDecodeCnt++;
6151             }
6152
6153             if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
6154             {
6155                 pDevice->RxCounters.RxErrOddNibbleCnt++;
6156             }
6157
6158             if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
6159             {
6160                 pDevice->RxCounters.RxErrMacAbortCnt++;
6161             }
6162
6163             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
6164             {
6165                 pDevice->RxCounters.RxErrShortPacketCnt++;
6166             }
6167
6168             if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
6169             {
6170                 pDevice->RxCounters.RxErrNoResourceCnt++;
6171             }
6172
6173             if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
6174             {
6175                 pDevice->RxCounters.RxErrLargePacketCnt++;
6176             }
6177         }
6178         else
6179         {
6180             pPacket->PacketStatus = LM_STATUS_SUCCESS;
6181             pPacket->PacketSize = pRcvBd->Len - 4;
6182
6183             pPacket->Flags = pRcvBd->Flags;
6184             if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
6185             {
6186                 pPacket->VlanTag = pRcvBd->VlanTag;
6187             }
6188
6189             pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
6190         }
6191
6192         /* Put the packet descriptor containing the received packet */
6193         /* buffer in the RxPacketReceivedQ for indication later. */
6194         QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
6195
6196         /* Go to the next buffer descriptor. */
6197         SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
6198             pDevice->RcvRetRcbEntryCountMask;
6199
6200     } /* while */
6201
6202     pDevice->RcvRetConIdx = SwRcvRetConIdx;
6203
6204     /* Update the receive return ring consumer index. */
6205     MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
6206     if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
6207     {
6208         MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
6209     }
6210     else
6211     {
6212         MM_MMIOWB();
6213     }
6214
6215 #endif
6216 } /* LM_ServiceRxInterrupt */
6217
6218
6219
6220 /******************************************************************************/
6221 /* Description:                                                               */
6222 /*    This is the interrupt event handler routine. It acknowledges all        */
6223 /*    pending interrupts and process all pending events.                      */
6224 /*                                                                            */
6225 /* Return:                                                                    */
6226 /*    LM_STATUS_SUCCESS                                                       */
6227 /******************************************************************************/
6228 LM_STATUS
6229 LM_ServiceInterrupts(
6230     PLM_DEVICE_BLOCK pDevice)
6231 {
6232     LM_UINT32 Value32;
6233     int ServicePhyInt = FALSE;
6234
6235     /* Setup the phy chip whenever the link status changes. */
6236     if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
6237     {
6238         Value32 = REG_RD(pDevice, MacCtrl.Status);
6239         if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
6240         {
6241             if (Value32 & MAC_STATUS_MI_INTERRUPT)
6242             {
6243                 ServicePhyInt = TRUE;
6244             }
6245         }
6246         else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
6247         {
6248             ServicePhyInt = TRUE;
6249         }
6250     }
6251     else
6252     {
6253         if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
6254         {
6255             pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
6256                 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
6257             ServicePhyInt = TRUE;
6258         }
6259     }
6260 #ifdef INCLUDE_TBI_SUPPORT
6261     if (pDevice->IgnoreTbiLinkChange == TRUE)
6262     {
6263         ServicePhyInt = FALSE;
6264     }
6265 #endif
6266     if (ServicePhyInt == TRUE)
6267     {
6268         MM_ACQUIRE_PHY_LOCK_IN_IRQ(pDevice);
6269         LM_SetupPhy(pDevice);
6270         MM_RELEASE_PHY_LOCK_IN_IRQ(pDevice);
6271     }
6272
6273     /* Service receive and transmit interrupts. */
6274     LM_ServiceRxInterrupt(pDevice);
6275     LM_ServiceTxInterrupt(pDevice);
6276         
6277 #ifndef BCM_NAPI_RXPOLL
6278     /* No spinlock for this queue since this routine is serialized. */
6279     if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
6280     {
6281         /* Indicate receive packets. */
6282         MM_IndicateRxPackets(pDevice);
6283     }
6284 #endif
6285
6286     /* No spinlock for this queue since this routine is serialized. */
6287     if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
6288     {
6289         MM_IndicateTxPackets(pDevice);
6290     }
6291
6292     return LM_STATUS_SUCCESS;
6293 } /* LM_ServiceInterrupts */
6294
6295
6296 /******************************************************************************/
6297 /* Description:  Add a Multicast address. Note that MC addresses, once added, */
6298 /*               cannot be individually deleted. All addresses must be        */
6299 /*               cleared.                                                     */
6300 /*                                                                            */
6301 /* Return:                                                                    */
6302 /******************************************************************************/
6303 LM_STATUS
6304 LM_MulticastAdd(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
6305 {
6306
6307     LM_UINT32 RegIndex;
6308     LM_UINT32 Bitpos;
6309     LM_UINT32 Crc32;
6310
6311     Crc32 = ComputeCrc32(pMcAddress, ETHERNET_ADDRESS_SIZE);
6312
6313     /* The most significant 7 bits of the CRC32 (no inversion), */
6314     /* are used to index into one of the possible 128 bit positions. */
6315     Bitpos = ~Crc32 & 0x7f;
6316
6317     /* Hash register index. */
6318     RegIndex = (Bitpos & 0x60) >> 5;
6319
6320     /* Bit to turn on within a hash register. */
6321     Bitpos &= 0x1f;
6322
6323     /* Enable the multicast bit. */
6324     pDevice->MulticastHash[RegIndex] |= (1 << Bitpos);
6325
6326     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
6327
6328     return LM_STATUS_SUCCESS;
6329 }
6330
6331
6332 /******************************************************************************/
6333 /* Description:                                                               */
6334 /*                                                                            */
6335 /* Return:                                                                    */
6336 /******************************************************************************/
6337 LM_STATUS
6338 LM_MulticastDel(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
6339 {
6340     return LM_STATUS_FAILURE;
6341 } /* LM_MulticastDel */
6342
6343
6344
6345 /******************************************************************************/
6346 /* Description:                                                               */
6347 /*                                                                            */
6348 /* Return:                                                                    */
6349 /******************************************************************************/
6350 LM_STATUS
6351 LM_MulticastClear(LM_DEVICE_BLOCK *pDevice)
6352 {
6353     int i;
6354
6355     for (i = 0; i < 4; i++)
6356     {
6357         pDevice->MulticastHash[i] = 0;
6358     }
6359     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
6360
6361     return LM_STATUS_SUCCESS;
6362 } /* LM_MulticastClear */
6363
6364
6365
6366 /******************************************************************************/
6367 /* Description:                                                               */
6368 /*                                                                            */
6369 /* Return:                                                                    */
6370 /******************************************************************************/
6371 LM_STATUS
6372 LM_SetMacAddress(
6373     PLM_DEVICE_BLOCK pDevice,
6374     PLM_UINT8 pMacAddress)
6375 {
6376     LM_UINT32 j;
6377
6378     for(j = 0; j < 4; j++)
6379     {
6380         REG_WR(pDevice, MacCtrl.MacAddr[j].High,
6381             (pMacAddress[0] << 8) | pMacAddress[1]);
6382         REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
6383             (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
6384             (pMacAddress[4] << 8) | pMacAddress[5]);
6385     }
6386
6387     if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
6388         (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)) 
6389     {
6390         for (j = 0; j < 12; j++)
6391         {
6392             REG_WR(pDevice, MacCtrl.MacAddrExt[j].High,
6393                 (pMacAddress[0] << 8) | pMacAddress[1]);
6394             REG_WR(pDevice, MacCtrl.MacAddrExt[j].Low,
6395                 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
6396                 (pMacAddress[4] << 8) | pMacAddress[5]);
6397         }
6398     }
6399     return LM_STATUS_SUCCESS;
6400 }
6401
6402 LM_VOID
6403 LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice)
6404 {
6405     /* Turn off tap power management. */
6406     if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6407     {
6408         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
6409         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
6410         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
6411         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
6412         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
6413         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
6414         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
6415         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
6416         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
6417         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
6418         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
6419
6420         MM_Wait(40);
6421     }
6422 }
6423
6424 /******************************************************************************/
6425 /* Description:                                                               */
6426 /*                                                                            */
6427 /* Return:                                                                    */
6428 /*    LM_STATUS_LINK_ACTIVE                                                   */
6429 /*    LM_STATUS_LINK_DOWN                                                     */
6430 /******************************************************************************/
6431 static LM_STATUS
6432 LM_InitBcm540xPhy(
6433 PLM_DEVICE_BLOCK pDevice)
6434 {
6435     LM_LINE_SPEED CurrentLineSpeed;
6436     LM_DUPLEX_MODE CurrentDuplexMode;
6437     LM_STATUS CurrentLinkStatus;
6438     LM_UINT32 Value32;
6439     LM_UINT32 j;
6440
6441     LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
6442
6443     if ((pDevice->PhyFlags & PHY_RESET_ON_LINKDOWN) &&
6444         (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE))
6445     {
6446         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6447         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6448         if(!(Value32 & PHY_STATUS_LINK_PASS))
6449         {
6450             LM_ResetPhy(pDevice);
6451         }
6452     }
6453     if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6454     {
6455         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6456         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6457
6458         if(!pDevice->InitDone)
6459         {
6460             Value32 = 0;
6461         }
6462
6463         if(!(Value32 & PHY_STATUS_LINK_PASS))
6464         {
6465             LM_PhyTapPowerMgmt(pDevice);
6466
6467             LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6468             for(j = 0; j < 1000; j++)
6469             {
6470                 MM_Wait(10);
6471
6472                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6473                 if(Value32 & PHY_STATUS_LINK_PASS)
6474                 {
6475                     MM_Wait(40);
6476                     break;
6477                 }
6478             }
6479
6480             if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
6481             {
6482                 if(!(Value32 & PHY_STATUS_LINK_PASS) &&
6483                     (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
6484                 {
6485                     LM_ResetPhy(pDevice);
6486                 }
6487             }
6488         }
6489     }
6490     else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
6491         pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
6492     {
6493         /* Bug: 5701 A0, B0 TX CRC workaround. */
6494         LM_WritePhy(pDevice, 0x15, 0x0a75);
6495         LM_WritePhy(pDevice, 0x1c, 0x8c68);
6496         LM_WritePhy(pDevice, 0x1c, 0x8d68);
6497         LM_WritePhy(pDevice, 0x1c, 0x8c68);
6498     }
6499
6500     /* Acknowledge interrupts. */
6501     LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
6502     LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
6503
6504     /* Configure the interrupt mask. */
6505     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
6506     {
6507         LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
6508     }
6509
6510     /* Configure PHY led mode. */
6511     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
6512         (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
6513     {
6514         if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_1)
6515         {
6516             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 
6517                 BCM540X_EXT_CTRL_LINK3_LED_MODE);
6518         }
6519         else
6520         {
6521             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
6522         }
6523     }
6524
6525     if (pDevice->PhyFlags & PHY_CAPACITIVE_COUPLING)
6526     {
6527         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4007);
6528         LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &Value32);
6529         if (!(Value32 & BIT_10))
6530         {
6531             /* set the bit and re-link */
6532             LM_WritePhy(pDevice, BCM5401_AUX_CTRL, Value32 | BIT_10);
6533             return LM_STATUS_LINK_SETTING_MISMATCH;
6534         }
6535     }
6536
6537     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
6538
6539     /* Get current link and duplex mode. */
6540     for(j = 0; j < 100; j++)
6541     {
6542         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6543         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
6544
6545         if(Value32 & PHY_STATUS_LINK_PASS)
6546         {
6547             break;
6548         }
6549         MM_Wait(40);
6550     }
6551
6552     if(Value32 & PHY_STATUS_LINK_PASS)
6553     {
6554
6555         /* Determine the current line and duplex settings. */
6556         LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
6557         for(j = 0; j < 2000; j++)
6558         {
6559             MM_Wait(10);
6560
6561             LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
6562             if(Value32)
6563             {
6564                 break;
6565             }
6566         }
6567
6568         switch(Value32 & BCM540X_AUX_SPEED_MASK)
6569         {
6570             case BCM540X_AUX_10BASET_HD:
6571                 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
6572                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6573                 break;
6574
6575             case BCM540X_AUX_10BASET_FD:
6576                 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
6577                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6578                 break;
6579
6580             case BCM540X_AUX_100BASETX_HD:
6581                 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
6582                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6583                 break;
6584
6585             case BCM540X_AUX_100BASETX_FD:
6586                 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
6587                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6588                 break;
6589
6590             case BCM540X_AUX_100BASET_HD:
6591                 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
6592                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
6593                 break;
6594
6595             case BCM540X_AUX_100BASET_FD:
6596                 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
6597                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
6598                 break;
6599
6600             default:
6601
6602                 CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
6603                 CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
6604                 break;
6605         }
6606
6607         /* Make sure we are in auto-neg mode. */
6608         for (j = 0; j < 200; j++)
6609         {
6610             LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
6611             if(Value32 && Value32 != 0x7fff)
6612             {
6613                 break;
6614             }
6615
6616             if(Value32 == 0 &&
6617                 pDevice->RequestedLineSpeed == LM_LINE_SPEED_10MBPS &&
6618                 pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_HALF)
6619             {
6620                 break;
6621             }
6622
6623             MM_Wait(10);
6624         }
6625
6626         /* Use the current line settings for "auto" mode. */
6627         if(pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
6628         {
6629             if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
6630             {
6631                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6632
6633                 /* We may be exiting low power mode and the link is in */
6634                 /* 10mb.  In this case, we need to restart autoneg. */
6635
6636                 if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
6637                 {
6638                     CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6639                 }
6640             }
6641             else
6642             {
6643                 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6644             }
6645         }
6646         else
6647         {
6648             /* Force line settings. */
6649             /* Use the current setting if it matches the user's requested */
6650             /* setting. */
6651             LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
6652             if((pDevice->LineSpeed == CurrentLineSpeed) &&
6653                 (pDevice->DuplexMode == CurrentDuplexMode))
6654             {
6655                 if ((pDevice->DisableAutoNeg &&
6656                     !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
6657                     (!pDevice->DisableAutoNeg &&
6658                     (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
6659                 {
6660                     CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6661                 }
6662                 else
6663                 {
6664                     CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6665                 } 
6666             }
6667             else
6668             {
6669                 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
6670             } 
6671         }
6672
6673         /* Save line settings. */
6674         pDevice->LineSpeed = CurrentLineSpeed;
6675         pDevice->DuplexMode = CurrentDuplexMode;
6676     }
6677
6678     return CurrentLinkStatus;
6679 } /* LM_InitBcm540xPhy */
6680
6681 /******************************************************************************/
6682 /* Description:                                                               */
6683 /*                                                                            */
6684 /* Return:                                                                    */
6685 /******************************************************************************/
6686 LM_STATUS
6687 LM_SetFlowControl(
6688     PLM_DEVICE_BLOCK pDevice,
6689     LM_UINT32 LocalPhyAd,
6690     LM_UINT32 RemotePhyAd)
6691 {
6692     LM_FLOW_CONTROL FlowCap;
6693
6694     /* Resolve flow control. */
6695     FlowCap = LM_FLOW_CONTROL_NONE;
6696
6697     /* See Table 28B-3 of 802.3ab-1999 spec. */
6698     if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
6699     {
6700         if(pDevice->PhyFlags & PHY_IS_FIBER){
6701                 LocalPhyAd &= ~(PHY_AN_AD_ASYM_PAUSE |
6702                                  PHY_AN_AD_PAUSE_CAPABLE);
6703                 RemotePhyAd &= ~(PHY_AN_AD_ASYM_PAUSE |
6704                                 PHY_AN_AD_PAUSE_CAPABLE);
6705
6706                 if (LocalPhyAd & PHY_AN_AD_1000XPAUSE)
6707                      LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
6708                 if (LocalPhyAd & PHY_AN_AD_1000XPSE_ASYM)
6709                      LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
6710                 if (RemotePhyAd & PHY_AN_AD_1000XPAUSE)
6711                      RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
6712                 if (RemotePhyAd & PHY_AN_AD_1000XPSE_ASYM)
6713                      RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
6714         }
6715
6716         if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
6717         {
6718             if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6719             {
6720                 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
6721                 {
6722                     FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
6723                         LM_FLOW_CONTROL_RECEIVE_PAUSE;
6724                 }
6725                 else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
6726                 {
6727                     FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
6728                 }
6729             }
6730             else
6731             {
6732                 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
6733                 {
6734                     FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
6735                         LM_FLOW_CONTROL_RECEIVE_PAUSE;
6736                 }
6737             }
6738         }
6739         else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6740         {
6741             if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
6742                 (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
6743             {
6744                 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
6745             }
6746         }
6747     }
6748     else
6749     {
6750         FlowCap = pDevice->FlowControlCap;
6751     }
6752
6753     pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
6754
6755     /* Enable/disable rx PAUSE. */
6756     pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
6757     if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
6758         (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
6759         pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
6760     {
6761         pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
6762         pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
6763
6764     }
6765     REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
6766
6767     /* Enable/disable tx PAUSE. */
6768     pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
6769     if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
6770         (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
6771         pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
6772     {
6773         pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
6774         pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
6775
6776     }
6777     REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
6778
6779     return LM_STATUS_SUCCESS;
6780 }
6781
6782
6783 #ifdef INCLUDE_TBI_SUPPORT
6784 /******************************************************************************/
6785 /* Description:                                                               */
6786 /*                                                                            */
6787 /* Return:                                                                    */
6788 /******************************************************************************/
6789 STATIC LM_STATUS
6790 LM_InitBcm800xPhy(
6791     PLM_DEVICE_BLOCK pDevice)
6792 {
6793     LM_UINT32 Value32;
6794     LM_UINT32 j;
6795
6796
6797     Value32 = REG_RD(pDevice, MacCtrl.Status);
6798
6799     /* Reset the SERDES during init and when we have link. */
6800     if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
6801     {
6802         /* Set PLL lock range. */
6803         LM_WritePhy(pDevice, 0x16, 0x8007);
6804
6805         /* Software reset. */
6806         LM_WritePhy(pDevice, 0x00, 0x8000);
6807
6808         /* Wait for reset to complete. */
6809         for(j = 0; j < 500; j++)
6810         {
6811             MM_Wait(10);
6812         }
6813
6814         /* Config mode; seletct PMA/Ch 1 regs. */
6815         LM_WritePhy(pDevice, 0x10, 0x8411);
6816
6817         /* Enable auto-lock and comdet, select txclk for tx. */
6818         LM_WritePhy(pDevice, 0x11, 0x0a10);
6819
6820         LM_WritePhy(pDevice, 0x18, 0x00a0);
6821         LM_WritePhy(pDevice, 0x16, 0x41ff);
6822
6823         /* Assert and deassert POR. */
6824         LM_WritePhy(pDevice, 0x13, 0x0400);
6825         MM_Wait(40);
6826         LM_WritePhy(pDevice, 0x13, 0x0000);
6827
6828         LM_WritePhy(pDevice, 0x11, 0x0a50);
6829         MM_Wait(40);
6830         LM_WritePhy(pDevice, 0x11, 0x0a10);
6831
6832         /* Delay for signal to stabilize. */
6833         for(j = 0; j < 15000; j++)
6834         {
6835             MM_Wait(10);
6836         }
6837
6838         /* Deselect the channel register so we can read the PHY id later. */
6839         LM_WritePhy(pDevice, 0x10, 0x8011);
6840     }
6841
6842     return LM_STATUS_SUCCESS;
6843 }
6844
6845
6846
6847 /******************************************************************************/
6848 /* Description:                                                               */
6849 /*                                                                            */
6850 /* Return:                                                                    */
6851 /******************************************************************************/
6852 STATIC LM_STATUS
6853 LM_SetupFiberPhy(
6854     PLM_DEVICE_BLOCK pDevice)
6855 {
6856     LM_STATUS CurrentLinkStatus;
6857     AUTONEG_STATUS AnStatus = 0;
6858     LM_UINT32 Value32;
6859     LM_UINT32 Cnt;
6860     LM_UINT32 j, k;
6861     LM_UINT32 MacStatus, RemotePhyAd, LocalPhyAd;
6862     LM_FLOW_CONTROL PreviousFlowControl = pDevice->FlowControl;
6863
6864
6865     if (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE)
6866     {
6867         pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
6868         MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
6869         return LM_STATUS_SUCCESS;
6870     }
6871
6872
6873     if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
6874         (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) && pDevice->InitDone)
6875     {
6876         MacStatus = REG_RD(pDevice, MacCtrl.Status);
6877         if ((MacStatus & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED |
6878             MAC_STATUS_CFG_CHANGED | MAC_STATUS_RECEIVING_CFG))
6879             == (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED))
6880         {
6881       
6882             REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
6883                 MAC_STATUS_CFG_CHANGED);
6884             return LM_STATUS_SUCCESS;
6885         }
6886     }
6887     pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
6888
6889     /* Initialize the send_config register. */
6890     REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
6891
6892     pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
6893     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6894     MM_Wait(10);
6895
6896     /* Initialize the BCM8002 SERDES PHY. */
6897     switch(pDevice->PhyId & PHY_ID_MASK)
6898     {
6899         case PHY_BCM8002_PHY_ID:
6900             LM_InitBcm800xPhy(pDevice);
6901             break;
6902
6903         default:
6904             break;
6905     }
6906
6907     /* Enable link change interrupt. */
6908     REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
6909
6910     /* Default to link down. */
6911     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
6912
6913     /* Get the link status. */
6914     MacStatus = REG_RD(pDevice, MacCtrl.Status);
6915
6916     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
6917     {
6918         LM_UINT32 SgDigCtrl, SgDigStatus;
6919         LM_UINT32 SerdesCfg = 0;
6920         LM_UINT32 ExpectedSgDigCtrl = 0;
6921         LM_UINT32 WorkAround = 0;
6922         LM_UINT32 PortA = 1;
6923
6924         if ((pDevice->ChipRevId != T3_CHIP_ID_5704_A0) &&
6925             (pDevice->ChipRevId != T3_CHIP_ID_5704_A1))
6926         {
6927             WorkAround = 1;
6928             if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
6929             {
6930                 PortA = 0;
6931             }
6932
6933             if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6934             {
6935                 /* Save voltage reg bits & bits 14:0 */
6936                 SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
6937                               (BIT_23 | BIT_22 | BIT_21 | BIT_20 | 0x7fff );
6938
6939             }
6940             else
6941             { 
6942                 /* preserve the voltage regulator bits */
6943                 SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
6944                                    (BIT_23 | BIT_22 | BIT_21 | BIT_20);
6945             }
6946         }
6947         SgDigCtrl = REG_RD(pDevice, MacCtrl.SgDigControl);
6948         if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
6949             (pDevice->DisableAutoNeg == FALSE))
6950         {
6951         
6952             ExpectedSgDigCtrl = 0x81388400;
6953             LocalPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
6954             if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
6955             {
6956                 ExpectedSgDigCtrl |= BIT_11;
6957             }
6958             if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
6959             {
6960                 ExpectedSgDigCtrl |= BIT_12;
6961             }
6962             if (SgDigCtrl != ExpectedSgDigCtrl)
6963             {
6964                 if (WorkAround)
6965                 {
6966                     if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
6967                     {
6968                          REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011000 | SerdesCfg);                   
6969                     }
6970                     else
6971                     {
6972                         REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011880 | SerdesCfg);
6973                     }
6974                 }
6975                 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl |
6976                     BIT_30);
6977                 REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
6978                 MM_Wait(5);
6979                 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl);
6980                 pDevice->AutoNegJustInited = TRUE;
6981             }
6982             /* If autoneg is off, you only get SD when link is up */
6983             else if(MacStatus & (MAC_STATUS_PCS_SYNCED |
6984                 MAC_STATUS_SIGNAL_DETECTED))
6985             {
6986                 SgDigStatus = REG_RD(pDevice, MacCtrl.SgDigStatus);
6987                 if ((SgDigStatus & BIT_1) &&
6988                     (MacStatus & MAC_STATUS_PCS_SYNCED))
6989                 {
6990                     /* autoneg. completed */
6991                     RemotePhyAd = 0;
6992                     if(SgDigStatus & BIT_19)
6993                     {
6994                         RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
6995                     }
6996
6997                     if(SgDigStatus & BIT_20)
6998                     {
6999                         RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
7000                     }
7001
7002                     LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
7003                     CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7004                     pDevice->AutoNegJustInited = FALSE;
7005                 }
7006                 else if (!(SgDigStatus & BIT_1))
7007                 {
7008                     if (pDevice->AutoNegJustInited == TRUE)
7009                     {
7010                         /* we may be checking too soon, so check again */
7011                         /* at the next poll interval */
7012                         pDevice->AutoNegJustInited = FALSE;
7013                     }
7014                     else
7015                     {
7016                         /* autoneg. failed */
7017                         if (WorkAround)
7018                         {
7019                             if (PortA)
7020                             {
7021                                 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
7022                                 {
7023                                     REG_WR(pDevice, MacCtrl.SerdesCfg,
7024                                         0xc010000 | (SerdesCfg & ~0x00001000));
7025                                 }
7026                                 else
7027                                 {
7028                                     REG_WR(pDevice, MacCtrl.SerdesCfg,
7029                                         0xc010880 | SerdesCfg);
7030                                 }
7031                             }
7032                             else
7033                             {
7034                                 if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
7035                                 {
7036                                     REG_WR(pDevice, MacCtrl.SerdesCfg,
7037                                         0x4010000 | (SerdesCfg & ~0x00001000));
7038                                 }
7039                                 else
7040                                 {
7041                                     REG_WR(pDevice, MacCtrl.SerdesCfg,
7042                                         0x4010880 | SerdesCfg);
7043                                 }
7044                             }
7045                         }
7046                         /* turn off autoneg. to allow traffic to pass */
7047                         REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
7048                         REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
7049                         MM_Wait(40);
7050                         MacStatus = REG_RD(pDevice, MacCtrl.Status);
7051                         if ((MacStatus & MAC_STATUS_PCS_SYNCED) && !(MacStatus & MAC_STATUS_RECEIVING_CFG)) 
7052                         {
7053                             LM_SetFlowControl(pDevice, 0, 0);
7054                             CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7055                         }
7056                     }
7057                 }
7058             }
7059         }
7060         else
7061         {
7062             if (SgDigCtrl & BIT_31) {
7063                 if (WorkAround)
7064                 {
7065                     if (PortA)
7066                     {
7067
7068                        if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
7069                        {
7070                            REG_WR(pDevice, MacCtrl.SerdesCfg,
7071                                   0xc010000 | (SerdesCfg & ~0x00001000));
7072                        }
7073                        else
7074                        {
7075                             REG_WR(pDevice, MacCtrl.SerdesCfg,
7076                                  0xc010880 | SerdesCfg);
7077                        }
7078                     }
7079                     else
7080                     {
7081                        if(pDevice->TbiFlags & TBI_DO_PREEMPHASIS)
7082                        {
7083                            REG_WR(pDevice, MacCtrl.SerdesCfg,
7084                                 0x4010000 | (SerdesCfg & ~0x00001000));
7085                        }
7086                        else
7087                        {
7088                            REG_WR(pDevice, MacCtrl.SerdesCfg,
7089                                0x4010880 | SerdesCfg);
7090                        }
7091                     }
7092                 }
7093                 REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
7094             }
7095             if(MacStatus & MAC_STATUS_PCS_SYNCED)
7096             {
7097                 LM_SetFlowControl(pDevice, 0, 0);
7098                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7099             }
7100         }
7101     }
7102     else if(MacStatus & MAC_STATUS_PCS_SYNCED)
7103     {
7104         if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
7105             (pDevice->DisableAutoNeg == FALSE))
7106         {
7107             /* auto-negotiation mode. */
7108             /* Initialize the autoneg default capaiblities. */
7109             AutonegInit(&pDevice->AnInfo);
7110
7111             /* Set the context pointer to point to the main device structure. */
7112             pDevice->AnInfo.pContext = pDevice;
7113
7114             /* Setup flow control advertisement register. */
7115             Value32 = GetPhyAdFlowCntrlSettings(pDevice);
7116             if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
7117             {
7118                 pDevice->AnInfo.mr_adv_sym_pause = 1;
7119             }
7120             else
7121             {
7122                 pDevice->AnInfo.mr_adv_sym_pause = 0;
7123             }
7124
7125             if(Value32 & PHY_AN_AD_ASYM_PAUSE)
7126             {
7127                 pDevice->AnInfo.mr_adv_asym_pause = 1;
7128             }
7129             else
7130             {
7131                 pDevice->AnInfo.mr_adv_asym_pause = 0;
7132             }
7133
7134             /* Try to autoneg up to six times. */
7135             if (pDevice->IgnoreTbiLinkChange)
7136             {
7137                 Cnt = 1;
7138             }
7139             else
7140             {
7141                 Cnt = 6;
7142             }
7143             for (j = 0; j < Cnt; j++)
7144             {
7145                 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
7146
7147                 Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
7148                 REG_WR(pDevice, MacCtrl.Mode, Value32);
7149                 REG_RD_BACK(pDevice, MacCtrl.Mode);
7150                 MM_Wait(20);
7151
7152                 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
7153                     MAC_MODE_SEND_CONFIGS);
7154                 REG_RD_BACK(pDevice, MacCtrl.Mode);
7155
7156                 MM_Wait(20);
7157
7158                 pDevice->AnInfo.State = AN_STATE_UNKNOWN;
7159                 pDevice->AnInfo.CurrentTime_us = 0;
7160
7161                 REG_WR(pDevice, Grc.Timer, 0);
7162                 for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
7163                     (k < 75000); k++)
7164                 {
7165                     AnStatus = Autoneg8023z(&pDevice->AnInfo);
7166
7167                     if((AnStatus == AUTONEG_STATUS_DONE) || 
7168                         (AnStatus == AUTONEG_STATUS_FAILED))
7169                     {
7170                         break;
7171                     }
7172
7173                     pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
7174                 
7175                 }
7176                 if((AnStatus == AUTONEG_STATUS_DONE) || 
7177                     (AnStatus == AUTONEG_STATUS_FAILED))
7178                 {
7179                     break;
7180                 }
7181                 if (j >= 1)
7182                 {
7183                     if (!(REG_RD(pDevice, MacCtrl.Status) &
7184                         MAC_STATUS_PCS_SYNCED)) {
7185                         break;
7186                     }
7187                 }
7188             }
7189
7190             /* Stop sending configs. */
7191             MM_AnTxIdle(&pDevice->AnInfo);
7192
7193             /* Resolve flow control settings. */
7194             if((AnStatus == AUTONEG_STATUS_DONE) &&
7195                 pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
7196                 pDevice->AnInfo.mr_lp_adv_full_duplex)
7197                 {
7198                 LM_UINT32 RemotePhyAd;
7199                 LM_UINT32 LocalPhyAd;
7200
7201                 LocalPhyAd = 0;
7202                 if(pDevice->AnInfo.mr_adv_sym_pause)
7203                 {
7204                     LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
7205                 }
7206
7207                 if(pDevice->AnInfo.mr_adv_asym_pause)
7208                 {
7209                     LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
7210                 }
7211
7212                 RemotePhyAd = 0;
7213                 if(pDevice->AnInfo.mr_lp_adv_sym_pause)
7214                 {
7215                     RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
7216                 }
7217
7218                 if(pDevice->AnInfo.mr_lp_adv_asym_pause)
7219                 {
7220                     RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
7221                 }
7222
7223                 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
7224
7225                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7226             }
7227             else
7228             {
7229                 LM_SetFlowControl(pDevice, 0, 0);
7230             }
7231             for (j = 0; j < 30; j++)
7232             {
7233                 MM_Wait(20);
7234                 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7235                     MAC_STATUS_CFG_CHANGED);
7236                 REG_RD_BACK(pDevice, MacCtrl.Status);
7237                 MM_Wait(20);
7238                 if ((REG_RD(pDevice, MacCtrl.Status) &
7239                     (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
7240                     break;
7241             }
7242             if (pDevice->TbiFlags & TBI_POLLING_FLAGS)
7243             {
7244                 Value32 = REG_RD(pDevice, MacCtrl.Status);
7245                 if (Value32 & MAC_STATUS_RECEIVING_CFG)
7246                 {
7247                     pDevice->IgnoreTbiLinkChange = TRUE;
7248                 }
7249                 else if (pDevice->TbiFlags & TBI_POLLING_INTR_FLAG)
7250                 {
7251                     pDevice->IgnoreTbiLinkChange = FALSE;
7252                 }
7253             }
7254             Value32 = REG_RD(pDevice, MacCtrl.Status);
7255             if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
7256                  (Value32 & MAC_STATUS_PCS_SYNCED) &&
7257                  ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
7258             {
7259                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7260             }
7261         }
7262         else
7263         {
7264             /* We are forcing line speed. */
7265             pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
7266             LM_SetFlowControl(pDevice, 0, 0);
7267
7268             CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7269             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
7270                 MAC_MODE_SEND_CONFIGS);
7271         }
7272     }
7273     /* Set the link polarity bit. */
7274     pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7275     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7276
7277     pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7278             (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7279     
7280     for (j = 0; j < 100; j++)
7281     {
7282         REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7283             MAC_STATUS_CFG_CHANGED);
7284         REG_RD_BACK(pDevice, MacCtrl.Status);
7285         MM_Wait(5);
7286         if ((REG_RD(pDevice, MacCtrl.Status) &
7287             (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
7288             break;
7289     }
7290
7291     Value32 = REG_RD(pDevice, MacCtrl.Status);
7292     if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
7293     {
7294         CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7295         if (pDevice->DisableAutoNeg == FALSE)
7296         {
7297             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
7298                 MAC_MODE_SEND_CONFIGS);
7299             REG_RD_BACK(pDevice, MacCtrl.Mode);
7300             MM_Wait(1);
7301             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7302         }
7303     }
7304
7305     /* Initialize the current link status. */
7306     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7307     {
7308         pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
7309         pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
7310         REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
7311             LED_CTRL_OVERRIDE_LINK_LED |
7312             LED_CTRL_1000MBPS_LED_ON);
7313     }
7314     else
7315     {
7316         pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
7317         pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
7318         REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
7319             LED_CTRL_OVERRIDE_LINK_LED |
7320             LED_CTRL_OVERRIDE_TRAFFIC_LED);
7321     }
7322
7323     /* Indicate link status. */
7324     if ((pDevice->LinkStatus != CurrentLinkStatus) ||
7325         ((CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
7326         (PreviousFlowControl != pDevice->FlowControl)))
7327     {
7328         pDevice->LinkStatus = CurrentLinkStatus;
7329         MM_IndicateStatus(pDevice, CurrentLinkStatus);
7330     }
7331
7332     return LM_STATUS_SUCCESS;
7333 }
7334 #endif /* INCLUDE_TBI_SUPPORT */
7335
7336
7337 /******************************************************************************/
7338 /* Description:                                                               */
7339 /*                                                                            */
7340 /* Return:                                                                    */
7341 /******************************************************************************/
7342 LM_STATUS
7343 LM_SetupCopperPhy(
7344     PLM_DEVICE_BLOCK pDevice)
7345 {
7346     LM_STATUS CurrentLinkStatus;
7347     LM_UINT32 Value32;
7348
7349     /* Assume there is not link first. */
7350     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7351
7352     /* Disable phy link change attention. */
7353     REG_WR(pDevice, MacCtrl.MacEvent, 0);
7354
7355     /* Clear link change attention. */
7356     REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7357         MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
7358         MAC_STATUS_LINK_STATE_CHANGED);
7359
7360     /* Disable auto-polling for the moment. */
7361     pDevice->MiMode = 0xc0000;
7362     REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
7363     REG_RD_BACK(pDevice, MacCtrl.MiMode);
7364     MM_Wait(40);
7365
7366     /* Determine the requested line speed and duplex. */
7367     pDevice->OldLineSpeed = pDevice->LineSpeed;
7368     pDevice->LineSpeed = pDevice->RequestedLineSpeed;
7369     pDevice->DuplexMode = pDevice->RequestedDuplexMode;
7370
7371     /* Set the phy to loopback mode. */
7372     if ((pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE) ||
7373         (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE))
7374     {
7375         LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7376         if(!(Value32 & PHY_CTRL_LOOPBACK_MODE) &&
7377             (pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE))
7378         {
7379             /* Disable link change and PHY interrupts. */
7380             REG_WR(pDevice, MacCtrl.MacEvent, 0);
7381
7382             /* Clear link change attention. */
7383             REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7384                 MAC_STATUS_CFG_CHANGED);
7385
7386             LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
7387             MM_Wait(40);
7388
7389             pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7390             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
7391                 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 ||
7392                 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
7393                 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705 ||
7394                 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 &&
7395                 (pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID))
7396             {
7397                 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7398             }
7399
7400             /* Prevent the interrupt handling from being called. */
7401             pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7402                     (pDevice->pStatusBlkVirt->Status &
7403                     ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7404
7405             /* GMII interface. */
7406             pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
7407             pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7408             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7409             REG_RD_BACK(pDevice, MacCtrl.Mode);
7410             MM_Wait(40);
7411
7412             /* Configure PHY led mode. */
7413             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
7414                 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
7415             {
7416                 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 
7417                     BCM540X_EXT_CTRL_LINK3_LED_MODE);
7418                 MM_Wait(40);
7419             }
7420
7421             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
7422             {
7423                 int j = 0;
7424
7425                 while (REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE)
7426                 {
7427                     MM_Wait(40);
7428                     j++;
7429                     if (j > 20)
7430                         break;
7431                 }
7432
7433                 Value32 = DMA_WRITE_MODE_ENABLE |
7434                     DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
7435                     DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
7436                     DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
7437                     DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
7438                     DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
7439                     DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
7440                     DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
7441                     DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
7442                 REG_WR(pDevice, DmaWrite.Mode, Value32);
7443             }
7444         }
7445
7446         pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7447         MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
7448
7449         return LM_STATUS_SUCCESS;
7450     }
7451
7452     LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7453     if(Value32 & PHY_CTRL_LOOPBACK_MODE)
7454     {
7455         CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7456
7457         /* Re-enable link change interrupt.  This was disabled when we */
7458         /* enter loopback mode. */
7459         if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
7460         {
7461             REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
7462         }
7463         else
7464         {
7465             REG_WR(pDevice, MacCtrl.MacEvent, 
7466                 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7467         }
7468     }
7469     else
7470     {
7471         /* Initialize the phy chip. */
7472         CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
7473     }
7474
7475     if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
7476     {
7477         CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7478     }
7479     
7480     /* Setup flow control. */
7481     pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
7482     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7483     {
7484         LM_FLOW_CONTROL FlowCap;     /* Flow control capability. */
7485
7486         FlowCap = LM_FLOW_CONTROL_NONE;
7487
7488         if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
7489         {
7490             if(pDevice->DisableAutoNeg == FALSE ||
7491                 pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
7492             {
7493                 LM_UINT32 ExpectedPhyAd;
7494                 LM_UINT32 LocalPhyAd;
7495                 LM_UINT32 RemotePhyAd;
7496
7497                 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
7498                 pDevice->advertising = LocalPhyAd;
7499                 LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
7500
7501                 ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
7502
7503                 if(LocalPhyAd != ExpectedPhyAd)
7504                 {
7505                     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
7506                 }
7507                 else
7508                 {
7509                     LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
7510                         &RemotePhyAd);
7511
7512                     LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
7513                 }
7514             }
7515             else
7516             {
7517                 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
7518                 LM_SetFlowControl(pDevice, 0, 0);
7519             }
7520         }
7521     }
7522
7523     if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
7524     {
7525         LM_ForceAutoNeg(pDevice);
7526
7527         /* If we force line speed, we make get link right away. */
7528         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7529         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7530         if(Value32 & PHY_STATUS_LINK_PASS)
7531         {
7532             CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
7533         }
7534     }
7535
7536     /* GMII interface. */
7537     pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
7538     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7539     {
7540         if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
7541             pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
7542         {
7543             pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
7544         }
7545         else
7546         {
7547             pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7548         }
7549     }
7550     else {
7551         pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7552     }
7553
7554     /* Set the MAC to operate in the appropriate duplex mode. */
7555     pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
7556     if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
7557     {
7558         pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
7559     }
7560
7561     /* Set the link polarity bit. */
7562     pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
7563     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
7564     {
7565         if((pDevice->LedCtrl == LED_CTRL_PHY_MODE_2) ||
7566              (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
7567              pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
7568         {
7569             pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7570         }
7571     }
7572     else
7573     {
7574         if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
7575         {
7576             pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
7577         }
7578     }
7579
7580     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7581
7582     /* Enable auto polling. */
7583     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
7584     {
7585         pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
7586         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
7587     }
7588     /* if using MAC led mode and not using auto polling, need to configure */
7589     /* mi status register */
7590     else if ((pDevice->LedCtrl &
7591             (LED_CTRL_PHY_MODE_1 | LED_CTRL_PHY_MODE_2)) == 0)
7592     {
7593         if (CurrentLinkStatus != LM_STATUS_LINK_ACTIVE)
7594         {
7595             REG_WR(pDevice, MacCtrl.MiStatus, 0);
7596         }
7597         else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
7598         {
7599             REG_WR(pDevice, MacCtrl.MiStatus,
7600                 MI_STATUS_ENABLE_LINK_STATUS_ATTN | MI_STATUS_10MBPS);
7601         }
7602         else
7603         {
7604             REG_WR(pDevice, MacCtrl.MiStatus,
7605                 MI_STATUS_ENABLE_LINK_STATUS_ATTN);
7606         }
7607     }
7608
7609     /* Enable phy link change attention. */
7610     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
7611     {
7612         REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
7613     }
7614     else
7615     {
7616         REG_WR(pDevice, MacCtrl.MacEvent, 
7617             MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7618     }
7619     if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
7620         (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
7621         (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
7622         (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
7623           (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
7624          !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
7625     {
7626         MM_Wait(120);
7627         REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7628             MAC_STATUS_CFG_CHANGED);
7629         MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
7630             T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
7631     }
7632
7633     /* Indicate link status. */
7634     if (pDevice->LinkStatus != CurrentLinkStatus) {
7635         pDevice->LinkStatus = CurrentLinkStatus;
7636         MM_IndicateStatus(pDevice, CurrentLinkStatus);
7637     }
7638
7639     return LM_STATUS_SUCCESS;
7640 } /* LM_SetupCopperPhy */
7641
7642
7643 void
7644 LM_5714_FamForceFiber(
7645     PLM_DEVICE_BLOCK pDevice)
7646 {
7647     u32 Creg, new_bmcr;
7648     LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7649
7650     new_bmcr = Creg & ~PHY_CTRL_AUTO_NEG_ENABLE; 
7651  
7652     if ( pDevice->RequestedDuplexMode == 0 ||
7653         pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_FULL){
7654
7655         new_bmcr |= PHY_CTRL_FULL_DUPLEX_MODE;
7656     }
7657
7658     if(Creg == new_bmcr)
7659         return;
7660
7661     new_bmcr |= PHY_CTRL_SPEED_SELECT_1000MBPS; /* Reserve bit */
7662
7663     /* Force a linkdown */
7664     LM_WritePhy(pDevice, PHY_AN_AD_REG, 0);
7665     LM_WritePhy(pDevice, PHY_CTRL_REG, new_bmcr | 
7666                          PHY_CTRL_RESTART_AUTO_NEG |
7667                          PHY_CTRL_AUTO_NEG_ENABLE  |
7668                          PHY_CTRL_SPEED_SELECT_1000MBPS);
7669     MM_Wait(10);
7670
7671     /* Force it */
7672     LM_WritePhy(pDevice, PHY_CTRL_REG, new_bmcr);
7673     MM_Wait(10);
7674
7675     return;
7676
7677 }/* LM_5714_FamForceFiber */
7678
7679
7680 void
7681 LM_5714_FamGoFiberAutoNeg(
7682         PLM_DEVICE_BLOCK pDevice)
7683 {
7684     u32 adv,Creg,new;
7685
7686     LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7687     LM_ReadPhy(pDevice,PHY_AN_AD_REG, &adv);
7688
7689     new = adv & ~(  PHY_AN_AD_1000XFULL | 
7690                     PHY_AN_AD_1000XHALF |
7691                     PHY_AN_AD_1000XPAUSE |
7692                     PHY_AN_AD_1000XPSE_ASYM |
7693                     0x1f);
7694
7695     new |= PHY_AN_AD_1000XPAUSE;
7696
7697     new |=  PHY_AN_AD_1000XFULL; 
7698     new |=  PHY_AN_AD_1000XHALF;
7699
7700     if ((new != adv) || !(Creg & PHY_CTRL_AUTO_NEG_ENABLE)){
7701         LM_WritePhy(pDevice, PHY_AN_AD_REG, new);
7702         MM_Wait(5);
7703         pDevice->AutoNegJustInited=1;
7704         LM_WritePhy(pDevice, PHY_CTRL_REG, (Creg | 
7705             PHY_CTRL_RESTART_AUTO_NEG | 
7706             PHY_CTRL_SPEED_SELECT_1000MBPS |
7707             PHY_CTRL_AUTO_NEG_ENABLE) );
7708     }
7709
7710     return;
7711 } /* 5714_FamGoFiberAutoNeg */
7712  
7713
7714 void
7715 LM_5714_FamDoFiberLoopback(PLM_DEVICE_BLOCK pDevice)
7716 {
7717     u32 Value32;
7718     
7719     LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7720
7721     if( !(Value32 & PHY_CTRL_LOOPBACK_MODE) )
7722     {
7723         LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
7724
7725         /* Prevent the interrupt handling from being called. */
7726         pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
7727                  (pDevice->pStatusBlkVirt->Status &
7728                  ~STATUS_BLOCK_LINK_CHANGED_STATUS);
7729     }
7730   
7731     pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7732     MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
7733   
7734     return; 
7735
7736 }/* 5714_FamDoFiberLoopBack */
7737
7738
7739 /******************************************************************************/
7740 /* Description:                                                               */
7741 /*                                                                            */
7742 /* Return:                                                                    */
7743 /******************************************************************************/
7744
7745 LM_STATUS
7746 LM_SetupNewFiberPhy(
7747     PLM_DEVICE_BLOCK pDevice)
7748 {
7749     LM_STATUS LmStatus = LM_STATUS_SUCCESS;
7750     u32 Creg,Sreg,rsav;
7751
7752     rsav = pDevice->LinkStatus;
7753
7754     pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII; 
7755     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7756     MM_Wait(40);
7757
7758      /* Disable phy link change attention. */
7759     REG_WR(pDevice, MacCtrl.MacEvent, 0);
7760
7761     /* Clear link change attention. */
7762     REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
7763         MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
7764         MAC_STATUS_LINK_STATE_CHANGED);
7765        
7766
7767     if( (pDevice->PhyFlags & PHY_FIBER_FALLBACK) &&  
7768         ( pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ){
7769
7770         /* do nothing */
7771     }else if ( pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE){
7772
7773         LM_5714_FamDoFiberLoopback(pDevice);
7774         goto fiberloopbackreturn;
7775
7776     } else if( pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) { 
7777
7778         LM_5714_FamGoFiberAutoNeg(pDevice);
7779
7780
7781     }else {
7782
7783         LM_5714_FamForceFiber(pDevice);
7784     }
7785     LM_ReadPhy(pDevice, PHY_STATUS_REG, &Sreg);
7786     LM_ReadPhy(pDevice, PHY_STATUS_REG, &Sreg);
7787
7788     if(Sreg & PHY_STATUS_LINK_PASS){
7789
7790         pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
7791         pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
7792
7793         LM_ReadPhy(pDevice, PHY_CTRL_REG, &Creg);
7794
7795         if(Creg & PHY_CTRL_FULL_DUPLEX_MODE) {
7796             pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
7797         }else{
7798             pDevice->DuplexMode = LM_DUPLEX_MODE_HALF;
7799             pDevice->MacMode |= MAC_MODE_HALF_DUPLEX; 
7800             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7801         }
7802
7803         if(Creg & PHY_CTRL_AUTO_NEG_ENABLE){
7804             u32 ours,partner;
7805
7806             LM_ReadPhy(pDevice,PHY_AN_AD_REG, &ours);
7807             LM_ReadPhy(pDevice,PHY_LINK_PARTNER_ABILITY_REG, &partner);
7808             LM_SetFlowControl(pDevice, ours, partner);
7809         }
7810
7811     }else{      
7812         pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
7813         pDevice->LineSpeed = 0;
7814     }
7815
7816     if(rsav != pDevice->LinkStatus)
7817         MM_IndicateStatus(pDevice, pDevice->LinkStatus);
7818
7819 fiberloopbackreturn:
7820     pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
7821     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
7822     MM_Wait(40);
7823     /* Enable link change interrupt. */
7824     REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
7825
7826     return LmStatus;
7827 } /* Setup New phy */
7828
7829 void
7830 LM_5714_FamFiberCheckLink(
7831     PLM_DEVICE_BLOCK pDevice)
7832 {
7833
7834     if(pDevice->AutoNegJustInited){
7835         pDevice->AutoNegJustInited=0;
7836         return;
7837     }
7838
7839     if ((pDevice->LinkStatus != LM_STATUS_LINK_ACTIVE) &&
7840         (pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) &&
7841         !(pDevice->PhyFlags &  PHY_FIBER_FALLBACK)){
7842         u32 bmcr;
7843
7844         LM_ReadPhy(pDevice, PHY_CTRL_REG, &bmcr);
7845         if (bmcr & PHY_CTRL_AUTO_NEG_ENABLE) {
7846             u32 phy1, phy2;
7847
7848             LM_WritePhy(pDevice, 0x1c, 0x7c00);
7849             LM_ReadPhy(pDevice, 0x1c, &phy1);
7850
7851             LM_WritePhy(pDevice, 0x17, 0x0f01);
7852             LM_ReadPhy(pDevice, 0x15, &phy2);
7853             LM_ReadPhy(pDevice, 0x15, &phy2);
7854
7855             if ((phy1 & 0x10) && !(phy2 & 0x20)) {
7856
7857                 /* We have signal detect and not receiving
7858                  * configs.
7859                  */
7860
7861                 pDevice->PhyFlags |= PHY_FIBER_FALLBACK;
7862                 LM_5714_FamForceFiber(pDevice);
7863             }
7864         }
7865     }
7866     else if ( (pDevice->PhyFlags & PHY_FIBER_FALLBACK) &&
7867               (pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)) {
7868             u32 phy2;
7869
7870             LM_WritePhy(pDevice, 0x17, 0x0f01);
7871             LM_ReadPhy(pDevice, 0x15, &phy2);
7872             if (phy2 & 0x20) {
7873                 /* Receiving configs. */
7874
7875                 pDevice->PhyFlags &= ~PHY_FIBER_FALLBACK;
7876                 LM_5714_FamGoFiberAutoNeg(pDevice);
7877         }
7878     }
7879
7880 } /* LM_5714_FamFiberCheckLink */
7881
7882
7883 /******************************************************************************/
7884 /* Description:                                                               */
7885 /*                                                                            */
7886 /* Return:                                                                    */
7887 /******************************************************************************/
7888 LM_STATUS
7889 LM_SetupPhy(
7890     PLM_DEVICE_BLOCK pDevice)
7891 {
7892     LM_STATUS LmStatus;
7893     LM_UINT32 Value32;
7894
7895     if(pDevice->PhyFlags & PHY_IS_FIBER)
7896     {
7897        LmStatus = LM_SetupNewFiberPhy(pDevice);
7898     }else 
7899 #ifdef INCLUDE_TBI_SUPPORT
7900     if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
7901     {
7902         LmStatus = LM_SetupFiberPhy(pDevice);
7903     }
7904     else
7905 #endif /* INCLUDE_TBI_SUPPORT */
7906     {
7907         LmStatus = LM_SetupCopperPhy(pDevice);
7908     }
7909     if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
7910     {
7911         if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
7912         {
7913             Value32 = REG_RD(pDevice, PciCfg.PciState);
7914             REG_WR(pDevice, PciCfg.PciState,
7915                 Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
7916         }
7917     }
7918     if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
7919         (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
7920     {
7921         REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
7922     }
7923     else
7924     {
7925         REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
7926     }
7927     if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
7928     {
7929         if (pDevice->LinkStatus == LM_STATUS_LINK_DOWN)
7930         {
7931             REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks, 0);
7932         }
7933         else
7934         {
7935             REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
7936                 pDevice->StatsCoalescingTicks);
7937         }
7938     }
7939
7940     return LmStatus;
7941 }
7942
7943
7944 /* test data pattern */
7945 static LM_UINT32 pattern[4][6] = {
7946     /* For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
7947     For 5705   , each DFE TAP has 19-bits (low word 15, hi word 4)
7948     For simplicity, we check only 19-bits, so we don't have to
7949     distinguish which chip it is.
7950     the LO word contains 15 bits, make sure pattern data is < 0x7fff
7951     the HI word contains  6 bits, make sure pattern data is < 0x003f */
7952     {0x00005555, 0x00000005, /* ch0, TAP 0, LO/HI pattern */
7953     0x00002aaa, 0x0000000a,  /* ch0, TAP 1, LO/HI pattern */
7954     0x00003456, 0x00000003}, /* ch0, TAP 2, LO/HI pattern */
7955
7956     {0x00002aaa, 0x0000000a, /* ch1, TAP 0, LO/HI pattern */
7957     0x00003333, 0x00000003,  /* ch1, TAP 1, LO/HI pattern */
7958     0x0000789a, 0x00000005}, /* ch1, TAP 2, LO/HI pattern */
7959
7960     {0x00005a5a, 0x00000005, /* ch2, TAP 0, LO/HI pattern */
7961     0x00002a6a, 0x0000000a,  /* ch2, TAP 1, LO/HI pattern */
7962     0x00001bcd, 0x00000003}, /* ch2, TAP 2, LO/HI pattern */
7963
7964     {0x00002a5a, 0x0000000a, /* ch3, TAP 0, LO/HI pattern */
7965     0x000033c3, 0x00000003,  /* ch3, TAP 1, LO/HI pattern */
7966     0x00002ef1, 0x00000005}, /* ch3, TAP 2, LO/HI pattern */
7967 };
7968
7969 /********************************************************/
7970 /* Routine to wait for PHY Macro Command to complete    */
7971 /*                                                      */
7972 /* If PHY's Macro operation keeps stay busy, nothing we */
7973 /* can do anyway.  The timeout is there so we won't     */
7974 /* stay in this routine indefinitly.                    */
7975 /********************************************************/
7976 static LM_UINT32 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice);
7977
7978 static LM_UINT32
7979 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice)
7980 {
7981     LM_UINT32 timeout;
7982     LM_UINT32 val32;
7983
7984     timeout = 100;
7985     while (timeout--)
7986     {
7987         /* make sure the MACRO operation is complete */
7988         LM_ReadPhy(pDevice, 0x16, &val32);
7989         if ((val32 & 0x1000) == 0) break;
7990     }
7991
7992     return( timeout > 0 );
7993 }
7994
7995 /********************************************************/
7996 /* This routine resets the PHY on following chips:      */
7997 /*      5703, 04, CIOB-E and 5705                       */
7998 /*                                                      */
7999 /* This routine will issue PHY_RESET and check if       */
8000 /* the reset is sucessful.  If not, another PHY RESET   */
8001 /* will be issued, until max "retry" reaches            */
8002 /*                                                      */
8003 /* Input:                                               */
8004 /*      pDevice - device's context                      */
8005 /*      retry   - number of retries                     */
8006 /*      reset   - TRUE=will cause a PHY reset initially */
8007 /*                FALSE = will not issue a PHY reset    */
8008 /*                        unless TAP lockup detected    */
8009 /*                                                      */
8010 /* Output:                                              */
8011 /*      TRUE    - PHY Reset is done sucessfully         */
8012 /*      FALSE   - PHY Reset had failed, after "retry"   */
8013 /*                has reached                           */
8014 /*                                                      */
8015 /* Dependencies:                                        */
8016 /*      void LM_wait_macro_done()                       */
8017 /*      u32  pattern[]                                  */
8018 /*                                                      */
8019 /* Usage:                                               */
8020 /*      a. Before calling this routine, caller must     */
8021 /*         determine if the chip is a 5702/03/04 or     */
8022 /*         CIOB-E, and only call this routine if the    */
8023 /*         is one of these.                             */
8024 /*         or its derivatives.                          */
8025 /*      b. Instead of using MII register write to reset */
8026 /*         the PHY, call this routine instead           */
8027 /*      c. Upon return from this routine, check return  */
8028 /*         value (TRUE/FALSE) to determine if PHY reset */
8029 /*         is successful of not and "optionally" take   */
8030 /*         appropriate action (such as: event log)      */
8031 /*      d. Regardless of the return TRUE or FALSE,      */
8032 /*         proceed with PHY setup as you normally would */
8033 /*         after a PHY_RESET.                           */
8034 /*      e. It is recommended that the caller will give  */
8035 /*         10 "retry", however, caller can change to a  */
8036 /*         different number, depending on you code.     */
8037 /*                                                      */
8038 /********************************************************/
8039 LM_STATUS LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset);
8040
8041 LM_STATUS
8042 LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset)
8043 {
8044     LM_UINT32 val32, save9;
8045     LM_UINT32 dataLo, dataHi;
8046     int i, channel;
8047     int      reset_success = LM_STATUS_FAILURE;
8048     int      force_reset;
8049
8050     /* to actually do a PHY_RESET or not is dictated by the caller */
8051     force_reset = reset;
8052
8053     while (retry-- && (reset_success != LM_STATUS_SUCCESS))
8054     {
8055         if (force_reset)
8056         {
8057             /* issue a phy reset, and wait for reset to complete */
8058             LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
8059             for(i = 0; i < 100; i++)
8060             {
8061                 MM_Wait(10);
8062
8063                 LM_ReadPhy(pDevice, PHY_CTRL_REG, &val32);
8064                 if(val32 && !(val32 & PHY_CTRL_PHY_RESET))
8065                 {
8066                     MM_Wait(20);
8067                     break;
8068                 }
8069             }
8070
8071             /* no more phy reset unless lockup detected */
8072             force_reset = FALSE;
8073         }
8074
8075         /* assuming reset is successful first */
8076         reset_success = LM_STATUS_SUCCESS;
8077
8078         /* now go check the DFE TAPs to see if locked up, but
8079            first, we need to set up PHY so we can read DFE TAPs */
8080
8081         /* Disable Transmitter and Interrupt, while we play with
8082            the PHY registers, so the link partner won't see any
8083            strange data and the Driver won't see any interrupts. */
8084         LM_ReadPhy(pDevice, 0x10, &val32);
8085         LM_WritePhy(pDevice, 0x10, val32 | 0x3000);
8086
8087         /* Setup Full-Duplex, 1000 mbps */
8088         LM_WritePhy(pDevice, 0x0, 0x0140);
8089
8090         /* Set to Master mode */
8091         LM_ReadPhy(pDevice, 0x9, &save9);
8092         LM_WritePhy(pDevice, 0x9, 0x1800);
8093
8094         /* Enable SM_DSP_CLOCK & 6dB */
8095         LM_WritePhy(pDevice, 0x18, 0x0c00);
8096
8097         /* blocks the PHY control access */
8098         LM_WritePhy(pDevice, 0x17, 0x8005);
8099         LM_WritePhy(pDevice, 0x15, 0x0800);
8100
8101         /* check TAPs for all 4 channels, as soon
8102            as we see a lockup we'll stop checking */
8103         for (channel=0; (channel<4) && (reset_success == LM_STATUS_SUCCESS);
8104             channel++)
8105         {
8106             /* select channel and set TAP index to 0 */
8107             LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
8108             /* freeze filter again just to be safe */
8109             LM_WritePhy(pDevice, 0x16, 0x0002);
8110
8111             /* write fixed pattern to the RAM, 3 TAPs for
8112                each channel, each TAP have 2 WORDs (LO/HI) */
8113             for (i=0; i<6; i++)
8114                 LM_WritePhy(pDevice, 0x15, pattern[channel][i]);
8115
8116             /* Activate PHY's Macro operation to write DFE TAP from RAM,
8117                and wait for Macro to complete */
8118             LM_WritePhy(pDevice, 0x16, 0x0202);
8119             if (!LM_wait_macro_done(pDevice))
8120             {
8121                 reset_success = LM_STATUS_FAILURE;
8122                 force_reset = TRUE;
8123                 break;
8124             }
8125
8126             /* --- done with write phase, now begin read phase --- */
8127
8128             /* select channel and set TAP index to 0 */
8129             LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
8130
8131             /* Active PHY's Macro operation to load DFE TAP to RAM,
8132                and wait for Macro to complete */
8133             LM_WritePhy(pDevice, 0x16, 0x0082);
8134             if (!LM_wait_macro_done(pDevice))
8135             {
8136                 reset_success = LM_STATUS_FAILURE;
8137                 force_reset = TRUE;
8138                 break;
8139             }
8140
8141             /* enable "pre-fetch" */
8142             LM_WritePhy(pDevice, 0x16, 0x0802);
8143             if (!LM_wait_macro_done(pDevice))
8144             {
8145                 reset_success = LM_STATUS_FAILURE;
8146                 force_reset = TRUE;
8147                 break;
8148             }
8149
8150             /* read back the TAP values.
8151                3 TAPs for each channel, each TAP have 2 WORDs (LO/HI) */
8152             for (i=0; i<6; i+=2)
8153             {
8154                 /* read Lo/Hi then wait for 'done' is faster */
8155                 LM_ReadPhy(pDevice, 0x15, &dataLo);
8156                 LM_ReadPhy(pDevice, 0x15, &dataHi);
8157                 if (!LM_wait_macro_done(pDevice))
8158                 {
8159                     reset_success = LM_STATUS_FAILURE;
8160                     force_reset = TRUE;
8161                     break;
8162                 }
8163
8164                 /* For 5703/04, each DFE TAP has 21-bits (low word 15,
8165                  * hi word 6) For 5705, each DFE TAP pas 19-bits (low word 15,
8166                  * hi word 4) For simplicity, we check only 19-bits, so we
8167                  * don't have to distinguish which chip it is. */
8168                 dataLo &= 0x7fff;
8169                 dataHi &= 0x000f;
8170             
8171                 /* check if what we wrote is what we read back */
8172                 if ( (dataLo != pattern[channel][i]) || (dataHi != pattern[channel][i+1]) )
8173                 {
8174                     /* if failed, then the PHY is locked up,
8175                        we need to do PHY reset again */
8176                     reset_success = LM_STATUS_FAILURE;
8177                     force_reset = TRUE;
8178                     /* 04/25/2003. sb. do these writes before issueing a reset. */
8179                     /* these steps will reduce the chance of back-to-back
8180                      * phy lockup after reset */
8181                     LM_WritePhy(pDevice, 0x17, 0x000B);
8182                     LM_WritePhy(pDevice, 0x15, 0x4001);
8183                     LM_WritePhy(pDevice, 0x15, 0x4005);
8184                     break;
8185                 }
8186             } /* for i */
8187         } /* for channel */
8188     } /* while */
8189
8190     /* restore dfe coeff back to zeros */
8191     for (channel=0; channel<4 ; channel++)
8192     {
8193         LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
8194         LM_WritePhy(pDevice, 0x16, 0x0002);
8195         for (i=0; i<6; i++)
8196             LM_WritePhy(pDevice, 0x15, 0x0000);
8197         LM_WritePhy(pDevice, 0x16, 0x0202);
8198         if (!LM_wait_macro_done(pDevice))
8199         {
8200             reset_success = LM_STATUS_FAILURE;
8201             break;
8202         }
8203     }
8204
8205     /* remove block phy control */
8206     LM_WritePhy(pDevice, 0x17, 0x8005);
8207     LM_WritePhy(pDevice, 0x15, 0x0000);
8208
8209     /* unfreeze DFE TAP filter for all channels */
8210     LM_WritePhy(pDevice, 0x17, 0x8200);
8211     LM_WritePhy(pDevice, 0x16, 0x0000);
8212
8213     /* Restore PHY back to operating state */
8214     LM_WritePhy(pDevice, 0x18, 0x0400);
8215
8216     /* Restore register 9 */
8217     LM_WritePhy(pDevice, 0x9, save9);
8218
8219     /* enable transmitter and interrupt */
8220     LM_ReadPhy(pDevice, 0x10, &val32);
8221     LM_WritePhy(pDevice, 0x10, (val32 & ~0x3000));
8222
8223     return reset_success;
8224 }
8225
8226 LM_VOID
8227 LM_ResetPhy(LM_DEVICE_BLOCK *pDevice)
8228 {
8229     int j;
8230     LM_UINT32 miireg;
8231
8232     if (pDevice->PhyFlags & PHY_CHECK_TAPS_AFTER_RESET)
8233     {
8234         LM_ResetPhy_5703_4_5(pDevice, 5, 1);
8235     }
8236     else
8237     {
8238         int wait_val = 100;
8239         LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
8240
8241         if( pDevice->PhyFlags & PHY_IS_FIBER )
8242             wait_val = 5000;
8243
8244         for(j = 0; j < wait_val; j++)
8245         {
8246             MM_Wait(10);
8247
8248             LM_ReadPhy(pDevice, PHY_CTRL_REG, &miireg);
8249             if(miireg && !(miireg & PHY_CTRL_PHY_RESET))
8250             {
8251                 MM_Wait(20);
8252                 break;
8253             }
8254         }
8255
8256         LM_PhyTapPowerMgmt(pDevice);
8257     }
8258     if ( (pDevice->PhyFlags & PHY_ADC_FIX) && 
8259          !( pDevice->PhyFlags & PHY_IS_FIBER) )
8260     {
8261         LM_WritePhy(pDevice, 0x18, 0x0c00);
8262         LM_WritePhy(pDevice, 0x17, 0x201f);
8263         LM_WritePhy(pDevice, 0x15, 0x2aaa);
8264         LM_WritePhy(pDevice, 0x17, 0x000a);
8265         LM_WritePhy(pDevice, 0x15, 0x0323);
8266         LM_WritePhy(pDevice, 0x18, 0x0400);
8267     }
8268     if ( (pDevice->PhyFlags & PHY_5705_5750_FIX) &&
8269          !( pDevice->PhyFlags & PHY_IS_FIBER) )
8270     {
8271         LM_WritePhy(pDevice, 0x18, 0x0c00);
8272         LM_WritePhy(pDevice, 0x17, 0x000a);
8273         LM_WritePhy(pDevice, 0x15, 0x310b);
8274         LM_WritePhy(pDevice, 0x17, 0x201f);
8275         LM_WritePhy(pDevice, 0x15, 0x9506);
8276         LM_WritePhy(pDevice, 0x17, 0x401f);
8277         LM_WritePhy(pDevice, 0x15, 0x14e2);
8278         LM_WritePhy(pDevice, 0x18, 0x0400);
8279     }
8280     if ( (pDevice->PhyFlags & PHY_5704_A0_FIX) &&
8281          !( pDevice->PhyFlags & PHY_IS_FIBER) )
8282     {
8283         LM_WritePhy(pDevice, 0x1c, 0x8d68);
8284         LM_WritePhy(pDevice, 0x1c, 0x8d68);
8285     }
8286     if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
8287     {
8288        LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &miireg);
8289        miireg |= 1;         /* set tx elastic fifo */
8290        LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, miireg);
8291
8292        LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
8293     }
8294     else if (pDevice->Flags & JUMBO_CAPABLE_FLAG) 
8295     {
8296         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
8297         LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &miireg);
8298         miireg |= 0x4000;    /* set rx extended packet length */
8299         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, miireg);
8300
8301         LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &miireg);
8302         miireg |= 1;         /* set tx elastic fifo */
8303         LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, miireg);
8304
8305     }
8306
8307     LM_SetEthWireSpeed(pDevice);
8308     pDevice->PhyFlags &= ~PHY_FIBER_FALLBACK;
8309 }
8310
8311 STATIC LM_VOID
8312 LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice)
8313 {
8314     LM_UINT32 Value32;
8315
8316     if( pDevice->PhyFlags & PHY_IS_FIBER) 
8317         return;
8318
8319     /* Enable Ethernet@WireSpeed. */
8320     if (pDevice->PhyFlags & PHY_ETHERNET_WIRESPEED)
8321     {
8322         LM_WritePhy(pDevice, 0x18, 0x7007);
8323         LM_ReadPhy(pDevice, 0x18, &Value32);
8324         LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
8325     }
8326 }
8327
8328 STATIC LM_STATUS
8329 LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice)
8330 {
8331     LM_UINT32 miireg;
8332
8333     LM_ReadPhy(pDevice, PHY_AN_AD_REG, &miireg);
8334     pDevice->advertising = miireg;
8335     if ((miireg & PHY_AN_AD_ALL_SPEEDS) != PHY_AN_AD_ALL_SPEEDS)
8336     {
8337         return LM_STATUS_FAILURE;
8338     }
8339
8340     LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &miireg);
8341     pDevice->advertising1000 = miireg;
8342
8343     if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
8344     {
8345         if ((miireg & BCM540X_AN_AD_ALL_1G_SPEEDS) !=
8346             BCM540X_AN_AD_ALL_1G_SPEEDS)
8347         {
8348             return LM_STATUS_FAILURE;
8349         }
8350     }else{
8351         
8352         if(miireg)
8353         {
8354             return LM_STATUS_FAILURE;
8355         }
8356     }
8357     return LM_STATUS_SUCCESS;
8358 }
8359
8360 /******************************************************************************/
8361 /* Description:                                                               */
8362 /*                                                                            */
8363 /* Return:                                                                    */
8364 /******************************************************************************/
8365 LM_VOID
8366 LM_ReadPhy(
8367 PLM_DEVICE_BLOCK pDevice,
8368 LM_UINT32 PhyReg,
8369 PLM_UINT32 pData32) {
8370     LM_UINT32 Value32;
8371     LM_UINT32 j;
8372
8373     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8374     {
8375         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
8376             ~MI_MODE_AUTO_POLLING_ENABLE);
8377         REG_RD_BACK(pDevice, MacCtrl.MiMode);
8378         MM_Wait(40);
8379     }
8380
8381     Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
8382         ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
8383         MI_COM_CMD_READ | MI_COM_START;
8384
8385     REG_WR(pDevice, MacCtrl.MiCom, Value32);
8386     
8387     for(j = 0; j < 200; j++)
8388     {
8389         MM_Wait(1);
8390
8391         Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8392
8393         if(!(Value32 & MI_COM_BUSY))
8394         {
8395             MM_Wait(5);
8396             Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8397             Value32 &= MI_COM_PHY_DATA_MASK;
8398             break;
8399         }
8400     }
8401
8402     if(Value32 & MI_COM_BUSY)
8403     {
8404         Value32 = 0;
8405     }
8406
8407     *pData32 = Value32;
8408
8409     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8410     {
8411         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
8412         REG_RD_BACK(pDevice, MacCtrl.MiMode);
8413         MM_Wait(40);
8414     }
8415 } /* LM_ReadPhy */
8416
8417
8418
8419 /******************************************************************************/
8420 /* Description:                                                               */
8421 /*                                                                            */
8422 /* Return:                                                                    */
8423 /******************************************************************************/
8424 LM_VOID
8425 LM_WritePhy(
8426 PLM_DEVICE_BLOCK pDevice,
8427 LM_UINT32 PhyReg,
8428 LM_UINT32 Data32) {
8429     LM_UINT32 Value32;
8430     LM_UINT32 j;
8431
8432     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8433     {
8434         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
8435             ~MI_MODE_AUTO_POLLING_ENABLE);
8436         REG_RD_BACK(pDevice, MacCtrl.MiMode);
8437         MM_Wait(40);
8438     }
8439
8440     Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
8441         ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
8442         (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
8443
8444     REG_WR(pDevice, MacCtrl.MiCom, Value32);
8445     
8446     for(j = 0; j < 200; j++)
8447     {
8448         MM_Wait(1);
8449
8450         Value32 = REG_RD(pDevice, MacCtrl.MiCom);
8451
8452         if(!(Value32 & MI_COM_BUSY))
8453         {
8454             MM_Wait(5);
8455             break;
8456         }
8457     }
8458
8459     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
8460     {
8461         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
8462         REG_RD_BACK(pDevice, MacCtrl.MiMode);
8463         MM_Wait(40);
8464     }
8465 } /* LM_WritePhy */
8466
8467 STATIC void
8468 LM_GetPhyId(LM_DEVICE_BLOCK *pDevice)
8469 {
8470     LM_UINT32 Value32;
8471
8472     LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
8473     pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
8474
8475     LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
8476     pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
8477         (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
8478
8479 }
8480
8481 LM_STATUS
8482 LM_EnableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
8483 {
8484     pDevice->LoopBackMode = LM_MAC_LOOP_BACK_MODE;
8485     pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
8486     pDevice->MacMode |= (MAC_MODE_PORT_INTERNAL_LOOPBACK |
8487         MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII);
8488     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
8489     MM_Wait(40);    
8490     LM_SetupPhy(pDevice);
8491     return LM_STATUS_SUCCESS;
8492 }
8493
8494 LM_STATUS
8495 LM_DisableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
8496 {
8497     pDevice->LoopBackMode = 0;
8498     
8499     pDevice->MacMode &= ~(MAC_MODE_PORT_INTERNAL_LOOPBACK |
8500             MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_MASK);
8501     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
8502     MM_Wait(40); 
8503     if(pDevice->PhyFlags & PHY_IS_FIBER)
8504         LM_ResetPhy(pDevice);
8505
8506     LM_SetupPhy(pDevice);
8507     return LM_STATUS_SUCCESS;
8508 }
8509
8510 LM_STATUS
8511 LM_EnablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
8512 {
8513     pDevice->LoopBackMode = LM_PHY_LOOP_BACK_MODE;
8514     LM_SetupPhy(pDevice);
8515     return LM_STATUS_SUCCESS;
8516 }
8517
8518 LM_STATUS
8519 LM_DisablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
8520 {
8521     pDevice->LoopBackMode = 0;
8522     LM_SetupPhy(pDevice);
8523     return LM_STATUS_SUCCESS;
8524 }
8525
8526 LM_STATUS
8527 LM_EnableExtLoopBack(PLM_DEVICE_BLOCK pDevice, LM_LINE_SPEED LineSpeed)
8528 {
8529     pDevice->LoopBackMode = LM_EXT_LOOP_BACK_MODE;
8530
8531     pDevice->SavedDisableAutoNeg = pDevice->DisableAutoNeg;
8532     pDevice->SavedRequestedLineSpeed = pDevice->RequestedLineSpeed;
8533     pDevice->SavedRequestedDuplexMode = pDevice->RequestedDuplexMode;
8534
8535     pDevice->DisableAutoNeg = TRUE;
8536     pDevice->RequestedLineSpeed = LineSpeed;
8537     pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
8538     LM_SetupPhy(pDevice);
8539     return LM_STATUS_SUCCESS;
8540 }
8541
8542 LM_STATUS
8543 LM_DisableExtLoopBack(PLM_DEVICE_BLOCK pDevice)
8544 {
8545     pDevice->LoopBackMode = 0;
8546
8547     pDevice->DisableAutoNeg = pDevice->SavedDisableAutoNeg;
8548     pDevice->RequestedLineSpeed = pDevice->SavedRequestedLineSpeed;
8549     pDevice->RequestedDuplexMode = pDevice->SavedRequestedDuplexMode;
8550
8551     LM_SetupPhy(pDevice);
8552     return LM_STATUS_SUCCESS;
8553 }
8554
8555 /******************************************************************************/
8556 /* Description:                                                               */
8557 /*                                                                            */
8558 /* Return:                                                                    */
8559 /******************************************************************************/
8560 LM_STATUS
8561 LM_SetPowerState(
8562 PLM_DEVICE_BLOCK pDevice,
8563 LM_POWER_STATE PowerLevel)
8564 {
8565 #ifdef BCM_WOL
8566     LM_UINT32 PmeSupport;
8567     PLM_DEVICE_BLOCK pDevice2 = 0;
8568     int j; 
8569 #endif
8570     LM_UINT32 Value32;
8571     LM_UINT32 PmCtrl;
8572
8573     /* make sureindirect accesses are enabled*/
8574     MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
8575
8576     /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
8577     /* the PME bit. */
8578     MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
8579
8580     PmCtrl |= T3_PM_PME_ASSERTED;
8581     PmCtrl &= ~T3_PM_POWER_STATE_MASK;
8582
8583     /* Set the appropriate power state. */
8584     if(PowerLevel == LM_POWER_STATE_D0)
8585     {
8586         /* Bring the card out of low power mode. */
8587         PmCtrl |= T3_PM_POWER_STATE_D0;
8588         MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
8589
8590         Value32 = REG_RD(pDevice, Grc.LocalCtrl);
8591
8592         if(T3_ASIC_5752(pDevice->ChipRevId)){
8593             Value32 |= (GRC_MISC_LOCAL_CTRL_GPIO_OE3 |
8594                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT3 | 
8595                         GRC_MISC_LOCAL_CTRL_GPIO_OE0 | 
8596                         GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8597                         GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8598                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8599                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8600                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8601         }
8602         else
8603         {
8604             Value32 &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 | 
8605                         GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8606                         GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8607                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8608                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8609                         GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8610         }
8611
8612         RAW_REG_WR(pDevice, Grc.LocalCtrl, Value32); 
8613
8614         MM_Wait(40);    /* Required delay is about 20us. */
8615
8616         pDevice->PowerLevel = PowerLevel;
8617         return LM_STATUS_SUCCESS;
8618     }
8619 #ifdef BCM_WOL
8620     else if(PowerLevel == LM_POWER_STATE_D1)
8621     {
8622         PmCtrl |= T3_PM_POWER_STATE_D1;
8623     }
8624     else if(PowerLevel == LM_POWER_STATE_D2)
8625     {
8626         PmCtrl |= T3_PM_POWER_STATE_D2;
8627     }
8628     else if(PowerLevel == LM_POWER_STATE_D3)
8629     {
8630         PmCtrl |= T3_PM_POWER_STATE_D3;
8631     }
8632     else
8633     {
8634         return LM_STATUS_FAILURE;
8635     }
8636     PmCtrl |= T3_PM_PME_ENABLE;
8637
8638     /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
8639     /* setting new line speed. */
8640     Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
8641     REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
8642
8643     if(!pDevice->RestoreOnWakeUp)
8644     {
8645         pDevice->RestoreOnWakeUp = TRUE;
8646         pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
8647         pDevice->WakeUpRequestedLineSpeed = pDevice->RequestedLineSpeed;
8648         pDevice->WakeUpRequestedDuplexMode = pDevice->RequestedDuplexMode;
8649     }
8650
8651     /* Force auto-negotiation to 10 line speed. */
8652     pDevice->DisableAutoNeg = FALSE;
8653
8654     if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
8655     {
8656         pDevice->RequestedLineSpeed = LM_LINE_SPEED_10MBPS;
8657         LM_SetupPhy(pDevice);
8658     }
8659
8660     /* Put the driver in the initial state, and go through the power down */
8661     /* sequence. */
8662     LM_DoHalt(pDevice);
8663
8664     if (!(pDevice->AsfFlags & ASF_ENABLED))
8665     {
8666         for(j = 0; j < 20000; j++)
8667         {
8668             MM_Wait(10);
8669
8670             Value32 = MEM_RD_OFFSET(pDevice, T3_ASF_FW_STATUS_MAILBOX);
8671             if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
8672             {
8673                 break;
8674             }
8675         }
8676     }
8677
8678     MEM_WR_OFFSET(pDevice, DRV_WOL_MAILBOX, DRV_WOL_SIGNATURE |
8679         DRV_DOWN_STATE_SHUTDOWN | 0x2 | DRV_WOL_SET_MAGIC_PKT);
8680
8681     MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
8682
8683     if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
8684     {
8685
8686         /* Enable WOL. */
8687         if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
8688         {
8689             LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
8690             MM_Wait(40);
8691         }
8692
8693         if (! T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId))
8694         {
8695             /* Let boot code deal with LED mode on shasta */
8696             REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
8697         }
8698
8699         if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
8700         {
8701             Value32 = MAC_MODE_PORT_MODE_TBI;
8702         }
8703         else
8704         {
8705             Value32 = MAC_MODE_PORT_MODE_MII;
8706             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
8707             {
8708                 if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_2 ||
8709                     pDevice->WolSpeed == WOL_SPEED_10MB)
8710                 {
8711                     Value32 |= MAC_MODE_LINK_POLARITY;
8712                 }
8713             }
8714             else
8715             {
8716                 Value32 |= MAC_MODE_LINK_POLARITY;
8717             }
8718         }
8719         REG_WR(pDevice, MacCtrl.Mode, Value32);
8720         REG_RD_BACK(pDevice, MacCtrl.Mode);
8721         MM_Wait(40); MM_Wait(40); MM_Wait(40);
8722
8723         /* Always enable magic packet wake-up if we have vaux. */
8724         if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) && 
8725             (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
8726         {
8727             Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
8728         }
8729
8730 #ifdef BCM_ASF
8731         if (pDevice->AsfFlags & ASF_ENABLED)
8732         {
8733             Value32 &= ~MAC_MODE_ACPI_POWER_ON_ENABLE;
8734         }
8735 #endif
8736         REG_WR(pDevice, MacCtrl.Mode, Value32);
8737
8738         /* Enable the receiver. */
8739         REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
8740     }
8741     else if (!(pDevice->AsfFlags & ASF_ENABLED))
8742     {
8743         if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
8744         {
8745             REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
8746                 LED_CTRL_OVERRIDE_TRAFFIC_LED);
8747         }
8748         else
8749         {
8750             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
8751                 BCM540X_EXT_CTRL_FORCE_LED_OFF);
8752             LM_WritePhy(pDevice, 0x18, 0x01b2);
8753             if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
8754                 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
8755                 !T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) ) 
8756             {
8757                 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOWER_POWER_MODE);
8758             }
8759         }
8760     }
8761
8762     /* Disable tx/rx clocks, and select an alternate clock. */
8763     if (T3_ASIC_5714_FAMILY(pDevice->ChipRevId)){
8764         /* Do nothing */
8765     }
8766     else if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
8767         ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
8768         (pDevice->WolSpeed == WOL_SPEED_10MB)))
8769     {
8770         Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8771             T3_PCI_SELECT_ALTERNATE_CLOCK |
8772             T3_PCI_POWER_DOWN_PCI_PLL133;
8773
8774         REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8775     }
8776     /* ASF on 5750 will not run properly on slow core clock */
8777     else if( !(T3_ASIC_IS_575X_PLUS(pDevice->ChipRevId)  && 
8778                 (pDevice->AsfFlags & ASF_ENABLED) ))   
8779     { 
8780         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8781         {
8782             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8783                 T3_PCI_SELECT_ALTERNATE_CLOCK;
8784         }
8785         else if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
8786         {
8787             Value32 = T3_PCI_625_CORE_CLOCK;
8788         }
8789         else
8790         {
8791             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
8792         }
8793         RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8794
8795         MM_Wait(40);
8796
8797         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8798             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8799         {
8800             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8801                 T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
8802         }
8803         else if(T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) )
8804         {
8805             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_625_CORE_CLOCK;
8806         }
8807         else if(!T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
8808         {
8809             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
8810         }
8811
8812         RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8813
8814         if (!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
8815         {
8816             MM_Wait(40);
8817
8818             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8819                 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8820             {
8821                 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
8822                     T3_PCI_44MHZ_CORE_CLOCK;
8823             }
8824             else
8825             {
8826                 Value32 = T3_PCI_44MHZ_CORE_CLOCK;
8827             }
8828
8829             RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
8830         }
8831     }
8832
8833     MM_Wait(40);
8834
8835     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
8836     {
8837         pDevice2 = MM_FindPeerDev(pDevice);
8838     }
8839     if (!(pDevice->Flags & EEPROM_WP_FLAG))
8840     {
8841         LM_SwitchVaux(pDevice, pDevice2);
8842     }
8843
8844     LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
8845
8846     /* Workaround for pll instability */
8847     if((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5750_AX) ||
8848         (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5750_BX)) {
8849
8850         Value32= REG_RD_OFFSET(pDevice, 0x7d00);
8851         REG_WR_OFFSET(pDevice, 0x7d00,Value32 & ~(BIT_16 | BIT_4 | BIT_2 | BIT_1 | BIT_0)); 
8852
8853         if(!(pDevice->AsfFlags & ASF_ENABLED)) 
8854             LM_HaltCpu(pDevice, T3_RX_CPU_ID);
8855         
8856     }
8857
8858     /* Put the the hardware in low power mode. */
8859     if (!(pDevice->Flags & DISABLE_D3HOT_FLAG))
8860     {
8861         MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
8862         MM_Wait(200); /* Wait 200us for state transition */
8863     }
8864
8865     pDevice->PowerLevel = PowerLevel;
8866
8867 #else
8868     LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
8869 #endif /* BCM_WOL */
8870
8871     return LM_STATUS_SUCCESS;
8872 } /* LM_SetPowerState */
8873
8874
8875 LM_VOID
8876 LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2)
8877 {
8878     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
8879         return;
8880
8881     pDevice->GrcLocalCtrl &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8882                                GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8883                                GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
8884                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8885                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8886                                GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8887
8888     /* Switch adapter to auxilliary power if WOL enabled */
8889     if ((pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
8890         (pDevice->AsfFlags & ASF_ENABLED) ||
8891         (pDevice2 && ((pDevice2->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
8892         (pDevice2->AsfFlags & ASF_ENABLED))))
8893     {
8894         if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
8895             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
8896         {
8897             /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
8898             RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8899                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8900                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8901                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 | 
8902                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8903                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8904             MM_Wait(40);
8905         }
8906         else
8907         {
8908             if (pDevice2 && pDevice2->InitDone)
8909             {
8910                 return;
8911             }
8912
8913             /* On NICs GPIOs are used for vaux.
8914                The transition of GPIO0 from 0-1 causes vaux
8915                to power up. Transition of GPIO1 from 1-0 turns vaux off.
8916                GPIO2 transition from 1-0 enables a non-glitch vaux
8917                transition from one state to another. 
8918                On certain designs we should not output GPIO2.
8919             */
8920             if(pDevice->Flags & GPIO2_DONOT_OUTPUT)
8921             {
8922                 /* GPIO0 = 0, GPIO1 = 1. */
8923                 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8924                     GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8925                     GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8926                     GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8927
8928                 MM_Wait(40);
8929
8930                 /* GPIO0 = 1, GPIO1 = 1. */
8931                 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8932                     GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8933                     GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8934                     GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8935                     GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8936
8937                 MM_Wait(40);
8938             }
8939             else
8940             {
8941
8942                 /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
8943                 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8944                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8945                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8946                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 | 
8947                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 | 
8948                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8949
8950                 MM_Wait(40);
8951     
8952                 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
8953                 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8954                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
8955                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8956                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 | 
8957                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8958                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
8959                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
8960                 MM_Wait(40);
8961
8962                 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
8963                 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8964                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 | 
8965                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8966                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 | 
8967                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
8968                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8969                 MM_Wait(40);
8970             } /* GPIO2 OK */
8971         }        /* Not 5700||5701 */
8972     }                /* WOL disabled */
8973     else        
8974     {
8975         if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
8976             (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
8977         {
8978             if (pDevice2 && pDevice2->InitDone)
8979             {
8980                 return;
8981             }
8982
8983             /* GPIO1 = 1 */
8984             RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8985                        GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8986                          GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8987             MM_Wait(40);
8988
8989             /* GPIO1 = 0 */
8990             RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8991                             GRC_MISC_LOCAL_CTRL_GPIO_OE1);
8992             MM_Wait(40);
8993
8994             /* GPIO1 = 1 */
8995             RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
8996                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
8997                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
8998             MM_Wait(40);
8999         }
9000     }
9001 }
9002
9003
9004 /******************************************************************************/
9005 /* Description:                                                               */
9006 /*                                                                            */
9007 /* Return:                                                                    */
9008 /******************************************************************************/
9009 static LM_UINT32
9010 GetPhyAdFlowCntrlSettings(
9011     PLM_DEVICE_BLOCK pDevice)
9012 {
9013     LM_UINT32 Value32;
9014
9015     Value32 = 0;
9016
9017     /* Auto negotiation flow control only when autonegotiation is enabled. */
9018     if(pDevice->DisableAutoNeg == FALSE ||
9019         pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
9020     {
9021         if (T3_ASIC_5714_FAMILY(pDevice->ChipRevId) &&
9022             (pDevice->PhyFlags & PHY_IS_FIBER)) {
9023
9024             /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
9025             if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
9026                 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
9027                 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
9028             {
9029                 Value32 |=PHY_AN_AD_1000XPAUSE; 
9030             }
9031             else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
9032             {
9033                 Value32 |= PHY_AN_AD_1000XPSE_ASYM;
9034             }
9035             else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
9036             {
9037                 Value32 |= (PHY_AN_AD_1000XPSE_ASYM |  PHY_AN_AD_1000XPAUSE);
9038             }
9039
9040         }else{
9041
9042             /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
9043             if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
9044                 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
9045                 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
9046             {
9047                 Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
9048             }
9049             else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
9050             {
9051                 Value32 |= PHY_AN_AD_ASYM_PAUSE;
9052             }
9053             else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
9054             {
9055                 Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
9056             }
9057         }
9058     }
9059
9060     return Value32;
9061 }
9062
9063
9064
9065 /******************************************************************************/
9066 /* Description:                                                               */
9067 /*                                                                            */
9068 /* Return:                                                                    */
9069 /*    LM_STATUS_FAILURE                                                       */
9070 /*    LM_STATUS_SUCCESS                                                       */
9071 /*                                                                            */
9072 /******************************************************************************/
9073 static LM_STATUS
9074 LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice) 
9075 {
9076     LM_LINE_SPEED LineSpeed;
9077     LM_DUPLEX_MODE DuplexMode;
9078     LM_UINT32 NewPhyCtrl;
9079     LM_UINT32 Value32, PhyReg18;
9080     LM_UINT32 Cnt;
9081
9082     /* Get the interface type, line speed, and duplex mode. */
9083     LineSpeed = pDevice->RequestedLineSpeed;
9084     DuplexMode = pDevice->RequestedDuplexMode;
9085
9086     /* Exit ext. loop back, in case it was in ext. loopback mode */
9087     /* Set Extended packet length bit on chips that support jumbo frames */
9088     if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
9089     {
9090         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
9091
9092         LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &Value32);
9093         Value32 |= 1;         /* set tx elastic fifo */
9094         LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, Value32);
9095
9096     }
9097     else
9098     {
9099         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
9100         LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
9101         PhyReg18 &= ~0x8000;       /* clear external loop back */
9102
9103         if (pDevice->Flags & JUMBO_CAPABLE_FLAG)
9104         {
9105             PhyReg18 |= 0x4000;    /* set extended packet length */
9106             LM_ReadPhy(pDevice, BCM540X_EXT_CTRL_REG, &Value32);
9107             Value32 |= 1;         /* set tx elastic fifo */
9108             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, Value32);
9109         }
9110         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
9111     }
9112
9113 #ifdef BCM_WOL
9114     if (pDevice->RestoreOnWakeUp)
9115     {
9116         LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9117         pDevice->advertising1000 = 0;
9118         Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
9119         if (pDevice->WolSpeed == WOL_SPEED_100MB)
9120         {
9121             Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
9122         }
9123         Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9124         Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9125         LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9126         pDevice->advertising = Value32;
9127     }
9128     /* Setup the auto-negotiation advertisement register. */
9129     else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
9130 #else
9131     /* Setup the auto-negotiation advertisement register. */
9132     if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
9133 #endif
9134     {
9135         /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
9136         Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD | PHY_AN_AD_ALL_SPEEDS;
9137         Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9138
9139         LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9140         pDevice->advertising = Value32;
9141
9142         /* Advertise 1000Mbps */
9143         if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
9144         {
9145             Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS;
9146
9147 #ifdef INCLUDE_5701_AX_FIX
9148             /* Bug: workaround for CRC error in gigabit mode when we are in */
9149             /* slave mode.  This will force the PHY to operate in */
9150             /* master mode. */
9151             if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
9152                 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
9153             {
9154                 Value32 |= BCM540X_CONFIG_AS_MASTER |
9155                     BCM540X_ENABLE_CONFIG_AS_MASTER;
9156             }
9157 #endif
9158
9159             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
9160             pDevice->advertising1000 = Value32;
9161         }
9162         else
9163         {
9164             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9165             pDevice->advertising1000 = 0;
9166         }
9167     }
9168     else
9169     {
9170         if ((pDevice->PhyFlags & PHY_NO_GIGABIT) &&
9171             (LineSpeed == LM_LINE_SPEED_1000MBPS))
9172         {
9173             LineSpeed = LM_LINE_SPEED_100MBPS;
9174         }
9175         if(LineSpeed == LM_LINE_SPEED_1000MBPS)
9176         {
9177             Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9178             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9179
9180             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9181             pDevice->advertising = Value32;
9182
9183             if(DuplexMode != LM_DUPLEX_MODE_FULL)
9184             {
9185                 Value32 = BCM540X_AN_AD_1000BASET_HALF;
9186             }
9187             else
9188             {
9189                 Value32 = BCM540X_AN_AD_1000BASET_FULL;
9190             }
9191
9192 #ifdef INCLUDE_5701_AX_FIX
9193             if ((pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE) ||
9194                 (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
9195                 pDevice->ChipRevId == T3_CHIP_ID_5701_B0))
9196 #else
9197             if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
9198 #endif
9199             {
9200                 Value32 |= BCM540X_CONFIG_AS_MASTER |
9201                     BCM540X_ENABLE_CONFIG_AS_MASTER;
9202             }
9203             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
9204             pDevice->advertising1000 = Value32;
9205             if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
9206             {
9207                 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
9208                 {
9209                     LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x8c20);
9210                 }
9211                 else
9212                 {
9213                     LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
9214                     LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
9215                     PhyReg18 |= 0x8000;    /* set loop back */
9216                     LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
9217                 }
9218             }
9219         }
9220         else if(LineSpeed == LM_LINE_SPEED_100MBPS)
9221         {
9222             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9223             pDevice->advertising1000 = 0;
9224
9225             if(DuplexMode != LM_DUPLEX_MODE_FULL)
9226             {
9227                 Value32 = PHY_AN_AD_100BASETX_HALF;
9228             }
9229             else
9230             {
9231                 Value32 = PHY_AN_AD_100BASETX_FULL;
9232             }
9233
9234             Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9235             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9236
9237             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9238             pDevice->advertising = Value32;
9239         }
9240         else if(LineSpeed == LM_LINE_SPEED_10MBPS)
9241         {
9242             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
9243             pDevice->advertising1000 = 0;
9244
9245             if(DuplexMode != LM_DUPLEX_MODE_FULL)
9246             {
9247                 Value32 = PHY_AN_AD_10BASET_HALF;
9248             }
9249             else
9250             {
9251                 Value32 = PHY_AN_AD_10BASET_FULL;
9252             }
9253
9254             Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
9255             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
9256
9257             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
9258             pDevice->advertising = Value32;
9259         }
9260     }
9261
9262     /* Force line speed if auto-negotiation is disabled. */
9263     if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
9264     {
9265         /* This code path is executed only when there is link. */
9266         pDevice->LineSpeed = LineSpeed;
9267         pDevice->DuplexMode = DuplexMode;
9268
9269         /* Force line seepd. */
9270         NewPhyCtrl = 0;
9271         switch(LineSpeed)
9272         {
9273             case LM_LINE_SPEED_10MBPS:
9274                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
9275                 break;
9276             case LM_LINE_SPEED_100MBPS:
9277                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
9278                 break;
9279             case LM_LINE_SPEED_1000MBPS:
9280                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
9281                 break;
9282             default:
9283                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
9284                 break;
9285         }
9286
9287         if(DuplexMode == LM_DUPLEX_MODE_FULL)
9288         {
9289             NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
9290         }
9291
9292         /* Don't do anything if the PHY_CTRL is already what we wanted. */
9293         LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
9294         if(Value32 != NewPhyCtrl)
9295         {
9296             /* Temporary bring the link down before forcing line speed. */
9297             LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
9298             
9299             /* Wait for link to go down. */
9300             for(Cnt = 0; Cnt < 1500; Cnt++)
9301             {
9302                 MM_Wait(10);
9303
9304                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
9305                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
9306
9307                 if(!(Value32 & PHY_STATUS_LINK_PASS))
9308                 {
9309                     MM_Wait(40);
9310                     break;
9311                 }
9312             }
9313
9314             LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
9315             MM_Wait(40);
9316         }
9317     }
9318     else
9319     {
9320         LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
9321             PHY_CTRL_RESTART_AUTO_NEG);
9322     }
9323
9324     return LM_STATUS_SUCCESS;
9325 } /* LM_ForceAutoNegBcm540xPhy */
9326
9327 /******************************************************************************/
9328 /* Description:                                                               */
9329 /*                                                                            */
9330 /* Return:                                                                    */
9331 /******************************************************************************/
9332 LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
9333                           PT3_FWIMG_INFO pFwImg,
9334                           LM_UINT32 LoadCpu,
9335                           LM_UINT32 StartCpu)
9336 {
9337     LM_UINT32 i;
9338     LM_UINT32 address;
9339     LM_VOID (*Wr_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32);
9340     LM_UINT32 (*Rd_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register);
9341     LM_UINT32 len;
9342     LM_UINT32 base_addr;
9343
9344 #ifdef INCLUDE_TCP_SEG_SUPPORT
9345     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
9346       {
9347         Wr_fn = LM_MemWrInd;
9348         Rd_fn = LM_MemRdInd;
9349         len = LM_GetStkOffLdFirmwareSize(pDevice);
9350         base_addr = T3_NIC_BCM5705_MBUF_POOL_ADDR;
9351       }
9352     else
9353 #endif
9354       {
9355         Wr_fn = LM_RegWrInd;
9356         Rd_fn = LM_RegRdInd;
9357         len = T3_RX_CPU_SPAD_SIZE;
9358         base_addr = T3_RX_CPU_SPAD_ADDR;
9359       }
9360
9361     if (LoadCpu & T3_RX_CPU_ID)
9362     {
9363         if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
9364         {
9365             return LM_STATUS_FAILURE;
9366         }
9367
9368         /* First of all clear scrach pad memory */
9369         for (i = 0; i < len; i+=4)
9370         { 
9371             Wr_fn(pDevice,base_addr+i,0);
9372         }
9373
9374         /* Copy code first */
9375         address = base_addr + (pFwImg->Text.Offset & 0xffff);
9376         for (i = 0; i <= pFwImg->Text.Length; i+=4)
9377         {
9378             Wr_fn(pDevice,address+i,
9379                         ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
9380         }
9381
9382         address = base_addr + (pFwImg->ROnlyData.Offset & 0xffff);
9383         for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
9384         {
9385             Wr_fn(pDevice,address+i,
9386                         ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
9387         }
9388
9389         address = base_addr + (pFwImg->Data.Offset & 0xffff);
9390         for (i= 0; i <= pFwImg->Data.Length; i+=4)
9391         {
9392             Wr_fn(pDevice,address+i,
9393                         ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
9394         }
9395     }
9396
9397     if ((LoadCpu & T3_TX_CPU_ID) &&
9398         (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
9399     {
9400         if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
9401         {
9402             return LM_STATUS_FAILURE;
9403         }
9404
9405         /* First of all clear scrach pad memory */
9406         for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
9407         { 
9408             Wr_fn(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
9409         }
9410
9411         /* Copy code first */
9412         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
9413         for (i= 0; i <= pFwImg->Text.Length; i+=4)
9414         {
9415             Wr_fn(pDevice,address+i,
9416                         ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
9417         }
9418
9419         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
9420         for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
9421         {
9422             Wr_fn(pDevice,address+i,
9423                         ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
9424         }
9425
9426         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
9427         for (i= 0; i <= pFwImg->Data.Length; i+=4)
9428         {
9429             Wr_fn(pDevice,address+i,
9430                         ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
9431         }
9432     }
9433
9434     if (StartCpu & T3_RX_CPU_ID)
9435     {
9436         /* Start Rx CPU */
9437         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9438         REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
9439         for (i = 0 ; i < 5; i++)
9440         {
9441           if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
9442              break;
9443
9444           REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9445           REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9446           REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
9447           REG_RD_BACK(pDevice,rxCpu.reg.PC);
9448           MM_Wait(1000);
9449         }
9450
9451         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9452         REG_WR(pDevice,rxCpu.reg.mode, 0);
9453     }
9454
9455     if ((StartCpu & T3_TX_CPU_ID) &&
9456         (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
9457     {
9458         /* Start Tx CPU */
9459         REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9460         REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
9461         for (i = 0 ; i < 5; i++)
9462         {
9463           if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
9464              break;
9465
9466           REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9467           REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
9468           REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
9469           REG_RD_BACK(pDevice,txCpu.reg.PC);
9470           MM_Wait(1000);
9471         }
9472         
9473         REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9474         REG_WR(pDevice,txCpu.reg.mode, 0);
9475     }
9476     
9477     return LM_STATUS_SUCCESS;
9478 }
9479
9480 LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
9481 {
9482     LM_UINT32 i;
9483     LM_STATUS status;
9484
9485     status = LM_STATUS_SUCCESS;
9486
9487     if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId) &&
9488         !(cpu_number & T3_RX_CPU_ID))
9489     {
9490         return status;
9491     }
9492
9493     if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
9494         (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
9495     {
9496         status = LM_NVRAM_AcquireLock(pDevice);
9497     }
9498
9499     if (cpu_number & T3_RX_CPU_ID)
9500     {
9501         for (i = 0 ; i < 10000; i++)
9502         {
9503             REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9504             REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9505
9506             if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
9507               break;
9508         }
9509
9510         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
9511         REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
9512         REG_RD_BACK(pDevice,rxCpu.reg.mode);
9513         MM_Wait(10);
9514
9515         if (i == 10000)
9516             status = LM_STATUS_FAILURE;
9517     }
9518
9519     if ((pDevice->Flags & T3_HAS_TWO_CPUS) &&
9520         (cpu_number & T3_TX_CPU_ID))
9521     {
9522         for (i = 0 ; i < 10000; i++)
9523         {
9524             REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
9525             REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
9526
9527             if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
9528                break;
9529         }
9530
9531         if (i == 10000)
9532             status = LM_STATUS_FAILURE;
9533     }
9534
9535     if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
9536         (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
9537     {
9538         if (status != LM_STATUS_SUCCESS)
9539         {
9540             /*
9541              * Some part of this operation failed.
9542              * Just undo our own actions.
9543              */
9544             LM_NVRAM_ReleaseLock(pDevice);
9545         }
9546         else if (!(pDevice->Flags & T3_HAS_TWO_CPUS) ||
9547                  cpu_number == (T3_TX_CPU_ID | T3_RX_CPU_ID))
9548         {
9549             /*
9550              * Release our NVRAM arbitration grant along
9551              * with the firmware's arbitration request bit.
9552              */
9553             REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1 | SW_ARB_REQ_CLR0);
9554             REG_RD_BACK(pDevice, Nvram.SwArb);
9555         }
9556         else
9557         {
9558             LM_NVRAM_ReleaseLock(pDevice);
9559
9560             if (LM_NVRAM_AcquireLock(pDevice) == LM_STATUS_SUCCESS)
9561             {
9562                 /* All is well. Release the arbitration and continue. */
9563                 LM_NVRAM_ReleaseLock(pDevice);
9564             }
9565             else
9566             {
9567                 /*
9568                  * We've timed out while attempting to get the
9569                  * NVRAM arbitration.  Assume the cause is that
9570                  * the NVRAM has requested arbitration after we
9571                  * acquired arbitration the first time, but before
9572                  * the CPU was actually halted.
9573                  */
9574
9575                 /*
9576                  * Release our NVRAM arbitration grant along
9577                  * with the firmware's arbitration request bit.
9578                  */
9579                 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1 | SW_ARB_REQ_CLR0);
9580                 REG_RD_BACK(pDevice, Nvram.SwArb);
9581             }
9582         }
9583     }
9584
9585     return status;
9586 }
9587
9588
9589 LM_STATUS
9590 LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
9591 {
9592         int j;
9593         int ret = LM_STATUS_SUCCESS;
9594
9595         if(BlinkDurationSec == 0)
9596         {
9597                 BlinkDurationSec = 1;
9598         }
9599         if(BlinkDurationSec > 120)
9600         {
9601                 BlinkDurationSec = 120;
9602         }
9603
9604         for(j = 0; j < BlinkDurationSec * 2; j++)
9605         {
9606                 if(j % 2)
9607                 {
9608                         // Turn on the LEDs.
9609                         REG_WR(pDevice, MacCtrl.LedCtrl,
9610                                 LED_CTRL_OVERRIDE_LINK_LED |
9611                                 LED_CTRL_1000MBPS_LED_ON |
9612                                 LED_CTRL_100MBPS_LED_ON |
9613                                 LED_CTRL_10MBPS_LED_ON |
9614                                 LED_CTRL_OVERRIDE_TRAFFIC_LED |
9615                                 LED_CTRL_BLINK_TRAFFIC_LED |
9616                                 LED_CTRL_TRAFFIC_LED);
9617                 }
9618                 else
9619                 {
9620                         // Turn off the LEDs.
9621                         REG_WR(pDevice, MacCtrl.LedCtrl,
9622                                 LED_CTRL_OVERRIDE_LINK_LED |
9623                                 LED_CTRL_OVERRIDE_TRAFFIC_LED);
9624                 }
9625                 if (MM_Sleep(pDevice, 500) != LM_STATUS_SUCCESS)/* 0.5 second */
9626                 {
9627                     ret = LM_STATUS_FAILURE;
9628                     break;
9629                 }
9630         }
9631         REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
9632         return ret;
9633 }
9634
9635 LM_STATUS
9636 LM_SwitchClocks(PLM_DEVICE_BLOCK pDevice)
9637 {
9638     LM_UINT32 ClockCtrl;
9639
9640     if(T3_ASIC_5714_FAMILY(pDevice->ChipRevId))
9641         return LM_STATUS_SUCCESS;
9642
9643     ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl);
9644     pDevice->ClockCtrl = ClockCtrl & (T3_PCI_FORCE_CLKRUN |
9645         T3_PCI_CLKRUN_OUTPUT_EN | 0x1f);
9646     if (T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
9647     {
9648         if (ClockCtrl & T3_PCI_625_CORE_CLOCK)
9649         {
9650             /* clear ALT clock first */
9651             RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9652                 T3_PCI_625_CORE_CLOCK);
9653             MM_Wait(40);  /* required delay is 27usec */
9654         }
9655     }
9656     else
9657     {
9658         if (ClockCtrl & T3_PCI_44MHZ_CORE_CLOCK)
9659         {
9660             RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9661                 T3_PCI_44MHZ_CORE_CLOCK | T3_PCI_SELECT_ALTERNATE_CLOCK);
9662             MM_Wait(40);  /* required delay is 27usec */
9663             RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
9664                 T3_PCI_SELECT_ALTERNATE_CLOCK);
9665             MM_Wait(40);  /* required delay is 27usec */
9666         }
9667     }
9668
9669     RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
9670     MM_Wait(40);  /* required delay is 27usec */
9671     return LM_STATUS_SUCCESS;
9672 }
9673
9674 int t3_do_dma(PLM_DEVICE_BLOCK pDevice, 
9675                    LM_PHYSICAL_ADDRESS host_addr_phy, int length,
9676                    int dma_read)
9677 {
9678     T3_DMA_DESC dma_desc;
9679     int i;
9680     LM_UINT32 dma_desc_addr;
9681     LM_UINT32 value32;
9682
9683     REG_WR(pDevice, BufMgr.Mode, 0);
9684     REG_WR(pDevice, Ftq.Reset, 0);
9685
9686     dma_desc.host_addr.High = host_addr_phy.High;
9687     dma_desc.host_addr.Low = host_addr_phy.Low;
9688     dma_desc.nic_mbuf = 0x2100;
9689     dma_desc.len = length;
9690     dma_desc.flags = 0x00000005; /* Generate Rx-CPU event */
9691
9692     if (dma_read)
9693     {
9694         dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
9695             T3_QID_DMA_HIGH_PRI_READ;
9696         REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
9697     }
9698     else
9699     {
9700         dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
9701             T3_QID_DMA_HIGH_PRI_WRITE;
9702         REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
9703     }
9704
9705     dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
9706
9707     /* Writing this DMA descriptor to DMA memory */
9708     for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
9709     {
9710         value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
9711         MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
9712         MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG,
9713             MM_SWAP_LE32(value32));
9714     }
9715     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
9716
9717     if (dma_read)
9718         REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
9719     else
9720         REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
9721
9722     for (i = 0; i < 40; i++)
9723     {
9724         if (dma_read)
9725             value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
9726         else
9727             value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
9728
9729         if ((value32 & 0xffff) == dma_desc_addr)
9730             break;
9731
9732         MM_Wait(10);
9733     }
9734
9735     return LM_STATUS_SUCCESS;
9736 }
9737
9738 STATIC LM_STATUS
9739 LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
9740            LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
9741 {
9742     int j;
9743     LM_UINT32 *ptr;
9744     int dma_success = 0;
9745     LM_STATUS ret = LM_STATUS_FAILURE;
9746
9747     if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
9748         T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
9749     {
9750         return LM_STATUS_SUCCESS;
9751     }
9752     while (!dma_success)
9753     {
9754         /* Fill data with incremental patterns */
9755         ptr = (LM_UINT32 *)pBufferVirt;
9756         for (j = 0; j < BufferSize/4; j++)
9757             *ptr++ = j;
9758
9759         if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
9760         {
9761             goto LM_DmaTestDone;
9762         }
9763
9764         MM_Wait(40);
9765         ptr = (LM_UINT32 *)pBufferVirt;
9766         /* Fill data with zero */
9767         for (j = 0; j < BufferSize/4; j++)
9768             *ptr++ = 0;
9769
9770         if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
9771         {
9772             goto LM_DmaTestDone;
9773         }
9774
9775         MM_Wait(40);
9776         /* Check for data */
9777         ptr = (LM_UINT32 *)pBufferVirt;
9778         for (j = 0; j < BufferSize/4; j++)
9779         {
9780             if (*ptr++ != j)
9781             {
9782                 if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
9783                     != DMA_CTRL_WRITE_BOUNDARY_16)
9784                 {
9785                     pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
9786                          ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
9787                           DMA_CTRL_WRITE_BOUNDARY_16;
9788                     REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
9789                            pDevice->DmaReadWriteCtrl);
9790                     break;
9791                  }
9792                  else
9793                  {
9794                      goto LM_DmaTestDone;
9795                  }
9796             }
9797         }
9798         if (j == (BufferSize/4))
9799             dma_success = 1;
9800     }
9801     ret = LM_STATUS_SUCCESS;
9802 LM_DmaTestDone:
9803     memset(pBufferVirt, 0, BufferSize);
9804     return ret;
9805 }
9806
9807 void
9808 LM_Add32To64Counter(LM_UINT32 Counter32, T3_64BIT_REGISTER *Counter64)
9809 {
9810     Counter64->Low += Counter32;
9811     if (Counter64->Low < Counter32)
9812     {
9813         Counter64->High++;
9814     }
9815 }
9816
9817 LM_STATUS
9818 LM_GetStats(PLM_DEVICE_BLOCK pDevice)
9819 {
9820     PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
9821
9822     if(!T3_ASIC_IS_5705_BEYOND(pDevice->ChipRevId))
9823     {
9824         return LM_STATUS_FAILURE;
9825     }
9826
9827     if (pStats == 0)
9828     {
9829         return LM_STATUS_FAILURE;
9830     }
9831     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutOctets),
9832         &pStats->ifHCOutOctets);
9833     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsCollisions),
9834         &pStats->etherStatsCollisions);
9835     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXonSent),
9836         &pStats->outXonSent);
9837     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXoffSent),
9838         &pStats->outXoffSent);
9839     LM_Add32To64Counter(REG_RD(pDevice,
9840         MacCtrl.dot3StatsInternalMacTransmitErrors),
9841         &pStats->dot3StatsInternalMacTransmitErrors);
9842     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsSingleCollisionFrames),
9843         &pStats->dot3StatsSingleCollisionFrames);
9844     LM_Add32To64Counter(REG_RD(pDevice,
9845         MacCtrl.dot3StatsMultipleCollisionFrames),
9846         &pStats->dot3StatsMultipleCollisionFrames);
9847     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsDeferredTransmissions),
9848         &pStats->dot3StatsDeferredTransmissions);
9849     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsExcessiveCollisions),
9850         &pStats->dot3StatsExcessiveCollisions);
9851     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsLateCollisions),
9852         &pStats->dot3StatsLateCollisions);
9853     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutUcastPkts),
9854         &pStats->ifHCOutUcastPkts);
9855     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutMulticastPkts),
9856         &pStats->ifHCOutMulticastPkts);
9857     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutBroadcastPkts),
9858         &pStats->ifHCOutBroadcastPkts);
9859     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInOctets),
9860         &pStats->ifHCInOctets);
9861     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsFragments),
9862         &pStats->etherStatsFragments);
9863     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInUcastPkts),
9864         &pStats->ifHCInUcastPkts);
9865     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInMulticastPkts),
9866         &pStats->ifHCInMulticastPkts);
9867     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInBroadcastPkts),
9868         &pStats->ifHCInBroadcastPkts);
9869     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFCSErrors),
9870         &pStats->dot3StatsFCSErrors);
9871     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsAlignmentErrors),
9872         &pStats->dot3StatsAlignmentErrors);
9873     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xonPauseFramesReceived),
9874         &pStats->xonPauseFramesReceived);
9875     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffPauseFramesReceived),
9876         &pStats->xoffPauseFramesReceived);
9877     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.macControlFramesReceived),
9878         &pStats->macControlFramesReceived);
9879     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffStateEntered),
9880         &pStats->xoffStateEntered);
9881     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFramesTooLong),
9882         &pStats->dot3StatsFramesTooLong);
9883     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsJabbers),
9884         &pStats->etherStatsJabbers);
9885     LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsUndersizePkts),
9886         &pStats->etherStatsUndersizePkts);
9887
9888     return LM_STATUS_SUCCESS;
9889 }