]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/tigon3.c
ec2cd2ac36ff29b7ef3e5ab628a8b28ea8765b86
[karo-tx-uboot.git] / drivers / tigon3.c
1 /******************************************************************************/
2 /*                                                                            */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 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 #include <common.h>
14 #include <asm/types.h>
15 #if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
16         defined(CONFIG_TIGON3)
17 #ifdef CONFIG_BMW
18 #include <mpc824x.h>
19 #endif
20 #include <malloc.h>
21 #include <linux/byteorder/big_endian.h>
22 #include "bcm570x_mm.h"
23
24 #define EMBEDDED 1
25 /******************************************************************************/
26 /* Local functions. */
27 /******************************************************************************/
28
29 LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
30 LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
31
32 static LM_STATUS LM_TranslateRequestedMediaType(
33     LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
34     PLM_MEDIA_TYPE pMediaType, PLM_LINE_SPEED pLineSpeed,
35     PLM_DUPLEX_MODE pDuplexMode);
36
37 static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
38
39 __inline static LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
40 __inline static LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
41
42 static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,
43     LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
44 static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,
45     LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
46 static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
47 STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
48     LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
49 #if INCLUDE_TBI_SUPPORT
50 STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
51 STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
52 #endif
53 STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
54 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
55 STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
56            LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
57 STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
58 STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
59 STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
60     PT3_SND_BD pSendBd);
61
62 /******************************************************************************/
63 /* External functions. */
64 /******************************************************************************/
65
66 LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
67
68
69 /******************************************************************************/
70 /* Description:                                                               */
71 /*                                                                            */
72 /* Return:                                                                    */
73 /******************************************************************************/
74 LM_UINT32
75 LM_RegRdInd(
76 PLM_DEVICE_BLOCK pDevice,
77 LM_UINT32 Register) {
78     LM_UINT32 Value32;
79
80 #if PCIX_TARGET_WORKAROUND
81     MM_ACQUIRE_UNDI_LOCK(pDevice);
82 #endif
83     MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
84     MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
85 #if PCIX_TARGET_WORKAROUND
86     MM_RELEASE_UNDI_LOCK(pDevice);
87 #endif
88
89     return Value32;
90 } /* LM_RegRdInd */
91
92
93 /******************************************************************************/
94 /* Description:                                                               */
95 /*                                                                            */
96 /* Return:                                                                    */
97 /******************************************************************************/
98 LM_VOID
99 LM_RegWrInd(
100 PLM_DEVICE_BLOCK pDevice,
101 LM_UINT32 Register,
102 LM_UINT32 Value32) {
103
104 #if PCIX_TARGET_WORKAROUND
105     MM_ACQUIRE_UNDI_LOCK(pDevice);
106 #endif
107     MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
108     MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, Value32);
109 #if PCIX_TARGET_WORKAROUND
110     MM_RELEASE_UNDI_LOCK(pDevice);
111 #endif
112 } /* LM_RegWrInd */
113
114
115 /******************************************************************************/
116 /* Description:                                                               */
117 /*                                                                            */
118 /* Return:                                                                    */
119 /******************************************************************************/
120 LM_UINT32
121 LM_MemRdInd(
122 PLM_DEVICE_BLOCK pDevice,
123 LM_UINT32 MemAddr) {
124     LM_UINT32 Value32;
125
126     MM_ACQUIRE_UNDI_LOCK(pDevice);
127 #ifdef BIG_ENDIAN_HOST
128     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
129     Value32 = REG_RD(pDevice, PciCfg.MemWindowData);
130     /*    Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
131 #else
132     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
133     MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
134 #endif
135     MM_RELEASE_UNDI_LOCK(pDevice);
136
137     return Value32;
138 } /* LM_MemRdInd */
139
140
141 /******************************************************************************/
142 /* Description:                                                               */
143 /*                                                                            */
144 /* Return:                                                                    */
145 /******************************************************************************/
146 LM_VOID
147 LM_MemWrInd(
148 PLM_DEVICE_BLOCK pDevice,
149 LM_UINT32 MemAddr,
150 LM_UINT32 Value32) {
151     MM_ACQUIRE_UNDI_LOCK(pDevice);
152 #ifdef BIG_ENDIAN_HOST
153     REG_WR(pDevice,PciCfg.MemWindowBaseAddr,MemAddr);
154     REG_WR(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4],Value32);
155 #else
156     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
157     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
158 #endif
159     MM_RELEASE_UNDI_LOCK(pDevice);
160 } /* LM_MemWrInd */
161
162
163 /******************************************************************************/
164 /* Description:                                                               */
165 /*                                                                            */
166 /* Return:                                                                    */
167 /******************************************************************************/
168 LM_STATUS
169 LM_QueueRxPackets(
170 PLM_DEVICE_BLOCK pDevice) {
171     LM_STATUS Lmstatus;
172     PLM_PACKET pPacket;
173     PT3_RCV_BD pRcvBd;
174     LM_UINT32 StdBdAdded = 0;
175 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
176     LM_UINT32 JumboBdAdded = 0;
177 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
178
179     Lmstatus = LM_STATUS_SUCCESS;
180
181     pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
182     while(pPacket) {
183         switch(pPacket->u.Rx.RcvProdRing) {
184 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
185             case T3_JUMBO_RCV_PROD_RING:        /* Jumbo Receive Ring. */
186                 /* Initialize the buffer descriptor. */
187                 pRcvBd =
188                     &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
189                 pRcvBd->Flags = RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
190                 pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
191
192                 /* Initialize the receive buffer pointer */
193 #if 0 /* Jimmy, deleted in new */
194                 pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
195                 pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
196 #endif
197                 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
198
199                 /* The opaque field may point to an offset from a fix addr. */
200                 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
201                     MM_UINT_PTR(pDevice->pPacketDescBase));
202
203                 /* Update the producer index. */
204                 pDevice->RxJumboProdIdx = (pDevice->RxJumboProdIdx + 1) &
205                     T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
206
207                 JumboBdAdded++;
208                 break;
209 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
210
211             case T3_STD_RCV_PROD_RING:      /* Standard Receive Ring. */
212                 /* Initialize the buffer descriptor. */
213                 pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
214                 pRcvBd->Flags = RCV_BD_FLAG_END;
215                 pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
216
217                 /* Initialize the receive buffer pointer */
218 #if 0  /* Jimmy, deleted in new replaced with MM_MapRxDma */
219                 pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
220                 pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
221 #endif
222                 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
223
224                 /* The opaque field may point to an offset from a fix addr. */
225                 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
226                     MM_UINT_PTR(pDevice->pPacketDescBase));
227
228                 /* Update the producer index. */
229                 pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
230                     T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
231
232                 StdBdAdded++;
233                 break;
234
235             case T3_UNKNOWN_RCV_PROD_RING:
236             default:
237                 Lmstatus = LM_STATUS_FAILURE;
238                 break;
239         } /* switch */
240
241         /* Bail out if there is any error. */
242         if(Lmstatus != LM_STATUS_SUCCESS)
243         {
244             break;
245         }
246
247         pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
248     } /* while */
249
250     wmb();
251     /* Update the procedure index. */
252     if(StdBdAdded)
253     {
254         MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, pDevice->RxStdProdIdx);
255     }
256 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
257     if(JumboBdAdded)
258     {
259         MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
260             pDevice->RxJumboProdIdx);
261     }
262 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
263
264     return Lmstatus;
265 } /* LM_QueueRxPackets */
266
267
268 /******************************************************************************/
269 /* Description:                                                               */
270 /*                                                                            */
271 /* Return:                                                                    */
272 /******************************************************************************/
273 STATIC LM_VOID
274 LM_NvramInit(
275     PLM_DEVICE_BLOCK pDevice)
276 {
277     LM_UINT32 Value32;
278     LM_UINT32 j;
279
280     /* Intialize clock period and state machine. */
281     Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
282         SEEPROM_ADDR_FSM_RESET;
283     REG_WR(pDevice, Grc.EepromAddr, Value32);
284
285     for(j = 0; j < 100; j++)
286     {
287         MM_Wait(10);
288     }
289
290     /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
291     Value32 = REG_RD(pDevice, Grc.LocalCtrl);
292     REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
293
294     /* Set the 5701 compatibility mode if we are using EEPROM. */
295     if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
296         T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
297     {
298         Value32 = REG_RD(pDevice, Nvram.Config1);
299         if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
300         {
301             /* Use the new interface to read EEPROM. */
302             Value32 &= ~FLASH_COMPAT_BYPASS;
303
304             REG_WR(pDevice, Nvram.Config1, Value32);
305         }
306     }
307 } /* LM_NvRamInit */
308
309
310 /******************************************************************************/
311 /* Description:                                                               */
312 /*                                                                            */
313 /* Return:                                                                    */
314 /******************************************************************************/
315 STATIC LM_STATUS
316 LM_EepromRead(
317     PLM_DEVICE_BLOCK pDevice,
318     LM_UINT32 Offset,
319     LM_UINT32 *pData)
320 {
321     LM_UINT32 Value32;
322     LM_UINT32 Addr;
323     LM_UINT32 Dev;
324     LM_UINT32 j;
325
326     if(Offset > SEEPROM_CHIP_SIZE)
327     {
328         return LM_STATUS_FAILURE;
329     }
330
331     Dev = Offset / SEEPROM_CHIP_SIZE;
332     Addr = Offset % SEEPROM_CHIP_SIZE;
333
334     Value32 = REG_RD(pDevice, Grc.EepromAddr);
335     Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
336         SEEPROM_ADDR_RW_MASK);
337     REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
338         SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
339
340     for(j = 0; j < 1000; j++)
341     {
342         Value32 = REG_RD(pDevice, Grc.EepromAddr);
343         if(Value32 & SEEPROM_ADDR_COMPLETE)
344         {
345             break;
346         }
347         MM_Wait(10);
348     }
349
350     if(Value32 & SEEPROM_ADDR_COMPLETE)
351     {
352         Value32 = REG_RD(pDevice, Grc.EepromData);
353         *pData = Value32;
354
355         return LM_STATUS_SUCCESS;
356     }
357
358     return LM_STATUS_FAILURE;
359 } /* LM_EepromRead */
360
361
362 /******************************************************************************/
363 /* Description:                                                               */
364 /*                                                                            */
365 /* Return:                                                                    */
366 /******************************************************************************/
367 STATIC LM_STATUS
368 LM_NvramRead(
369     PLM_DEVICE_BLOCK pDevice,
370     LM_UINT32 Offset,
371     LM_UINT32 *pData)
372 {
373     LM_UINT32 Value32;
374     LM_STATUS Status;
375     LM_UINT32 j;
376
377     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
378         T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
379     {
380         Status = LM_EepromRead(pDevice, Offset, pData);
381     }
382     else
383     {
384         /* Determine if we have flash or EEPROM. */
385         Value32 = REG_RD(pDevice, Nvram.Config1);
386         if(Value32 & FLASH_INTERFACE_ENABLE)
387         {
388             if(Value32 & FLASH_SSRAM_BUFFERRED_MODE)
389             {
390                 Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
391                     BUFFERED_FLASH_PAGE_POS) +
392                     (Offset % BUFFERED_FLASH_PAGE_SIZE);
393             }
394         }
395
396         REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
397         for (j = 0; j < 1000; j++)
398         {
399             if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
400             {
401                 break;
402             }
403             MM_Wait(20);
404         }
405         if (j == 1000)
406         {
407             return LM_STATUS_FAILURE;
408         }
409
410         /* Read from flash or EEPROM with the new 5703/02 interface. */
411         REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
412
413         REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
414             NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
415
416         /* Wait for the done bit to clear. */
417         for(j = 0; j < 500; j++)
418         {
419             MM_Wait(10);
420
421             Value32 = REG_RD(pDevice, Nvram.Cmd);
422             if(!(Value32 & NVRAM_CMD_DONE))
423             {
424                 break;
425             }
426         }
427
428         /* Wait for the done bit. */
429         if(!(Value32 & NVRAM_CMD_DONE))
430         {
431             for(j = 0; j < 500; j++)
432             {
433                 MM_Wait(10);
434
435                 Value32 = REG_RD(pDevice, Nvram.Cmd);
436                 if(Value32 & NVRAM_CMD_DONE)
437                 {
438                     MM_Wait(10);
439
440                     *pData = REG_RD(pDevice, Nvram.ReadData);
441
442                     /* Change the endianess. */
443                     *pData = ((*pData & 0xff) << 24)| ((*pData & 0xff00) << 8)|
444                         ((*pData & 0xff0000) >> 8) | ((*pData >> 24) & 0xff);
445
446                     break;
447                 }
448             }
449         }
450
451         REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
452         if(Value32 & NVRAM_CMD_DONE)
453         {
454             Status = LM_STATUS_SUCCESS;
455         }
456         else
457         {
458             Status = LM_STATUS_FAILURE;
459         }
460     }
461
462     return Status;
463 } /* LM_NvramRead */
464
465
466 STATIC void
467 LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
468 {
469     LM_UINT32 Vpd_arr[256/4];
470     LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
471     LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
472     LM_UINT32 Value32;
473     unsigned int j;
474
475     /* Read PN from VPD */
476     for (j = 0; j < 256; j += 4, Vpd_dptr++ )
477     {
478         if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
479             printf("BCM570x: LM_ReadVPD: VPD read failed"
480                    " (no EEPROM onboard)\n");
481             return;
482         }
483         *Vpd_dptr = cpu_to_le32(Value32);
484     }
485     for (j = 0; j < 256; )
486     {
487         unsigned int Vpd_r_len;
488         unsigned int Vpd_r_end;
489
490         if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
491         {
492             j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
493         }
494         else if (Vpd[j] == 0x90)
495         {
496             Vpd_r_len =  Vpd[j + 1] + (Vpd[j + 2] << 8);
497             j += 3;
498             Vpd_r_end = Vpd_r_len + j;
499             while (j < Vpd_r_end)
500             {
501                 if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
502                 {
503                     unsigned int len = Vpd[j + 2];
504
505                     if (len <= 24)
506                     {
507                         memcpy(pDevice->PartNo, &Vpd[j + 3], len);
508                     }
509                     break;
510                 }
511                 else
512                 {
513                     if (Vpd[j + 2] == 0)
514                     {
515                         break;
516                     }
517                     j = j + Vpd[j + 2];
518                 }
519             }
520             break;
521         }
522         else {
523             break;
524         }
525     }
526 }
527
528 STATIC void
529 LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
530 {
531     LM_UINT32 Value32, offset, ver_offset;
532     int i;
533
534     if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
535         return;
536     if (Value32 != 0xaa559966)
537         return;
538     if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
539         return;
540
541     offset = ((offset & 0xff) << 24)| ((offset & 0xff00) << 8)|
542         ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
543     if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
544         return;
545     if ((Value32 == 0x0300000e) &&
546         (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
547         (Value32 == 0)) {
548
549         if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
550             return;
551         ver_offset = ((ver_offset & 0xff0000) >> 8) |
552             ((ver_offset >> 24) & 0xff);
553         for (i = 0; i < 16; i += 4) {
554             if (LM_NvramRead(pDevice, offset + ver_offset + i, &Value32) !=
555                 LM_STATUS_SUCCESS)
556             {
557                 return;
558             }
559             *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = cpu_to_le32(Value32);
560         }
561     }
562     else {
563         char c;
564
565         if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
566             return;
567
568         i = 0;
569         c = ((Value32 & 0xff0000) >> 16);
570
571         if (c < 10) {
572             pDevice->BootCodeVer[i++] = c + '0';
573         }
574         else {
575             pDevice->BootCodeVer[i++] = (c / 10) + '0';
576             pDevice->BootCodeVer[i++] = (c % 10) + '0';
577         }
578         pDevice->BootCodeVer[i++] = '.';
579         c = (Value32 & 0xff000000) >> 24;
580         if (c < 10) {
581             pDevice->BootCodeVer[i++] = c + '0';
582         }
583         else {
584             pDevice->BootCodeVer[i++] = (c / 10) + '0';
585             pDevice->BootCodeVer[i++] = (c % 10) + '0';
586         }
587         pDevice->BootCodeVer[i] = 0;
588     }
589 }
590
591 STATIC void
592 LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
593 {
594     LM_UINT32 PciState = pDevice->PciState;
595     LM_UINT32 ClockCtrl;
596     char *SpeedStr = "";
597
598     if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
599     {
600         strcpy(pDevice->BusSpeedStr, "32-bit ");
601     }
602     else
603     {
604         strcpy(pDevice->BusSpeedStr, "64-bit ");
605     }
606     if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
607     {
608         strcat(pDevice->BusSpeedStr, "PCI ");
609         if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
610         {
611             SpeedStr = "66MHz";
612         }
613         else
614         {
615             SpeedStr = "33MHz";
616         }
617     }
618     else
619     {
620         strcat(pDevice->BusSpeedStr, "PCIX ");
621         if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
622         {
623             SpeedStr = "133MHz";
624         }
625         else
626         {
627             ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
628             switch (ClockCtrl)
629             {
630             case 0:
631                 SpeedStr = "33MHz";
632                 break;
633
634             case 2:
635                 SpeedStr = "50MHz";
636                 break;
637
638             case 4:
639                 SpeedStr = "66MHz";
640                 break;
641
642             case 6:
643                 SpeedStr = "100MHz";
644                 break;
645
646             case 7:
647                 SpeedStr = "133MHz";
648                 break;
649             }
650         }
651     }
652     strcat(pDevice->BusSpeedStr, SpeedStr);
653 }
654
655 /******************************************************************************/
656 /* Description:                                                               */
657 /*    This routine initializes default parameters and reads the PCI           */
658 /*    configurations.                                                         */
659 /*                                                                            */
660 /* Return:                                                                    */
661 /*    LM_STATUS_SUCCESS                                                       */
662 /******************************************************************************/
663 LM_STATUS
664 LM_GetAdapterInfo(
665 PLM_DEVICE_BLOCK pDevice)
666 {
667     PLM_ADAPTER_INFO pAdapterInfo;
668     LM_UINT32 Value32;
669     LM_STATUS Status;
670     LM_UINT32 j;
671     LM_UINT32 EeSigFound;
672     LM_UINT32 EePhyTypeSerdes = 0;
673     LM_UINT32 EePhyLedMode = 0;
674     LM_UINT32 EePhyId = 0;
675
676     /* Get Device Id and Vendor Id */
677     Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
678     if(Status != LM_STATUS_SUCCESS)
679     {
680         return Status;
681     }
682     pDevice->PciVendorId = (LM_UINT16) Value32;
683     pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
684
685     /* If we are not getting the write adapter, exit. */
686     if((Value32 != T3_PCI_ID_BCM5700) &&
687        (Value32 != T3_PCI_ID_BCM5701) &&
688        (Value32 != T3_PCI_ID_BCM5702) &&
689        (Value32 != T3_PCI_ID_BCM5702x) &&
690        (Value32 != T3_PCI_ID_BCM5702FE) &&
691        (Value32 != T3_PCI_ID_BCM5703) &&
692        (Value32 != T3_PCI_ID_BCM5703x) &&
693        (Value32 != T3_PCI_ID_BCM5704))
694     {
695         return LM_STATUS_FAILURE;
696     }
697
698     Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
699     if(Status != LM_STATUS_SUCCESS)
700     {
701         return Status;
702     }
703     pDevice->PciRevId = (LM_UINT8) Value32;
704
705     /* Get IRQ. */
706     Status = MM_ReadConfig32(pDevice, PCI_INT_LINE_REG, &Value32);
707     if(Status != LM_STATUS_SUCCESS)
708     {
709         return Status;
710     }
711     pDevice->Irq = (LM_UINT8) Value32;
712
713     /* Get interrupt pin. */
714     pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
715
716     /* Get chip revision id. */
717     Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
718     pDevice->ChipRevId = Value32 >> 16;
719
720     /* Get subsystem vendor. */
721     Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
722     if(Status != LM_STATUS_SUCCESS)
723     {
724         return Status;
725     }
726     pDevice->SubsystemVendorId = (LM_UINT16) Value32;
727
728     /* Get PCI subsystem id. */
729     pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
730
731     /* Get the cache line size. */
732     MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
733     pDevice->CacheLineSize = (LM_UINT8) Value32;
734     pDevice->SavedCacheLineReg = Value32;
735
736     if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
737         pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
738         pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
739     {
740         pDevice->UndiFix = FALSE;
741     }
742 #if !PCIX_TARGET_WORKAROUND
743     pDevice->UndiFix = FALSE;
744 #endif
745     /* Map the memory base to system address space. */
746     if (!pDevice->UndiFix)
747     {
748         Status = MM_MapMemBase(pDevice);
749         if(Status != LM_STATUS_SUCCESS)
750         {
751             return Status;
752         }
753         /* Initialize the memory view pointer. */
754         pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
755     }
756
757 #if PCIX_TARGET_WORKAROUND
758     /* store whether we are in PCI are PCI-X mode */
759     pDevice->EnablePciXFix = FALSE;
760
761     MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
762     if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
763     {
764         /* Enable PCI-X workaround only if we are running on 5700 BX. */
765         if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
766         {
767             pDevice->EnablePciXFix = TRUE;
768         }
769     }
770     if (pDevice->UndiFix)
771     {
772         pDevice->EnablePciXFix = TRUE;
773     }
774 #endif
775     /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
776     /* management register may be clobbered which may cause the */
777     /* BCM5700 to go into D3 state.  While in this state, we will */
778     /* not have memory mapped register access.  As a workaround, we */
779     /* need to restore the device to D0 state. */
780     MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
781     Value32 |= T3_PM_PME_ASSERTED;
782     Value32 &= ~T3_PM_POWER_STATE_MASK;
783     Value32 |= T3_PM_POWER_STATE_D0;
784     MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
785
786     /* read the current PCI command word */
787     MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
788
789     /* Make sure bus-mastering is enabled. */
790     Value32 |= PCI_BUSMASTER_ENABLE;
791
792 #if PCIX_TARGET_WORKAROUND
793     /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
794         are enabled */
795     if (pDevice->EnablePciXFix == TRUE) {
796         Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
797                     PCI_PARITY_ERROR_ENABLE);
798     }
799     if (pDevice->UndiFix)
800     {
801         Value32 &= ~PCI_MEM_SPACE_ENABLE;
802     }
803
804 #endif
805
806     if(pDevice->EnableMWI)
807     {
808         Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
809     }
810     else {
811         Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
812     }
813
814     /* Error out if mem-mapping is NOT enabled for PCI systems */
815     if (!(Value32 | PCI_MEM_SPACE_ENABLE))
816     {
817         return LM_STATUS_FAILURE;
818     }
819
820     /* save the value we are going to write into the PCI command word */
821     pDevice->PciCommandStatusWords = Value32;
822
823     Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
824     if(Status != LM_STATUS_SUCCESS)
825     {
826         return Status;
827     }
828
829     /* Set power state to D0. */
830     LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
831
832 #ifdef BIG_ENDIAN_PCI
833     pDevice->MiscHostCtrl =
834         MISC_HOST_CTRL_MASK_PCI_INT |
835         MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
836         MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
837         MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
838 #else /* No CPU Swap modes for PCI IO */
839
840     /* Setup the mode registers. */
841     pDevice->MiscHostCtrl =
842         MISC_HOST_CTRL_MASK_PCI_INT |
843         MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
844 #ifdef BIG_ENDIAN_HOST
845         MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
846 #endif /* BIG_ENDIAN_HOST */
847         MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
848         MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
849 #endif /* !BIG_ENDIAN_PCI */
850
851     /* write to PCI misc host ctr first in order to enable indirect accesses */
852     MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
853
854     REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
855
856 #ifdef BIG_ENDIAN_PCI
857     Value32 = GRC_MODE_WORD_SWAP_DATA|
858               GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
859 #else
860 /* No CPU Swap modes for PCI IO */
861 #ifdef BIG_ENDIAN_HOST
862     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
863               GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
864 #else
865     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
866 #endif
867 #endif /* !BIG_ENDIAN_PCI */
868
869     REG_WR(pDevice, Grc.Mode, Value32);
870
871     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
872     {
873         REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
874             GRC_MISC_LOCAL_CTRL_GPIO_OE1);
875     }
876     MM_Wait(40);
877
878     /* Enable indirect memory access */
879     REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
880
881     if (REG_RD(pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK)
882     {
883         REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
884                 T3_PCI_SELECT_ALTERNATE_CLOCK);
885         REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_SELECT_ALTERNATE_CLOCK);
886         MM_Wait(40);  /* required delay is 27usec */
887     }
888     REG_WR(pDevice, PciCfg.ClockCtrl, 0);
889     REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
890
891 #if PCIX_TARGET_WORKAROUND
892     MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
893     if ((pDevice->EnablePciXFix == FALSE) &&
894         ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
895     {
896         if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
897             pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
898             pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
899             pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
900         {
901             __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x300]));
902             __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
903             __raw_writel(0xffffffff, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
904             if (__raw_readl(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
905             {
906                 pDevice->EnablePciXFix = TRUE;
907             }
908         }
909     }
910 #endif
911 #if 1
912     /*
913     *  This code was at the beginning of else block below, but that's
914     *  a bug if node address in shared memory.
915     */
916     MM_Wait(50);
917     LM_NvramInit(pDevice);
918 #endif
919     /* Get the node address.  First try to get in from the shared memory. */
920     /* If the signature is not present, then get it from the NVRAM. */
921     Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
922     if((Value32 >> 16) == 0x484b)
923     {
924
925         pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
926         pDevice->NodeAddress[1] = (LM_UINT8) Value32;
927
928         Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
929
930         pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
931         pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
932         pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
933         pDevice->NodeAddress[5] = (LM_UINT8) Value32;
934
935         Status = LM_STATUS_SUCCESS;
936     }
937     else
938     {
939         Status = LM_NvramRead(pDevice, 0x7c, &Value32);
940         if(Status == LM_STATUS_SUCCESS)
941         {
942             pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
943             pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
944
945             Status = LM_NvramRead(pDevice, 0x80, &Value32);
946
947             pDevice->NodeAddress[2] = (LM_UINT8) Value32;
948             pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
949             pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
950             pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
951         }
952     }
953
954     /* Assign a default address. */
955     if(Status != LM_STATUS_SUCCESS)
956     {
957 #ifndef EMBEDDED
958         printk(KERN_ERR "Cannot get MAC addr from NVRAM. Using default.\n");
959 #endif
960         pDevice->NodeAddress[0] = 0x00; pDevice->NodeAddress[1] = 0x10;
961         pDevice->NodeAddress[2] = 0x18; pDevice->NodeAddress[3] = 0x68;
962         pDevice->NodeAddress[4] = 0x61; pDevice->NodeAddress[5] = 0x76;
963     }
964
965     pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
966     pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
967     pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
968     pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
969     pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
970     pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
971
972     /* Initialize the default values. */
973     pDevice->NoTxPseudoHdrChksum = FALSE;
974     pDevice->NoRxPseudoHdrChksum = FALSE;
975     pDevice->NicSendBd = FALSE;
976     pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
977     pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
978     pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
979     pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
980     pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
981     pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
982     pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
983     pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
984     pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
985     pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
986     pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
987     pDevice->EnableMWI = FALSE;
988     pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
989     pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
990     pDevice->DisableAutoNeg = FALSE;
991     pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
992     pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
993     pDevice->LedMode = LED_MODE_AUTO;
994     pDevice->ResetPhyOnInit = TRUE;
995     pDevice->DelayPciGrant = TRUE;
996     pDevice->UseTaggedStatus = FALSE;
997     pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
998
999     pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
1000     pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
1001     pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
1002
1003     pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
1004     pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
1005     pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
1006     pDevice->EnableTbi = FALSE;
1007 #if INCLUDE_TBI_SUPPORT
1008     pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
1009 #endif
1010
1011     switch (T3_ASIC_REV(pDevice->ChipRevId))
1012     {
1013     case T3_ASIC_REV_5704:
1014         pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1015         pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
1016         break;
1017     default:
1018         pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1019         pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
1020         break;
1021     }
1022
1023     pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
1024     pDevice->QueueRxPackets = TRUE;
1025
1026     pDevice->EnableWireSpeed = TRUE;
1027
1028 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1029     pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
1030 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1031
1032     /* Make this is a known adapter. */
1033     pAdapterInfo = LM_GetAdapterInfoBySsid(pDevice->SubsystemVendorId,
1034         pDevice->SubsystemId);
1035
1036     pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
1037     if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
1038         pDevice->BondId != GRC_MISC_BD_ID_5701 &&
1039         pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
1040         pDevice->BondId != GRC_MISC_BD_ID_5703 &&
1041         pDevice->BondId != GRC_MISC_BD_ID_5703S &&
1042         pDevice->BondId != GRC_MISC_BD_ID_5704 &&
1043         pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE)
1044     {
1045         return LM_STATUS_UNKNOWN_ADAPTER;
1046     }
1047
1048     pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
1049     if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
1050         (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
1051     {
1052         pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
1053         pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
1054     }
1055
1056     /* Get Eeprom info. */
1057     Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
1058     if (Value32 == T3_NIC_DATA_SIG)
1059     {
1060         EeSigFound = TRUE;
1061         Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
1062
1063         /* Determine PHY type. */
1064         switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
1065         {
1066             case T3_NIC_CFG_PHY_TYPE_COPPER:
1067                 EePhyTypeSerdes = FALSE;
1068                 break;
1069
1070             case T3_NIC_CFG_PHY_TYPE_FIBER:
1071                 EePhyTypeSerdes = TRUE;
1072                 break;
1073
1074             default:
1075                 EePhyTypeSerdes = FALSE;
1076                 break;
1077         }
1078
1079         /* Determine PHY led mode. */
1080         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1081             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1082         {
1083             switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
1084             {
1085                 case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
1086                     EePhyLedMode = LED_MODE_THREE_LINK;
1087                     break;
1088
1089                 case T3_NIC_CFG_LED_MODE_LINK_SPEED:
1090                     EePhyLedMode = LED_MODE_LINK10;
1091                     break;
1092
1093                 default:
1094                     EePhyLedMode = LED_MODE_AUTO;
1095                     break;
1096             }
1097         }
1098         else
1099         {
1100             switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
1101             {
1102                 case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
1103                     EePhyLedMode = LED_MODE_OPEN_DRAIN;
1104                     break;
1105
1106                 case T3_NIC_CFG_LED_MODE_OUTPUT:
1107                     EePhyLedMode = LED_MODE_OUTPUT;
1108                     break;
1109
1110                 default:
1111                     EePhyLedMode = LED_MODE_AUTO;
1112                     break;
1113             }
1114         }
1115         if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1116             pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
1117         {
1118             /* Enable EEPROM write protection. */
1119             if(Value32 & T3_NIC_EEPROM_WP)
1120             {
1121                 pDevice->EepromWp = TRUE;
1122             }
1123         }
1124
1125         /* Get the PHY Id. */
1126         Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1127         if (Value32)
1128         {
1129             EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1130                 PHY_ID1_OUI_MASK) << 10;
1131
1132             Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1133
1134             EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1135               (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1136         }
1137         else
1138         {
1139             EePhyId = 0;
1140         }
1141     }
1142     else
1143     {
1144         EeSigFound = FALSE;
1145     }
1146
1147     /* Set the PHY address. */
1148     pDevice->PhyAddr = PHY_DEVICE_ID;
1149
1150     /* Disable auto polling. */
1151     pDevice->MiMode = 0xc0000;
1152     REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
1153     MM_Wait(40);
1154
1155     /* Get the PHY id. */
1156     LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
1157     pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
1158
1159     LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
1160     pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1161       (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1162
1163     /* Set the EnableTbi flag to false if we have a copper PHY. */
1164     switch(pDevice->PhyId & PHY_ID_MASK)
1165     {
1166         case PHY_BCM5400_PHY_ID:
1167             pDevice->EnableTbi = FALSE;
1168             break;
1169
1170         case PHY_BCM5401_PHY_ID:
1171             pDevice->EnableTbi = FALSE;
1172             break;
1173
1174         case PHY_BCM5411_PHY_ID:
1175             pDevice->EnableTbi = FALSE;
1176             break;
1177
1178         case PHY_BCM5701_PHY_ID:
1179             pDevice->EnableTbi = FALSE;
1180             break;
1181
1182         case PHY_BCM5703_PHY_ID:
1183             pDevice->EnableTbi = FALSE;
1184             break;
1185
1186         case PHY_BCM5704_PHY_ID:
1187             pDevice->EnableTbi = FALSE;
1188             break;
1189
1190         case PHY_BCM8002_PHY_ID:
1191             pDevice->EnableTbi = TRUE;
1192             break;
1193
1194         default:
1195
1196             if (pAdapterInfo)
1197             {
1198                 pDevice->PhyId = pAdapterInfo->PhyId;
1199                 pDevice->EnableTbi = pAdapterInfo->Serdes;
1200             }
1201             else if (EeSigFound)
1202             {
1203                 pDevice->PhyId = EePhyId;
1204                 pDevice->EnableTbi = EePhyTypeSerdes;
1205             }
1206             break;
1207     }
1208
1209     /* Bail out if we don't know the copper PHY id. */
1210     if(UNKNOWN_PHY_ID(pDevice->PhyId) && !pDevice->EnableTbi)
1211     {
1212         return LM_STATUS_FAILURE;
1213     }
1214
1215     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1216     {
1217         if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
1218         {
1219             pDevice->SavedCacheLineReg &= 0xffff00ff;
1220             pDevice->SavedCacheLineReg |= 0x4000;
1221         }
1222     }
1223     /* Change driver parameters. */
1224     Status = MM_GetConfig(pDevice);
1225     if(Status != LM_STATUS_SUCCESS)
1226     {
1227         return Status;
1228     }
1229
1230 #if INCLUDE_5701_AX_FIX
1231     if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1232         pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1233     {
1234         pDevice->ResetPhyOnInit = TRUE;
1235     }
1236 #endif
1237
1238     /* Save the current phy link status. */
1239     if(!pDevice->EnableTbi)
1240     {
1241         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1242         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1243
1244         /* If we don't have link reset the PHY. */
1245         if(!(Value32 & PHY_STATUS_LINK_PASS) || pDevice->ResetPhyOnInit)
1246         {
1247
1248             LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
1249
1250             for(j = 0; j < 100; j++)
1251             {
1252                 MM_Wait(10);
1253
1254                 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
1255                 if(Value32 && !(Value32 & PHY_CTRL_PHY_RESET))
1256                 {
1257                     MM_Wait(40);
1258                     break;
1259                 }
1260             }
1261
1262
1263 #if INCLUDE_5701_AX_FIX
1264             /* 5701_AX_BX bug:  only advertises 10mb speed. */
1265             if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1266                 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1267             {
1268
1269                 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1270                     PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
1271                     PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
1272                 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
1273                 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
1274                 pDevice->advertising = Value32;
1275
1276                 Value32 = BCM540X_AN_AD_1000BASET_HALF |
1277                     BCM540X_AN_AD_1000BASET_FULL | BCM540X_CONFIG_AS_MASTER |
1278                     BCM540X_ENABLE_CONFIG_AS_MASTER;
1279                 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
1280                 pDevice->advertising1000 = Value32;
1281
1282                 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
1283                     PHY_CTRL_RESTART_AUTO_NEG);
1284             }
1285 #endif
1286             if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1287             {
1288                 LM_WritePhy(pDevice, 0x18, 0x0c00);
1289                 LM_WritePhy(pDevice, 0x17, 0x201f);
1290                 LM_WritePhy(pDevice, 0x15, 0x2aaa);
1291             }
1292             if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
1293             {
1294                 LM_WritePhy(pDevice, 0x1c, 0x8d68);
1295                 LM_WritePhy(pDevice, 0x1c, 0x8d68);
1296             }
1297             /* Enable Ethernet@WireSpeed. */
1298             if(pDevice->EnableWireSpeed)
1299             {
1300                 LM_WritePhy(pDevice, 0x18, 0x7007);
1301                 LM_ReadPhy(pDevice, 0x18, &Value32);
1302                 LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
1303             }
1304         }
1305     }
1306
1307     /* Turn off tap power management. */
1308     if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
1309     {
1310         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
1311         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
1312         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
1313         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
1314         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
1315         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1316         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
1317         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1318         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
1319         LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
1320         LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
1321
1322         MM_Wait(40);
1323     }
1324
1325 #if INCLUDE_TBI_SUPPORT
1326     pDevice->IgnoreTbiLinkChange = FALSE;
1327
1328     if(pDevice->EnableTbi)
1329     {
1330         pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1331         pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1332         if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
1333             pDevice->DisableAutoNeg)
1334         {
1335             pDevice->PollTbiLink = FALSE;
1336         }
1337     }
1338     else
1339     {
1340         pDevice->PollTbiLink = FALSE;
1341     }
1342 #endif /* INCLUDE_TBI_SUPPORT */
1343
1344     /* UseTaggedStatus is only valid for 5701 and later. */
1345     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1346     {
1347         pDevice->UseTaggedStatus = FALSE;
1348
1349         pDevice->CoalesceMode = 0;
1350     }
1351     else
1352     {
1353         pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1354             HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1355     }
1356
1357     /* Set the status block size. */
1358     if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1359         T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
1360     {
1361         pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1362     }
1363
1364     /* Check the DURING_INT coalescing ticks parameters. */
1365     if(pDevice->UseTaggedStatus)
1366     {
1367         if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1368         {
1369             pDevice->RxCoalescingTicksDuringInt =
1370                 DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1371         }
1372
1373         if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1374         {
1375             pDevice->TxCoalescingTicksDuringInt =
1376                 DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1377         }
1378
1379         if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1380         {
1381             pDevice->RxMaxCoalescedFramesDuringInt =
1382                 DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1383         }
1384
1385         if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1386         {
1387             pDevice->TxMaxCoalescedFramesDuringInt =
1388                 DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1389         }
1390     }
1391     else
1392     {
1393         if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1394         {
1395             pDevice->RxCoalescingTicksDuringInt = 0;
1396         }
1397
1398         if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1399         {
1400             pDevice->TxCoalescingTicksDuringInt = 0;
1401         }
1402
1403         if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1404         {
1405             pDevice->RxMaxCoalescedFramesDuringInt = 0;
1406         }
1407
1408         if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1409         {
1410             pDevice->TxMaxCoalescedFramesDuringInt = 0;
1411         }
1412     }
1413
1414 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1415     if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
1416     {
1417         pDevice->RxJumboDescCnt = 0;
1418         if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1419         {
1420             pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1421         }
1422     }
1423     else
1424     {
1425         pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
1426             COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
1427
1428         if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
1429         {
1430             pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1431             pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
1432         }
1433         pDevice->TxMtu = pDevice->RxMtu;
1434
1435     }
1436 #else
1437     pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1438 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1439
1440     pDevice->RxPacketDescCnt =
1441 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1442         pDevice->RxJumboDescCnt +
1443 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1444         pDevice->RxStdDescCnt;
1445
1446     if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1447     {
1448         pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1449     }
1450
1451     if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
1452     {
1453         pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1454     }
1455
1456     /* Configure the proper ways to get link change interrupt. */
1457     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
1458     {
1459         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1460         {
1461             pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1462         }
1463         else
1464         {
1465             pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1466         }
1467     }
1468     else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
1469     {
1470         /* Auto-polling does not work on 5700_AX and 5700_BX. */
1471         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1472         {
1473             pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1474         }
1475     }
1476
1477     /* Determine the method to get link change status. */
1478     if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
1479     {
1480         /* The link status bit in the status block does not work on 5700_AX */
1481         /* and 5700_BX chips. */
1482         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1483         {
1484             pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1485         }
1486         else
1487         {
1488             pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
1489         }
1490     }
1491
1492     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
1493         T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1494     {
1495         pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1496     }
1497
1498     /* Configure PHY led mode. */
1499     if(pDevice->LedMode == LED_MODE_AUTO)
1500     {
1501         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1502             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1503         {
1504             if(pDevice->SubsystemVendorId == T3_SVID_DELL)
1505             {
1506                 pDevice->LedMode = LED_MODE_LINK10;
1507             }
1508             else
1509             {
1510                 pDevice->LedMode = LED_MODE_THREE_LINK;
1511
1512                 if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
1513                 {
1514                     pDevice->LedMode = EePhyLedMode;
1515                 }
1516             }
1517
1518             /* bug? 5701 in LINK10 mode does not seem to work when */
1519             /* PhyIntMode is LINK_READY. */
1520             if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
1521 #if INCLUDE_TBI_SUPPORT
1522                 pDevice->EnableTbi == FALSE &&
1523 #endif
1524                 pDevice->LedMode == LED_MODE_LINK10)
1525             {
1526                 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1527                 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1528             }
1529
1530             if(pDevice->EnableTbi)
1531             {
1532                 pDevice->LedMode = LED_MODE_THREE_LINK;
1533             }
1534         }
1535         else
1536         {
1537             if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
1538             {
1539                 pDevice->LedMode = EePhyLedMode;
1540             }
1541             else
1542             {
1543                 pDevice->LedMode = LED_MODE_OPEN_DRAIN;
1544             }
1545         }
1546     }
1547
1548     /* Enable OneDmaAtOnce. */
1549     if(pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE)
1550     {
1551         pDevice->OneDmaAtOnce = FALSE;
1552     }
1553
1554     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1555         pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1556         pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1557         pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
1558     {
1559         pDevice->WolSpeed = WOL_SPEED_10MB;
1560     }
1561     else
1562     {
1563         pDevice->WolSpeed = WOL_SPEED_100MB;
1564     }
1565
1566     /* Offloadings. */
1567     pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1568
1569     /* Turn off task offloading on Ax. */
1570     if(pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
1571     {
1572         pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1573             LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1574     }
1575     pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
1576     LM_ReadVPD(pDevice);
1577     LM_ReadBootCodeVersion(pDevice);
1578     LM_GetBusSpeed(pDevice);
1579
1580     return LM_STATUS_SUCCESS;
1581 } /* LM_GetAdapterInfo */
1582
1583 STATIC PLM_ADAPTER_INFO
1584 LM_GetAdapterInfoBySsid(
1585     LM_UINT16 Svid,
1586     LM_UINT16 Ssid)
1587 {
1588     static LM_ADAPTER_INFO AdapterArr[] =
1589     {
1590         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
1591         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
1592         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
1593         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
1594         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
1595         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
1596         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
1597         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
1598         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
1599         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5701_PHY_ID, 0},
1600         { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5701_PHY_ID, 0},
1601
1602         { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
1603         { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
1604         { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
1605         { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
1606         { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
1607
1608         { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
1609         { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
1610         { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
1611         { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
1612
1613         { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
1614         { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
1615         { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
1616         { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
1617         { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
1618
1619     };
1620     LM_UINT32 j;
1621
1622     for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
1623     {
1624         if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
1625         {
1626             return &AdapterArr[j];
1627         }
1628     }
1629
1630     return NULL;
1631 }
1632
1633
1634 /******************************************************************************/
1635 /* Description:                                                               */
1636 /*    This routine sets up receive/transmit buffer descriptions queues.       */
1637 /*                                                                            */
1638 /* Return:                                                                    */
1639 /*    LM_STATUS_SUCCESS                                                       */
1640 /******************************************************************************/
1641 LM_STATUS
1642 LM_InitializeAdapter(
1643 PLM_DEVICE_BLOCK pDevice)
1644 {
1645     LM_PHYSICAL_ADDRESS MemPhy;
1646     PLM_UINT8 pMemVirt;
1647     PLM_PACKET pPacket;
1648     LM_STATUS Status;
1649     LM_UINT32 Size;
1650     LM_UINT32 j;
1651
1652     /* Set power state to D0. */
1653     LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
1654
1655     /* Intialize the queues. */
1656     QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
1657         MAX_RX_PACKET_DESC_COUNT);
1658     QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
1659         MAX_RX_PACKET_DESC_COUNT);
1660
1661     QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
1662     QQ_InitQueue(&pDevice->TxPacketActiveQ.Container,MAX_TX_PACKET_DESC_COUNT);
1663     QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
1664
1665     /* Allocate shared memory for: status block, the buffers for receive */
1666     /* rings -- standard, mini, jumbo, and return rings. */
1667     Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
1668         T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
1669 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1670         T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
1671 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1672         T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1673
1674     /* Memory for host based Send BD. */
1675     if(pDevice->NicSendBd == FALSE)
1676     {
1677         Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1678     }
1679
1680     /* Allocate the memory block. */
1681     Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
1682     if(Status != LM_STATUS_SUCCESS)
1683     {
1684         return Status;
1685     }
1686
1687     /* Program DMA Read/Write */
1688     if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
1689     {
1690         pDevice->DmaReadWriteCtrl = 0x763f000f;
1691     }
1692     else
1693     {
1694         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
1695         {
1696             pDevice->DmaReadWriteCtrl = 0x761f0000;
1697         }
1698         else
1699         {
1700             pDevice->DmaReadWriteCtrl = 0x761b000f;
1701         }
1702         if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1703             pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
1704         {
1705             pDevice->OneDmaAtOnce = TRUE;
1706         }
1707     }
1708     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1709     {
1710         pDevice->DmaReadWriteCtrl &= 0xfffffff0;
1711     }
1712
1713     if(pDevice->OneDmaAtOnce)
1714     {
1715         pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
1716     }
1717     REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
1718
1719     if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
1720     {
1721         return LM_STATUS_FAILURE;
1722     }
1723
1724     /* Status block. */
1725     pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
1726     pDevice->StatusBlkPhy = MemPhy;
1727     pMemVirt += T3_STATUS_BLOCK_SIZE;
1728     LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
1729
1730     /* Statistics block. */
1731     pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
1732     pDevice->StatsBlkPhy = MemPhy;
1733     pMemVirt += sizeof(T3_STATS_BLOCK);
1734     LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
1735
1736     /* Receive standard BD buffer. */
1737     pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
1738     pDevice->RxStdBdPhy = MemPhy;
1739
1740     pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1741     LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1742         T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1743
1744 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1745     /* Receive jumbo BD buffer. */
1746     pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
1747     pDevice->RxJumboBdPhy = MemPhy;
1748
1749     pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1750     LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1751         T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1752 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1753
1754     /* Receive return BD buffer. */
1755     pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
1756     pDevice->RcvRetBdPhy = MemPhy;
1757
1758     pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1759     LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1760         T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1761
1762     /* Set up Send BD. */
1763     if(pDevice->NicSendBd == FALSE)
1764     {
1765         pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
1766         pDevice->SendBdPhy = MemPhy;
1767
1768         pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1769         LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1770             sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
1771     }
1772     else
1773     {
1774         pDevice->pSendBdVirt = (PT3_SND_BD)
1775             pDevice->pMemView->uIntMem.First32k.BufferDesc;
1776         pDevice->SendBdPhy.High = 0;
1777         pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
1778     }
1779
1780     /* Allocate memory for packet descriptors. */
1781     Size = (pDevice->RxPacketDescCnt +
1782         pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
1783     Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
1784     if(Status != LM_STATUS_SUCCESS)
1785     {
1786         return Status;
1787     }
1788     pDevice->pPacketDescBase = (PLM_VOID) pPacket;
1789
1790     /* Create transmit packet descriptors from the memory block and add them */
1791     /* to the TxPacketFreeQ for each send ring. */
1792     for(j = 0; j < pDevice->TxPacketDescCnt; j++)
1793     {
1794         /* Ring index. */
1795         pPacket->Flags = 0;
1796
1797         /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
1798         QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
1799
1800         /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1801         /* is the total size of the packet descriptor including the */
1802         /* os-specific extensions in the UM_PACKET structure. */
1803         pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1804     } /* for(j.. */
1805
1806     /* Create receive packet descriptors from the memory block and add them */
1807     /* to the RxPacketFreeQ.  Create the Standard packet descriptors. */
1808     for(j = 0; j < pDevice->RxStdDescCnt; j++)
1809     {
1810         /* Receive producer ring. */
1811         pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
1812
1813         /* Receive buffer size. */
1814         pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
1815
1816         /* Add the descriptor to RxPacketFreeQ. */
1817         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
1818
1819         /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1820         /* is the total size of the packet descriptor including the */
1821         /* os-specific extensions in the UM_PACKET structure. */
1822         pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1823     } /* for */
1824
1825 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1826     /* Create the Jumbo packet descriptors. */
1827     for(j = 0; j < pDevice->RxJumboDescCnt; j++)
1828     {
1829         /* Receive producer ring. */
1830         pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
1831
1832         /* Receive buffer size. */
1833         pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
1834
1835         /* Add the descriptor to RxPacketFreeQ. */
1836         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
1837
1838         /* Get the pointer to the next descriptor.  MM_PACKET_DESC_SIZE */
1839         /* is the total size of the packet descriptor including the */
1840         /* os-specific extensions in the UM_PACKET structure. */
1841         pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1842     } /* for */
1843 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1844
1845     /* Initialize the rest of the packet descriptors. */
1846     Status = MM_InitializeUmPackets(pDevice);
1847     if(Status != LM_STATUS_SUCCESS)
1848     {
1849         return Status;
1850     } /* if */
1851
1852     /* Default receive mask. */
1853     pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1854         LM_ACCEPT_UNICAST;
1855
1856     /* Make sure we are in the first 32k memory window or NicSendBd. */
1857     REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
1858
1859     /* Initialize the hardware. */
1860     Status = LM_ResetAdapter(pDevice);
1861     if(Status != LM_STATUS_SUCCESS)
1862     {
1863         return Status;
1864     }
1865
1866     /* We are done with initialization. */
1867     pDevice->InitDone = TRUE;
1868
1869     return LM_STATUS_SUCCESS;
1870 } /* LM_InitializeAdapter */
1871
1872
1873 /******************************************************************************/
1874 /* Description:                                                               */
1875 /*    This function Enables/Disables a given block.                          */
1876 /*                                                                            */
1877 /* Return:                                                                    */
1878 /*    LM_STATUS_SUCCESS                                                       */
1879 /******************************************************************************/
1880 LM_STATUS
1881 LM_CntrlBlock(
1882 PLM_DEVICE_BLOCK pDevice,
1883 LM_UINT32 mask,LM_UINT32 cntrl)
1884 {
1885     LM_UINT32 j,i,data;
1886     LM_UINT32 MaxWaitCnt;
1887
1888     MaxWaitCnt = 2;
1889     j = 0;
1890
1891     for(i = 0 ; i < 32; i++)
1892     {
1893         if(!(mask & (1 << i)))
1894             continue;
1895
1896         switch (1 << i)
1897         {
1898             case T3_BLOCK_DMA_RD:
1899                 data = REG_RD(pDevice, DmaRead.Mode);
1900                 if (cntrl == LM_DISABLE)
1901                 {
1902                     data &= ~DMA_READ_MODE_ENABLE;
1903                     REG_WR(pDevice, DmaRead.Mode, data);
1904                     for(j = 0; j < MaxWaitCnt; j++)
1905                     {
1906                         if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
1907                             break;
1908                         MM_Wait(10);
1909                     }
1910                 }
1911                 else
1912                     REG_WR(pDevice, DmaRead.Mode, data | DMA_READ_MODE_ENABLE);
1913                 break;
1914
1915             case T3_BLOCK_DMA_COMP:
1916                 data = REG_RD(pDevice,DmaComp.Mode);
1917                 if (cntrl == LM_DISABLE)
1918                 {
1919                     data &= ~DMA_COMP_MODE_ENABLE;
1920                     REG_WR(pDevice, DmaComp.Mode, data);
1921                     for(j = 0; j < MaxWaitCnt; j++)
1922                     {
1923                         if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
1924                             break;
1925                         MM_Wait(10);
1926                     }
1927                 }
1928                 else
1929                     REG_WR(pDevice, DmaComp.Mode, data | DMA_COMP_MODE_ENABLE);
1930                 break;
1931
1932             case T3_BLOCK_RX_BD_INITIATOR:
1933                 data = REG_RD(pDevice, RcvBdIn.Mode);
1934                 if (cntrl == LM_DISABLE)
1935                 {
1936                     data &= ~RCV_BD_IN_MODE_ENABLE;
1937                     REG_WR(pDevice, RcvBdIn.Mode,data);
1938                     for(j = 0; j < MaxWaitCnt; j++)
1939                     {
1940                         if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
1941                             break;
1942                         MM_Wait(10);
1943                     }
1944                 }
1945                 else
1946                     REG_WR(pDevice, RcvBdIn.Mode,data | RCV_BD_IN_MODE_ENABLE);
1947                 break;
1948
1949             case T3_BLOCK_RX_BD_COMP:
1950                 data = REG_RD(pDevice, RcvBdComp.Mode);
1951                 if (cntrl == LM_DISABLE)
1952                 {
1953                     data &= ~RCV_BD_COMP_MODE_ENABLE;
1954                     REG_WR(pDevice, RcvBdComp.Mode,data);
1955                     for(j = 0; j < MaxWaitCnt; j++)
1956                     {
1957                         if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
1958                             break;
1959                         MM_Wait(10);
1960                     }
1961                 }
1962                 else
1963                     REG_WR(pDevice, RcvBdComp.Mode,data | RCV_BD_COMP_MODE_ENABLE);
1964                 break;
1965
1966             case T3_BLOCK_DMA_WR:
1967                 data = REG_RD(pDevice, DmaWrite.Mode);
1968                 if (cntrl == LM_DISABLE)
1969                 {
1970                     data &= ~DMA_WRITE_MODE_ENABLE;
1971                     REG_WR(pDevice, DmaWrite.Mode,data);
1972
1973                     for(j = 0; j < MaxWaitCnt; j++)
1974                     {
1975                         if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
1976                             break;
1977                         MM_Wait(10);
1978                     }
1979                 }
1980                 else
1981                     REG_WR(pDevice, DmaWrite.Mode,data | DMA_WRITE_MODE_ENABLE);
1982                 break;
1983
1984             case T3_BLOCK_MSI_HANDLER:
1985                 data = REG_RD(pDevice, Msi.Mode);
1986                 if (cntrl == LM_DISABLE)
1987                 {
1988                     data &= ~MSI_MODE_ENABLE;
1989                     REG_WR(pDevice, Msi.Mode, data);
1990                     for(j = 0; j < MaxWaitCnt; j++)
1991                     {
1992                         if(!(REG_RD(pDevice, Msi.Mode) & MSI_MODE_ENABLE))
1993                             break;
1994                         MM_Wait(10);
1995                     }
1996                 }
1997                 else
1998                     REG_WR(pDevice, Msi.Mode, data |MSI_MODE_ENABLE);
1999                 break;
2000
2001             case T3_BLOCK_RX_LIST_PLMT:
2002                 data = REG_RD(pDevice, RcvListPlmt.Mode);
2003                 if (cntrl == LM_DISABLE)
2004                 {
2005                     data &= ~RCV_LIST_PLMT_MODE_ENABLE;
2006                     REG_WR(pDevice, RcvListPlmt.Mode,data);
2007                     for(j = 0; j < MaxWaitCnt; j++)
2008                     {
2009                         if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
2010                             break;
2011                         MM_Wait(10);
2012                     }
2013                 }
2014                 else
2015                     REG_WR(pDevice, RcvListPlmt.Mode,data | RCV_LIST_PLMT_MODE_ENABLE);
2016                 break;
2017
2018             case T3_BLOCK_RX_LIST_SELECTOR:
2019                 data = REG_RD(pDevice, RcvListSel.Mode);
2020                 if (cntrl == LM_DISABLE)
2021                 {
2022                     data &= ~RCV_LIST_SEL_MODE_ENABLE;
2023                     REG_WR(pDevice, RcvListSel.Mode,data);
2024                     for(j = 0; j < MaxWaitCnt; j++)
2025                     {
2026                         if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
2027                             break;
2028                         MM_Wait(10);
2029                     }
2030                 }
2031                 else
2032                     REG_WR(pDevice, RcvListSel.Mode,data |RCV_LIST_SEL_MODE_ENABLE);
2033                 break;
2034
2035             case T3_BLOCK_RX_DATA_INITIATOR:
2036                 data = REG_RD(pDevice, RcvDataBdIn.Mode);
2037                 if (cntrl == LM_DISABLE)
2038                 {
2039                     data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
2040                     REG_WR(pDevice, RcvDataBdIn.Mode,data);
2041                     for(j = 0; j < MaxWaitCnt; j++)
2042                     {
2043                         if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
2044                             break;
2045                         MM_Wait(10);
2046                     }
2047                 }
2048                 else
2049                     REG_WR(pDevice, RcvDataBdIn.Mode, data | RCV_DATA_BD_IN_MODE_ENABLE);
2050                 break;
2051
2052             case T3_BLOCK_RX_DATA_COMP:
2053                 data = REG_RD(pDevice, RcvDataComp.Mode);
2054                 if (cntrl == LM_DISABLE)
2055                 {
2056                     data &= ~RCV_DATA_COMP_MODE_ENABLE;
2057                     REG_WR(pDevice, RcvDataComp.Mode,data);
2058                     for(j = 0; j < MaxWaitCnt; j++)
2059                     {
2060                         if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
2061                             break;
2062                         MM_Wait(10);
2063                     }
2064                 }
2065                 else
2066                     REG_WR(pDevice, RcvDataComp.Mode,data | RCV_DATA_COMP_MODE_ENABLE);
2067                 break;
2068
2069             case T3_BLOCK_HOST_COALESING:
2070                 data = REG_RD(pDevice, HostCoalesce.Mode);
2071                 if (cntrl == LM_DISABLE)
2072                 {
2073                     data &= ~HOST_COALESCE_ENABLE;
2074                     REG_WR(pDevice, HostCoalesce.Mode, data);
2075                     for(j = 0; j < MaxWaitCnt; j++)
2076                     {
2077                         if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
2078                             break;
2079                         MM_Wait(10);
2080                     }
2081                 }
2082                 else
2083                     REG_WR(pDevice, HostCoalesce.Mode, data | HOST_COALESCE_ENABLE);
2084                 break;
2085
2086             case T3_BLOCK_MAC_RX_ENGINE:
2087                 if(cntrl == LM_DISABLE)
2088                 {
2089                     pDevice->RxMode &= ~RX_MODE_ENABLE;
2090                     REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2091                     for(j = 0; j < MaxWaitCnt; j++)
2092                     {
2093                         if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
2094                         {
2095                             break;
2096                         }
2097                         MM_Wait(10);
2098                     }
2099                 }
2100                 else
2101                 {
2102                     pDevice->RxMode |= RX_MODE_ENABLE;
2103                     REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2104                 }
2105                 break;
2106
2107             case T3_BLOCK_MBUF_CLUSTER_FREE:
2108                 data = REG_RD(pDevice, MbufClusterFree.Mode);
2109                 if (cntrl == LM_DISABLE)
2110                 {
2111                     data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
2112                     REG_WR(pDevice, MbufClusterFree.Mode,data);
2113                     for(j = 0; j < MaxWaitCnt; j++)
2114                     {
2115                         if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
2116                             break;
2117                         MM_Wait(10);
2118                     }
2119                 }
2120                 else
2121                     REG_WR(pDevice, MbufClusterFree.Mode, data | MBUF_CLUSTER_FREE_MODE_ENABLE);
2122                 break;
2123
2124             case T3_BLOCK_SEND_BD_INITIATOR:
2125                 data = REG_RD(pDevice, SndBdIn.Mode);
2126                 if (cntrl == LM_DISABLE)
2127                 {
2128                     data &= ~SND_BD_IN_MODE_ENABLE;
2129                     REG_WR(pDevice, SndBdIn.Mode, data);
2130                     for(j = 0; j < MaxWaitCnt; j++)
2131                     {
2132                         if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
2133                             break;
2134                         MM_Wait(10);
2135                     }
2136                 }
2137                 else
2138                     REG_WR(pDevice, SndBdIn.Mode, data  | SND_BD_IN_MODE_ENABLE);
2139                 break;
2140
2141             case T3_BLOCK_SEND_BD_COMP:
2142                 data = REG_RD(pDevice, SndBdComp.Mode);
2143                 if (cntrl == LM_DISABLE)
2144                 {
2145                     data &= ~SND_BD_COMP_MODE_ENABLE;
2146                     REG_WR(pDevice, SndBdComp.Mode, data);
2147                     for(j = 0; j < MaxWaitCnt; j++)
2148                     {
2149                         if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
2150                             break;
2151                         MM_Wait(10);
2152                     }
2153                 }
2154                 else
2155                     REG_WR(pDevice, SndBdComp.Mode, data | SND_BD_COMP_MODE_ENABLE);
2156                 break;
2157
2158             case T3_BLOCK_SEND_BD_SELECTOR:
2159                 data = REG_RD(pDevice, SndBdSel.Mode);
2160                 if (cntrl == LM_DISABLE)
2161                 {
2162                     data &= ~SND_BD_SEL_MODE_ENABLE;
2163                     REG_WR(pDevice, SndBdSel.Mode, data);
2164                     for(j = 0; j < MaxWaitCnt; j++)
2165                     {
2166                         if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
2167                             break;
2168                         MM_Wait(10);
2169                     }
2170                 }
2171                 else
2172                     REG_WR(pDevice, SndBdSel.Mode, data | SND_BD_SEL_MODE_ENABLE);
2173                 break;
2174
2175             case T3_BLOCK_SEND_DATA_INITIATOR:
2176                 data = REG_RD(pDevice, SndDataIn.Mode);
2177                 if (cntrl == LM_DISABLE)
2178                 {
2179                     data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2180                     REG_WR(pDevice, SndDataIn.Mode,data);
2181                     for(j = 0; j < MaxWaitCnt; j++)
2182                     {
2183                         if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
2184                             break;
2185                         MM_Wait(10);
2186                     }
2187                 }
2188                 else
2189                     REG_WR(pDevice, SndDataIn.Mode,data | T3_SND_DATA_IN_MODE_ENABLE);
2190                 break;
2191
2192             case T3_BLOCK_SEND_DATA_COMP:
2193                 data = REG_RD(pDevice, SndDataComp.Mode);
2194                 if (cntrl == LM_DISABLE)
2195                 {
2196                     data &= ~SND_DATA_COMP_MODE_ENABLE;
2197                     REG_WR(pDevice, SndDataComp.Mode, data);
2198                     for(j = 0; j < MaxWaitCnt; j++)
2199                     {
2200                         if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
2201                             break;
2202                         MM_Wait(10);
2203                     }
2204                 }
2205                 else
2206                     REG_WR(pDevice, SndDataComp.Mode,data | SND_DATA_COMP_MODE_ENABLE);
2207                 break;
2208
2209             case T3_BLOCK_MAC_TX_ENGINE:
2210                 if(cntrl == LM_DISABLE)
2211                 {
2212                     pDevice->TxMode &= ~TX_MODE_ENABLE;
2213                     REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2214                     for(j = 0; j < MaxWaitCnt; j++)
2215                     {
2216                         if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
2217                             break;
2218                         MM_Wait(10);
2219                     }
2220                 }
2221                 else
2222                 {
2223                     pDevice->TxMode |= TX_MODE_ENABLE;
2224                     REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2225                 }
2226                 break;
2227
2228             case T3_BLOCK_MEM_ARBITOR:
2229                 data = REG_RD(pDevice, MemArbiter.Mode);
2230                 if (cntrl == LM_DISABLE)
2231                 {
2232                     data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2233                     REG_WR(pDevice, MemArbiter.Mode, data);
2234                     for(j = 0; j < MaxWaitCnt; j++)
2235                     {
2236                         if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
2237                             break;
2238                         MM_Wait(10);
2239                     }
2240                 }
2241                 else
2242                     REG_WR(pDevice, MemArbiter.Mode,data|T3_MEM_ARBITER_MODE_ENABLE);
2243                 break;
2244
2245             case T3_BLOCK_MBUF_MANAGER:
2246                 data = REG_RD(pDevice, BufMgr.Mode);
2247                 if (cntrl == LM_DISABLE)
2248                 {
2249                     data &= ~BUFMGR_MODE_ENABLE;
2250                     REG_WR(pDevice, BufMgr.Mode,data);
2251                     for(j = 0; j < MaxWaitCnt; j++)
2252                     {
2253                         if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
2254                             break;
2255                         MM_Wait(10);
2256                     }
2257                 }
2258                 else
2259                     REG_WR(pDevice, BufMgr.Mode,data |  BUFMGR_MODE_ENABLE);
2260                 break;
2261
2262             case T3_BLOCK_MAC_GLOBAL:
2263                 if(cntrl == LM_DISABLE)
2264                 {
2265                     pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
2266                         MAC_MODE_ENABLE_RDE |
2267                         MAC_MODE_ENABLE_FHDE);
2268                 }
2269                 else
2270                 {
2271                     pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
2272                         MAC_MODE_ENABLE_RDE |
2273                         MAC_MODE_ENABLE_FHDE);
2274                 }
2275                 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
2276                 break;
2277
2278             default:
2279                 return LM_STATUS_FAILURE;
2280         } /* switch */
2281
2282         if(j >= MaxWaitCnt)
2283         {
2284             return LM_STATUS_FAILURE;
2285         }
2286     }
2287
2288     return LM_STATUS_SUCCESS;
2289 }
2290
2291 /******************************************************************************/
2292 /* Description:                                                               */
2293 /*    This function reinitializes the adapter.                                */
2294 /*                                                                            */
2295 /* Return:                                                                    */
2296 /*    LM_STATUS_SUCCESS                                                       */
2297 /******************************************************************************/
2298 LM_STATUS
2299 LM_ResetAdapter(
2300 PLM_DEVICE_BLOCK pDevice)
2301 {
2302     LM_UINT32 Value32;
2303     LM_UINT16 Value16;
2304     LM_UINT32 j, k;
2305
2306     /* Disable interrupt. */
2307     LM_DisableInterrupt(pDevice);
2308
2309     /* May get a spurious interrupt */
2310     pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2311
2312     /* Disable transmit and receive DMA engines.  Abort all pending requests. */
2313     if(pDevice->InitDone)
2314     {
2315         LM_Abort(pDevice);
2316     }
2317
2318     pDevice->ShuttingDown = FALSE;
2319
2320     LM_ResetChip(pDevice);
2321
2322     /* Bug: Athlon fix for B3 silicon only.  This bit does not do anything */
2323     /* in other chip revisions. */
2324     if(pDevice->DelayPciGrant)
2325     {
2326         Value32 = REG_RD(pDevice, PciCfg.ClockCtrl);
2327         REG_WR(pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
2328     }
2329
2330     if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2331     {
2332         if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2333         {
2334             Value32 = REG_RD(pDevice, PciCfg.PciState);
2335             Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2336             REG_WR(pDevice, PciCfg.PciState, Value32);
2337         }
2338     }
2339
2340     /* Enable TaggedStatus mode. */
2341     if(pDevice->UseTaggedStatus)
2342     {
2343         pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2344     }
2345
2346     /* Restore PCI configuration registers. */
2347     MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
2348         pDevice->SavedCacheLineReg);
2349     MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2350         (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2351
2352     /* Clear the statistics block. */
2353     for(j = 0x0300; j < 0x0b00; j++)
2354     {
2355         MEM_WR_OFFSET(pDevice, j, 0);
2356     }
2357
2358     /* Initialize the statistis Block */
2359     pDevice->pStatusBlkVirt->Status = 0;
2360     pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2361     pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2362     pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2363
2364     for(j = 0; j < 16; j++)
2365     {
2366        pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2367        pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2368     }
2369
2370     for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
2371     {
2372        pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2373        pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2374     }
2375
2376 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2377     /* Receive jumbo BD buffer. */
2378     for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
2379     {
2380         pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2381         pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2382     }
2383 #endif
2384
2385     REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2386
2387     /* GRC mode control register. */
2388 #ifdef BIG_ENDIAN_PCI    /* Jimmy, this ifdef block deleted in new code! */
2389     Value32 =
2390         GRC_MODE_WORD_SWAP_DATA |
2391         GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2392         GRC_MODE_INT_ON_MAC_ATTN |
2393         GRC_MODE_HOST_STACK_UP;
2394 #else
2395     /* No CPU Swap modes for PCI IO */
2396     Value32 =
2397 #ifdef BIG_ENDIAN_HOST
2398         GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2399         GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2400         GRC_MODE_BYTE_SWAP_DATA |
2401         GRC_MODE_WORD_SWAP_DATA |
2402 #else
2403         GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2404         GRC_MODE_BYTE_SWAP_DATA |
2405         GRC_MODE_WORD_SWAP_DATA |
2406 #endif
2407         GRC_MODE_INT_ON_MAC_ATTN |
2408         GRC_MODE_HOST_STACK_UP;
2409 #endif /* !BIG_ENDIAN_PCI */
2410
2411     /* Configure send BD mode. */
2412     if(pDevice->NicSendBd == FALSE)
2413     {
2414         Value32 |= GRC_MODE_HOST_SEND_BDS;
2415     }
2416     else
2417     {
2418         Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2419     }
2420
2421     /* Configure pseudo checksum mode. */
2422     if(pDevice->NoTxPseudoHdrChksum)
2423     {
2424         Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2425     }
2426
2427     if(pDevice->NoRxPseudoHdrChksum)
2428     {
2429         Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2430     }
2431
2432     REG_WR(pDevice, Grc.Mode, Value32);
2433
2434     /* Setup the timer prescalar register. */
2435     REG_WR(pDevice, Grc.MiscCfg, 65 << 1);      /* Clock is alwasy 66Mhz. */
2436
2437     /* Set up the MBUF pool base address and size. */
2438     REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2439     REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2440
2441     /* Set up the DMA descriptor pool base address and size. */
2442     REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2443     REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2444
2445     /* Configure MBUF and Threshold watermarks */
2446     /* Configure the DMA read MBUF low water mark. */
2447     if(pDevice->DmaMbufLowMark)
2448     {
2449         REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2450             pDevice->DmaMbufLowMark);
2451     }
2452     else
2453     {
2454         if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2455         {
2456             REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2457                 T3_DEF_DMA_MBUF_LOW_WMARK);
2458         }
2459         else
2460         {
2461             REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2462                 T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2463         }
2464     }
2465
2466     /* Configure the MAC Rx MBUF low water mark. */
2467     if(pDevice->RxMacMbufLowMark)
2468     {
2469         REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2470             pDevice->RxMacMbufLowMark);
2471     }
2472     else
2473     {
2474         if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2475         {
2476             REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2477                 T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2478         }
2479         else
2480         {
2481             REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2482                 T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2483         }
2484     }
2485
2486     /* Configure the MBUF high water mark. */
2487     if(pDevice->MbufHighMark)
2488     {
2489         REG_WR(pDevice, BufMgr.MbufHighWaterMark, pDevice->MbufHighMark);
2490     }
2491     else
2492     {
2493         if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2494         {
2495             REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2496                 T3_DEF_MBUF_HIGH_WMARK);
2497         }
2498         else
2499         {
2500             REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2501                 T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2502         }
2503     }
2504
2505     REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2506     REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2507
2508     /* Enable buffer manager. */
2509     REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2510
2511     for(j = 0 ;j < 2000; j++)
2512     {
2513         if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2514             break;
2515         MM_Wait(10);
2516     }
2517
2518     if(j >= 2000)
2519     {
2520         return LM_STATUS_FAILURE;
2521     }
2522
2523     /* Enable the FTQs. */
2524     REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2525     REG_WR(pDevice, Ftq.Reset, 0);
2526
2527     /* Wait until FTQ is ready */
2528     for(j = 0; j < 2000; j++)
2529     {
2530         if(REG_RD(pDevice, Ftq.Reset) == 0)
2531             break;
2532         MM_Wait(10);
2533     }
2534
2535     if(j >= 2000)
2536     {
2537         return LM_STATUS_FAILURE;
2538     }
2539
2540     /* Initialize the Standard Receive RCB. */
2541     REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2542         pDevice->RxStdBdPhy.High);
2543     REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2544         pDevice->RxStdBdPhy.Low);
2545     REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2546         MAX_STD_RCV_BUFFER_SIZE << 16);
2547
2548     /* Initialize the Jumbo Receive RCB. */
2549     REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2550         T3_RCB_FLAG_RING_DISABLED);
2551 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2552     REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2553         pDevice->RxJumboBdPhy.High);
2554     REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2555         pDevice->RxJumboBdPhy.Low);
2556
2557     REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2558
2559 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2560
2561     /* Initialize the Mini Receive RCB. */
2562     REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2563         T3_RCB_FLAG_RING_DISABLED);
2564
2565     {
2566         REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2567             (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2568         REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2569             (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2570     }
2571
2572     /* Receive BD Ring replenish threshold. */
2573     REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
2574 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2575     REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
2576 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2577
2578     /* Disable all the unused rings. */
2579     for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2580         MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
2581     } /* for */
2582
2583     /* Initialize the indices. */
2584     pDevice->SendProdIdx = 0;
2585     pDevice->SendConIdx = 0;
2586
2587     MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2588     MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2589
2590     /* Set up host or NIC based send RCB. */
2591     if(pDevice->NicSendBd == FALSE)
2592     {
2593         MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
2594             pDevice->SendBdPhy.High);
2595         MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
2596             pDevice->SendBdPhy.Low);
2597
2598         /* Set up the NIC ring address in the RCB. */
2599         MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
2600
2601         /* Setup the RCB. */
2602         MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
2603             T3_SEND_RCB_ENTRY_COUNT << 16);
2604
2605         for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
2606         {
2607             pDevice->pSendBdVirt[k].HostAddr.High = 0;
2608             pDevice->pSendBdVirt[k].HostAddr.Low = 0;
2609         }
2610     }
2611     else
2612     {
2613         MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
2614         MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
2615         MEM_WR(pDevice, SendRcb[0].NicRingAddr,
2616             pDevice->SendBdPhy.Low);
2617
2618         for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
2619         {
2620             __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.High));
2621             __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.Low));
2622             __raw_writel(0, &(pDevice->pSendBdVirt[k].u1.Len_Flags));
2623             pDevice->ShadowSendBd[k].HostAddr.High = 0;
2624             pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
2625         }
2626     }
2627     atomic_set(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
2628
2629     /* Configure the receive return rings. */
2630     for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
2631     {
2632         MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
2633     }
2634
2635     pDevice->RcvRetConIdx = 0;
2636
2637     MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
2638         pDevice->RcvRetBdPhy.High);
2639     MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
2640         pDevice->RcvRetBdPhy.Low);
2641
2642     /* Set up the NIC ring address in the RCB. */
2643     /* Not very clear from the spec.  I am guessing that for Receive */
2644     /* Return Ring, NicRingAddr is not used. */
2645     MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
2646
2647     /* Setup the RCB. */
2648     MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
2649         T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
2650
2651     /* Reinitialize RX ring producer index */
2652     MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
2653     MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
2654     MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
2655
2656 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2657     pDevice->RxJumboProdIdx = 0;
2658     pDevice->RxJumboQueuedCnt = 0;
2659 #endif
2660
2661     /* Reinitialize our copy of the indices. */
2662     pDevice->RxStdProdIdx = 0;
2663     pDevice->RxStdQueuedCnt = 0;
2664
2665 #if T3_JUMBO_RCV_ENTRY_COUNT
2666     pDevice->RxJumboProdIdx = 0;
2667 #endif /* T3_JUMBO_RCV_ENTRY_COUNT */
2668
2669     /* Configure the MAC address. */
2670     LM_SetMacAddress(pDevice, pDevice->NodeAddress);
2671
2672     /* Initialize the transmit random backoff seed. */
2673     Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
2674         pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
2675         pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
2676         MAC_TX_BACKOFF_SEED_MASK;
2677     REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
2678
2679     /* Receive MTU.  Frames larger than the MTU is marked as oversized. */
2680     REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8);   /* CRC + VLAN. */
2681
2682     /* Configure Time slot/IPG per 802.3 */
2683     REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
2684
2685     /*
2686      * Configure Receive Rules so that packets don't match
2687      * Programmble rule will be queued to Return Ring 1
2688      */
2689     REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
2690
2691     /*
2692      * Configure to have 16 Classes of Services (COS) and one
2693      * queue per class.  Bad frames are queued to RRR#1.
2694      * And frames don't match rules are also queued to COS#1.
2695      */
2696     REG_WR(pDevice, RcvListPlmt.Config, 0x181);
2697
2698     /* Enable Receive Placement Statistics */
2699     REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
2700     REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
2701
2702     /* Enable Send Data Initator Statistics */
2703     REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
2704     REG_WR(pDevice, SndDataIn.StatsCtrl,
2705         T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
2706         T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
2707
2708     /* Disable the host coalescing state machine before configuring it's */
2709     /* parameters. */
2710     REG_WR(pDevice, HostCoalesce.Mode, 0);
2711     for(j = 0; j < 2000; j++)
2712     {
2713         Value32 = REG_RD(pDevice, HostCoalesce.Mode);
2714         if(!(Value32 & HOST_COALESCE_ENABLE))
2715         {
2716             break;
2717         }
2718         MM_Wait(10);
2719     }
2720
2721     /* Host coalescing configurations. */
2722     REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
2723     REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
2724     REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
2725         pDevice->RxMaxCoalescedFrames);
2726     REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
2727         pDevice->TxMaxCoalescedFrames);
2728     REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
2729         pDevice->RxCoalescingTicksDuringInt);
2730     REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
2731         pDevice->TxCoalescingTicksDuringInt);
2732     REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
2733         pDevice->RxMaxCoalescedFramesDuringInt);
2734     REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
2735         pDevice->TxMaxCoalescedFramesDuringInt);
2736
2737     /* Initialize the address of the status block.  The NIC will DMA */
2738     /* the status block to this memory which resides on the host. */
2739     REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
2740         pDevice->StatusBlkPhy.High);
2741     REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
2742         pDevice->StatusBlkPhy.Low);
2743
2744     /* Initialize the address of the statistics block.  The NIC will DMA */
2745     /* the statistics to this block of memory. */
2746     REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
2747         pDevice->StatsBlkPhy.High);
2748     REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
2749         pDevice->StatsBlkPhy.Low);
2750
2751     REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
2752         pDevice->StatsCoalescingTicks);
2753
2754     REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
2755     REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
2756
2757     /* Enable Host Coalesing state machine */
2758     REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
2759         pDevice->CoalesceMode);
2760
2761     /* Enable the Receive BD Completion state machine. */
2762     REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
2763         RCV_BD_COMP_MODE_ATTN_ENABLE);
2764
2765     /* Enable the Receive List Placement state machine. */
2766     REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
2767
2768     /* Enable the Receive List Selector state machine. */
2769     REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
2770         RCV_LIST_SEL_MODE_ATTN_ENABLE);
2771
2772     /* Enable transmit DMA, clear statistics. */
2773     pDevice->MacMode =  MAC_MODE_ENABLE_TX_STATISTICS |
2774         MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
2775         MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
2776     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
2777         MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
2778
2779     /* GRC miscellaneous local control register. */
2780     pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
2781         GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
2782
2783     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2784     {
2785         pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
2786             GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
2787     }
2788
2789     REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
2790     MM_Wait(40);
2791
2792     /* Reset RX counters. */
2793     for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
2794     {
2795         ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
2796     }
2797
2798     /* Reset TX counters. */
2799     for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
2800     {
2801         ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
2802     }
2803
2804     MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
2805
2806     /* Enable the DMA Completion state machine. */
2807     REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
2808
2809     /* Enable the DMA Write state machine. */
2810     Value32 = DMA_WRITE_MODE_ENABLE |
2811         DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
2812         DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
2813         DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
2814         DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2815         DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2816         DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2817         DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2818         DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
2819     REG_WR(pDevice, DmaWrite.Mode, Value32);
2820
2821     if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2822     {
2823         if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2824         {
2825             Value16 = REG_RD(pDevice, PciCfg.PciXCommand);
2826             Value16 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
2827             Value16 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
2828                 PCIX_CMD_MAX_BURST_MASK);
2829             if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
2830             {
2831                 Value16 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
2832                    & PCIX_CMD_MAX_SPLIT_MASK;
2833             }
2834             REG_WR(pDevice, PciCfg.PciXCommand, Value16);
2835         }
2836     }
2837
2838     /* Enable the Read DMA state machine. */
2839     Value32 = DMA_READ_MODE_ENABLE |
2840         DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
2841         DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
2842         DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
2843         DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2844         DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2845         DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2846         DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2847         DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
2848
2849     if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
2850     {
2851         Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
2852     }
2853     REG_WR(pDevice, DmaRead.Mode, Value32);
2854
2855     /* Enable the Receive Data Completion state machine. */
2856     REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
2857         RCV_DATA_COMP_MODE_ATTN_ENABLE);
2858
2859     /* Enable the Mbuf Cluster Free state machine. */
2860     REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
2861
2862     /* Enable the Send Data Completion state machine. */
2863     REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
2864
2865     /* Enable the Send BD Completion state machine. */
2866     REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
2867         SND_BD_COMP_MODE_ATTN_ENABLE);
2868
2869     /* Enable the Receive BD Initiator state machine. */
2870     REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
2871         RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
2872
2873     /* Enable the Receive Data and Receive BD Initiator state machine. */
2874     REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
2875         RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
2876
2877     /* Enable the Send Data Initiator state machine. */
2878     REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
2879
2880     /* Enable the Send BD Initiator state machine. */
2881     REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
2882         SND_BD_IN_MODE_ATTN_ENABLE);
2883
2884     /* Enable the Send BD Selector state machine. */
2885     REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
2886         SND_BD_SEL_MODE_ATTN_ENABLE);
2887
2888 #if INCLUDE_5701_AX_FIX
2889     /* Load the firmware for the 5701_A0 workaround. */
2890     if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
2891     {
2892         LM_LoadRlsFirmware(pDevice);
2893     }
2894 #endif
2895
2896     /* Enable the transmitter. */
2897     pDevice->TxMode = TX_MODE_ENABLE;
2898     REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2899
2900     /* Enable the receiver. */
2901     pDevice->RxMode = RX_MODE_ENABLE;
2902     REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2903
2904     if (pDevice->RestoreOnWakeUp)
2905     {
2906         pDevice->RestoreOnWakeUp = FALSE;
2907         pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
2908         pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
2909     }
2910
2911     /* Disable auto polling. */
2912     pDevice->MiMode = 0xc0000;
2913     REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
2914
2915     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2916         T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
2917     {
2918         Value32 = LED_CTRL_PHY_MODE_1;
2919     }
2920     else
2921     {
2922         if(pDevice->LedMode == LED_MODE_OUTPUT)
2923         {
2924             Value32 = LED_CTRL_PHY_MODE_2;
2925         }
2926         else
2927         {
2928             Value32 = LED_CTRL_PHY_MODE_1;
2929         }
2930     }
2931     REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
2932
2933     /* Activate Link to enable MAC state machine */
2934     REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
2935
2936     if (pDevice->EnableTbi)
2937     {
2938         REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
2939         MM_Wait(10);
2940         REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2941         if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
2942         {
2943             REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
2944         }
2945     }
2946     /* Setup the phy chip. */
2947     LM_SetupPhy(pDevice);
2948
2949     if (!pDevice->EnableTbi) {
2950         /* Clear CRC stats */
2951         LM_ReadPhy(pDevice, 0x1e, &Value32);
2952         LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
2953         LM_ReadPhy(pDevice, 0x14, &Value32);
2954     }
2955
2956     /* Set up the receive mask. */
2957     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
2958
2959     /* Queue Rx packet buffers. */
2960     if(pDevice->QueueRxPackets)
2961     {
2962         LM_QueueRxPackets(pDevice);
2963     }
2964
2965     /* Enable interrupt to the host. */
2966     if(pDevice->InitDone)
2967     {
2968         LM_EnableInterrupt(pDevice);
2969     }
2970
2971     return LM_STATUS_SUCCESS;
2972 } /* LM_ResetAdapter */
2973
2974
2975 /******************************************************************************/
2976 /* Description:                                                               */
2977 /*    This routine disables the adapter from generating interrupts.           */
2978 /*                                                                            */
2979 /* Return:                                                                    */
2980 /*    LM_STATUS_SUCCESS                                                       */
2981 /******************************************************************************/
2982 LM_STATUS
2983 LM_DisableInterrupt(
2984     PLM_DEVICE_BLOCK pDevice)
2985 {
2986     REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
2987         MISC_HOST_CTRL_MASK_PCI_INT);
2988     MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
2989
2990     return LM_STATUS_SUCCESS;
2991 }
2992
2993
2994 /******************************************************************************/
2995 /* Description:                                                               */
2996 /*    This routine enables the adapter to generate interrupts.                */
2997 /*                                                                            */
2998 /* Return:                                                                    */
2999 /*    LM_STATUS_SUCCESS                                                       */
3000 /******************************************************************************/
3001 LM_STATUS
3002 LM_EnableInterrupt(
3003     PLM_DEVICE_BLOCK pDevice)
3004 {
3005     REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
3006         ~MISC_HOST_CTRL_MASK_PCI_INT);
3007     MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
3008
3009     if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED)
3010     {
3011         REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
3012             GRC_MISC_LOCAL_CTRL_SET_INT);
3013     }
3014
3015     return LM_STATUS_SUCCESS;
3016 }
3017
3018
3019 /******************************************************************************/
3020 /* Description:                                                               */
3021 /*    This routine puts a packet on the wire if there is a transmit DMA       */
3022 /*    descriptor available; otherwise the packet is queued for later          */
3023 /*    transmission.  If the second argue is NULL, this routine will put       */
3024 /*    the queued packet on the wire if possible.                              */
3025 /*                                                                            */
3026 /* Return:                                                                    */
3027 /*    LM_STATUS_SUCCESS                                                       */
3028 /******************************************************************************/
3029 #if 0
3030 LM_STATUS
3031 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3032 {
3033     LM_UINT32 FragCount;
3034     PT3_SND_BD pSendBd;
3035     PT3_SND_BD pShadowSendBd;
3036     LM_UINT32 Value32, Len;
3037     LM_UINT32 Idx;
3038
3039     if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) {
3040         return LM_5700SendPacket(pDevice, pPacket);
3041     }
3042
3043     /* Update the SendBdLeft count. */
3044     atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3045
3046     /* Initalize the send buffer descriptors. */
3047     Idx = pDevice->SendProdIdx;
3048
3049     pSendBd = &pDevice->pSendBdVirt[Idx];
3050
3051     /* Next producer index. */
3052     if (pDevice->NicSendBd == TRUE)
3053     {
3054         T3_64BIT_HOST_ADDR paddr;
3055
3056         pShadowSendBd = &pDevice->ShadowSendBd[Idx];
3057         for(FragCount = 0; ; )
3058         {
3059             MM_MapTxDma(pDevice, pPacket, &paddr, &Len, FragCount);
3060             /* Initialize the pointer to the send buffer fragment. */
3061             if (paddr.High != pShadowSendBd->HostAddr.High)
3062             {
3063                 __raw_writel(paddr.High, &(pSendBd->HostAddr.High));
3064                 pShadowSendBd->HostAddr.High = paddr.High;
3065             }
3066             __raw_writel(paddr.Low, &(pSendBd->HostAddr.Low));
3067
3068             /* Setup the control flags and send buffer size. */
3069             Value32 = (Len << 16) | pPacket->Flags;
3070
3071             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3072
3073             FragCount++;
3074             if (FragCount >= pPacket->u.Tx.FragCount)
3075             {
3076                 Value32 |= SND_BD_FLAG_END;
3077                 if (Value32 != pShadowSendBd->u1.Len_Flags)
3078                 {
3079                     __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3080                     pShadowSendBd->u1.Len_Flags = Value32;
3081                 }
3082                 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3083                     __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
3084                 }
3085                 break;
3086             }
3087             else
3088             {
3089                 if (Value32 != pShadowSendBd->u1.Len_Flags)
3090                 {
3091                     __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3092                     pShadowSendBd->u1.Len_Flags = Value32;
3093                 }
3094                 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3095                     __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
3096                 }
3097             }
3098
3099             pSendBd++;
3100             pShadowSendBd++;
3101             if (Idx == 0)
3102             {
3103                 pSendBd = &pDevice->pSendBdVirt[0];
3104                 pShadowSendBd = &pDevice->ShadowSendBd[0];
3105             }
3106         } /* for */
3107
3108         /* Put the packet descriptor in the ActiveQ. */
3109         QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3110
3111         wmb();
3112         MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3113
3114     }
3115     else
3116     {
3117         for(FragCount = 0; ; )
3118         {
3119             /* Initialize the pointer to the send buffer fragment. */
3120             MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3121
3122             pSendBd->u2.VlanTag = pPacket->VlanTag;
3123
3124             /* Setup the control flags and send buffer size. */
3125             Value32 = (Len << 16) | pPacket->Flags;
3126
3127             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3128
3129             FragCount++;
3130             if (FragCount >= pPacket->u.Tx.FragCount)
3131             {
3132                 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3133                 break;
3134             }
3135             else
3136             {
3137                 pSendBd->u1.Len_Flags = Value32;
3138             }
3139             pSendBd++;
3140             if (Idx == 0)
3141             {
3142                 pSendBd = &pDevice->pSendBdVirt[0];
3143             }
3144         } /* for */
3145
3146         /* Put the packet descriptor in the ActiveQ. */
3147         QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3148
3149         wmb();
3150         MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3151
3152     }
3153
3154     /* Update the producer index. */
3155     pDevice->SendProdIdx = Idx;
3156
3157     return LM_STATUS_SUCCESS;
3158 }
3159 #endif
3160
3161 LM_STATUS
3162 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3163 {
3164     LM_UINT32 FragCount;
3165     PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
3166     T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
3167     LM_UINT32 StartIdx, Idx;
3168
3169     while (1)
3170     {
3171         /* Initalize the send buffer descriptors. */
3172         StartIdx = Idx = pDevice->SendProdIdx;
3173
3174         if (pDevice->NicSendBd)
3175         {
3176             pTmpSendBd = pSendBd = &NicSendBdArr[0];
3177         }
3178         else
3179         {
3180             pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
3181         }
3182
3183         /* Next producer index. */
3184         for(FragCount = 0; ; )
3185         {
3186             LM_UINT32 Value32, Len;
3187
3188             /* Initialize the pointer to the send buffer fragment. */
3189             MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3190
3191             pSendBd->u2.VlanTag = pPacket->VlanTag;
3192
3193             /* Setup the control flags and send buffer size. */
3194             Value32 = (Len << 16) | pPacket->Flags;
3195
3196             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3197
3198             FragCount++;
3199             if (FragCount >= pPacket->u.Tx.FragCount)
3200             {
3201                 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3202                 break;
3203             }
3204             else
3205             {
3206                 pSendBd->u1.Len_Flags = Value32;
3207             }
3208             pSendBd++;
3209             if ((Idx == 0) && !pDevice->NicSendBd)
3210             {
3211                 pSendBd = &pDevice->pSendBdVirt[0];
3212             }
3213         } /* for */
3214         if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3215         {
3216             if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
3217                 LM_STATUS_SUCCESS)
3218             {
3219                 if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
3220                 {
3221                     QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
3222                     return LM_STATUS_FAILURE;
3223                 }
3224                 continue;
3225             }
3226         }
3227         break;
3228     }
3229     /* Put the packet descriptor in the ActiveQ. */
3230     QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3231
3232     if (pDevice->NicSendBd)
3233     {
3234         pSendBd = &pDevice->pSendBdVirt[StartIdx];
3235         pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
3236
3237         while (StartIdx != Idx)
3238         {
3239             LM_UINT32 Value32;
3240
3241             if ((Value32 = pTmpSendBd->HostAddr.High) !=
3242                 pShadowSendBd->HostAddr.High)
3243             {
3244                 __raw_writel(Value32, &(pSendBd->HostAddr.High));
3245                 pShadowSendBd->HostAddr.High = Value32;
3246             }
3247
3248             __raw_writel(pTmpSendBd->HostAddr.Low, &(pSendBd->HostAddr.Low));
3249
3250             if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3251                 pShadowSendBd->u1.Len_Flags)
3252             {
3253                 __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3254                 pShadowSendBd->u1.Len_Flags = Value32;
3255             }
3256
3257             if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
3258             {
3259                 __raw_writel(pTmpSendBd->u2.VlanTag, &(pSendBd->u2.VlanTag));
3260             }
3261
3262             StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3263             if (StartIdx == 0)
3264                 pSendBd = &pDevice->pSendBdVirt[0];
3265             else
3266                 pSendBd++;
3267             pTmpSendBd++;
3268         }
3269         wmb();
3270         MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3271
3272         if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3273         {
3274             MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3275         }
3276     }
3277     else
3278     {
3279         wmb();
3280         MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3281
3282         if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3283         {
3284             MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3285         }
3286     }
3287
3288     /* Update the SendBdLeft count. */
3289     atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3290
3291     /* Update the producer index. */
3292     pDevice->SendProdIdx = Idx;
3293
3294     return LM_STATUS_SUCCESS;
3295 }
3296
3297 STATIC LM_STATUS
3298 LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3299     PT3_SND_BD pSendBd)
3300 {
3301     int FragCount;
3302     LM_UINT32 Idx, Base, Len;
3303
3304     Idx = pDevice->SendProdIdx;
3305     for(FragCount = 0; ; )
3306     {
3307         Len = pSendBd->u1.Len_Flags >> 16;
3308         if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3309             (pSendBd->HostAddr.High == 0) &&
3310             ((Base + 8 + Len) < Base))
3311         {
3312             return LM_STATUS_SUCCESS;
3313         }
3314         FragCount++;
3315         if (FragCount >= pPacket->u.Tx.FragCount)
3316         {
3317             break;
3318         }
3319         pSendBd++;
3320         if (!pDevice->NicSendBd)
3321         {
3322             Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3323             if (Idx == 0)
3324             {
3325                 pSendBd = &pDevice->pSendBdVirt[0];
3326             }
3327         }
3328     }
3329     return LM_STATUS_FAILURE;
3330 }
3331
3332 /******************************************************************************/
3333 /* Description:                                                               */
3334 /*                                                                            */
3335 /* Return:                                                                    */
3336 /******************************************************************************/
3337 __inline static unsigned long
3338 ComputeCrc32(
3339 unsigned char *pBuffer,
3340 unsigned long BufferSize) {
3341     unsigned long Reg;
3342     unsigned long Tmp;
3343     unsigned long j, k;
3344
3345     Reg = 0xffffffff;
3346
3347     for(j = 0; j < BufferSize; j++)
3348     {
3349         Reg ^= pBuffer[j];
3350
3351         for(k = 0; k < 8; k++)
3352         {
3353             Tmp = Reg & 0x01;
3354
3355             Reg >>= 1;
3356
3357             if(Tmp)
3358             {
3359                 Reg ^= 0xedb88320;
3360             }
3361         }
3362     }
3363
3364     return ~Reg;
3365 } /* ComputeCrc32 */
3366
3367
3368 /******************************************************************************/
3369 /* Description:                                                               */
3370 /*    This routine sets the receive control register according to ReceiveMask */
3371 /*                                                                            */
3372 /* Return:                                                                    */
3373 /*    LM_STATUS_SUCCESS                                                       */
3374 /******************************************************************************/
3375 LM_STATUS
3376 LM_SetReceiveMask(
3377 PLM_DEVICE_BLOCK pDevice,
3378 LM_UINT32 Mask) {
3379     LM_UINT32 ReceiveMask;
3380     LM_UINT32 RxMode;
3381     LM_UINT32 j, k;
3382
3383     ReceiveMask = Mask;
3384
3385     RxMode = pDevice->RxMode;
3386
3387     if(Mask & LM_ACCEPT_UNICAST)
3388     {
3389         Mask &= ~LM_ACCEPT_UNICAST;
3390     }
3391
3392     if(Mask & LM_ACCEPT_MULTICAST)
3393     {
3394         Mask &= ~LM_ACCEPT_MULTICAST;
3395     }
3396
3397     if(Mask & LM_ACCEPT_ALL_MULTICAST)
3398     {
3399         Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3400     }
3401
3402     if(Mask & LM_ACCEPT_BROADCAST)
3403     {
3404         Mask &= ~LM_ACCEPT_BROADCAST;
3405     }
3406
3407     RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3408     if(Mask & LM_PROMISCUOUS_MODE)
3409     {
3410         RxMode |= RX_MODE_PROMISCUOUS_MODE;
3411         Mask &= ~LM_PROMISCUOUS_MODE;
3412     }
3413
3414     RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3415     if(Mask & LM_ACCEPT_ERROR_PACKET)
3416     {
3417         RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3418         Mask &= ~LM_ACCEPT_ERROR_PACKET;
3419     }
3420
3421     /* Make sure all the bits are valid before committing changes. */
3422     if(Mask)
3423     {
3424         return LM_STATUS_FAILURE;
3425     }
3426
3427     /* Commit the new filter. */
3428     pDevice->RxMode = RxMode;
3429     REG_WR(pDevice, MacCtrl.RxMode, RxMode);
3430
3431     pDevice->ReceiveMask = ReceiveMask;
3432
3433     /* Set up the MC hash table. */
3434     if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
3435     {
3436         for(k = 0; k < 4; k++)
3437         {
3438             REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
3439         }
3440     }
3441     else if(ReceiveMask & LM_ACCEPT_MULTICAST)
3442     {
3443         LM_UINT32 HashReg[4];
3444
3445         HashReg[0] = 0; HashReg[1] = 0; HashReg[2] = 0; HashReg[3] = 0;
3446         for(j = 0; j < pDevice->McEntryCount; j++)
3447         {
3448             LM_UINT32 RegIndex;
3449             LM_UINT32 Bitpos;
3450             LM_UINT32 Crc32;
3451
3452             Crc32 = ComputeCrc32(pDevice->McTable[j], ETHERNET_ADDRESS_SIZE);
3453
3454             /* The most significant 7 bits of the CRC32 (no inversion), */
3455             /* are used to index into one of the possible 128 bit positions. */
3456             Bitpos = ~Crc32 & 0x7f;
3457
3458             /* Hash register index. */
3459             RegIndex = (Bitpos & 0x60) >> 5;
3460
3461             /* Bit to turn on within a hash register. */
3462             Bitpos &= 0x1f;
3463
3464             /* Enable the multicast bit. */
3465             HashReg[RegIndex] |= (1 << Bitpos);
3466         }
3467
3468         /* REV_AX has problem with multicast filtering where it uses both */
3469         /* DA and SA to perform hashing. */
3470         for(k = 0; k < 4; k++)
3471         {
3472             REG_WR(pDevice, MacCtrl.HashReg[k], HashReg[k]);
3473         }
3474     }
3475     else
3476     {
3477         /* Reject all multicast frames. */
3478         for(j = 0; j < 4; j++)
3479         {
3480             REG_WR(pDevice, MacCtrl.HashReg[j], 0);
3481         }
3482     }
3483
3484     /* By default, Tigon3 will accept broadcast frames.  We need to setup */
3485     if(ReceiveMask & LM_ACCEPT_BROADCAST)
3486     {
3487         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3488             REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3489         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3490             REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3491         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3492             REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3493         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3494             REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3495     }
3496     else
3497     {
3498         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3499             REJECT_BROADCAST_RULE1_RULE);
3500         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3501             REJECT_BROADCAST_RULE1_VALUE);
3502         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3503             REJECT_BROADCAST_RULE2_RULE);
3504         REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3505             REJECT_BROADCAST_RULE2_VALUE);
3506     }
3507
3508     /* disable the rest of the rules. */
3509     for(j = RCV_LAST_RULE_IDX; j < 16; j++)
3510     {
3511         REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
3512         REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
3513     }
3514
3515     return LM_STATUS_SUCCESS;
3516 } /* LM_SetReceiveMask */
3517
3518
3519 /******************************************************************************/
3520 /* Description:                                                               */
3521 /*    Disable the interrupt and put the transmitter and receiver engines in   */
3522 /*    an idle state.  Also aborts all pending send requests and receive       */
3523 /*    buffers.                                                                */
3524 /*                                                                            */
3525 /* Return:                                                                    */
3526 /*    LM_STATUS_SUCCESS                                                       */
3527 /******************************************************************************/
3528 LM_STATUS
3529 LM_Abort(
3530 PLM_DEVICE_BLOCK pDevice)
3531 {
3532     PLM_PACKET pPacket;
3533     LM_UINT Idx;
3534
3535     LM_DisableInterrupt(pDevice);
3536
3537     /* Disable all the state machines. */
3538     LM_CntrlBlock(pDevice,T3_BLOCK_MAC_RX_ENGINE,LM_DISABLE);
3539     LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_INITIATOR,LM_DISABLE);
3540     LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_PLMT,LM_DISABLE);
3541     LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_SELECTOR,LM_DISABLE);
3542     LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_INITIATOR,LM_DISABLE);
3543     LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_COMP,LM_DISABLE);
3544     LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_COMP,LM_DISABLE);
3545
3546     LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_SELECTOR,LM_DISABLE);
3547     LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_INITIATOR,LM_DISABLE);
3548     LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_INITIATOR,LM_DISABLE);
3549     LM_CntrlBlock(pDevice,T3_BLOCK_DMA_RD,LM_DISABLE);
3550     LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_COMP,LM_DISABLE);
3551     LM_CntrlBlock(pDevice,T3_BLOCK_DMA_COMP,LM_DISABLE);
3552     LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_COMP,LM_DISABLE);
3553
3554     /* Clear TDE bit */
3555     pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
3556     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
3557
3558     LM_CntrlBlock(pDevice,T3_BLOCK_MAC_TX_ENGINE,LM_DISABLE);
3559     LM_CntrlBlock(pDevice,T3_BLOCK_HOST_COALESING,LM_DISABLE);
3560     LM_CntrlBlock(pDevice,T3_BLOCK_DMA_WR,LM_DISABLE);
3561     LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_CLUSTER_FREE,LM_DISABLE);
3562
3563     /* Reset all FTQs */
3564     REG_WR(pDevice, Ftq.Reset, 0xffffffff);
3565     REG_WR(pDevice, Ftq.Reset, 0x0);
3566
3567     LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_MANAGER,LM_DISABLE);
3568     LM_CntrlBlock(pDevice,T3_BLOCK_MEM_ARBITOR,LM_DISABLE);
3569
3570     MM_ACQUIRE_INT_LOCK(pDevice);
3571
3572     /* Abort packets that have already queued to go out. */
3573     pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
3574     while(pPacket)
3575     {
3576
3577         pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3578         pDevice->TxCounters.TxPacketAbortedCnt++;
3579
3580         atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3581
3582         QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
3583
3584         pPacket = (PLM_PACKET)
3585             QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
3586     }
3587
3588     /* Cleanup the receive return rings. */
3589     LM_ServiceRxInterrupt(pDevice);
3590
3591     /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
3592     /* Doing so may cause system crash. */
3593     if(!pDevice->ShuttingDown)
3594     {
3595         /* Indicate packets to the protocol. */
3596         MM_IndicateTxPackets(pDevice);
3597
3598         /* Indicate received packets to the protocols. */
3599         MM_IndicateRxPackets(pDevice);
3600     }
3601     else
3602     {
3603         /* Move the receive packet descriptors in the ReceivedQ to the */
3604         /* free queue. */
3605         for(; ;)
3606         {
3607             pPacket = (PLM_PACKET) QQ_PopHead(
3608                 &pDevice->RxPacketReceivedQ.Container);
3609             if(pPacket == NULL)
3610             {
3611                 break;
3612             }
3613             QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3614         }
3615     }
3616
3617     /* Clean up the Std Receive Producer ring. */
3618     Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
3619
3620     while(Idx != pDevice->RxStdProdIdx) {
3621         pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3622             MM_UINT_PTR(pDevice->pRxStdBdVirt[Idx].Opaque));
3623
3624         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3625
3626         Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
3627     } /* while */
3628
3629     /* Reinitialize our copy of the indices. */
3630     pDevice->RxStdProdIdx = 0;
3631
3632 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3633     /* Clean up the Jumbo Receive Producer ring. */
3634     Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
3635
3636     while(Idx != pDevice->RxJumboProdIdx) {
3637         pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3638             MM_UINT_PTR(pDevice->pRxJumboBdVirt[Idx].Opaque));
3639
3640         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3641
3642         Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
3643     } /* while */
3644
3645     /* Reinitialize our copy of the indices. */
3646     pDevice->RxJumboProdIdx = 0;
3647 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3648
3649     MM_RELEASE_INT_LOCK(pDevice);
3650
3651     /* Initialize the statistis Block */
3652     pDevice->pStatusBlkVirt->Status = 0;
3653     pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
3654     pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
3655     pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
3656
3657     return LM_STATUS_SUCCESS;
3658 } /* LM_Abort */
3659
3660
3661 /******************************************************************************/
3662 /* Description:                                                               */
3663 /*    Disable the interrupt and put the transmitter and receiver engines in   */
3664 /*    an idle state.  Aborts all pending send requests and receive buffers.   */
3665 /*    Also free all the receive buffers.                                      */
3666 /*                                                                            */
3667 /* Return:                                                                    */
3668 /*    LM_STATUS_SUCCESS                                                       */
3669 /******************************************************************************/
3670 LM_STATUS
3671 LM_Halt(
3672 PLM_DEVICE_BLOCK pDevice) {
3673     PLM_PACKET pPacket;
3674     LM_UINT32 EntryCnt;
3675
3676     LM_Abort(pDevice);
3677
3678     /* Get the number of entries in the queue. */
3679     EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
3680
3681     /* Make sure all the packets have been accounted for. */
3682     for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
3683     {
3684         pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
3685         if (pPacket == 0)
3686             break;
3687
3688         MM_FreeRxBuffer(pDevice, pPacket);
3689
3690         QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3691     }
3692
3693     LM_ResetChip(pDevice);
3694
3695     /* Restore PCI configuration registers. */
3696     MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
3697         pDevice->SavedCacheLineReg);
3698     LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
3699         (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
3700
3701     /* Reprogram the MAC address. */
3702     LM_SetMacAddress(pDevice, pDevice->NodeAddress);
3703
3704     return LM_STATUS_SUCCESS;
3705 } /* LM_Halt */
3706
3707
3708 STATIC LM_STATUS
3709 LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
3710 {
3711     LM_UINT32 Value32;
3712     LM_UINT32 j;
3713
3714     /* Wait for access to the nvram interface before resetting.  This is */
3715     /* a workaround to prevent EEPROM corruption. */
3716     if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
3717         T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
3718     {
3719         /* Request access to the flash interface. */
3720         REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
3721
3722         for(j = 0; j < 100000; j++)
3723         {
3724             Value32 = REG_RD(pDevice, Nvram.SwArb);
3725             if(Value32 & SW_ARB_GNT1)
3726             {
3727                 break;
3728             }
3729             MM_Wait(10);
3730         }
3731     }
3732
3733     /* Global reset. */
3734     REG_WR(pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
3735     MM_Wait(40); MM_Wait(40); MM_Wait(40);
3736
3737     /* make sure we re-enable indirect accesses */
3738     MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
3739         pDevice->MiscHostCtrl);
3740
3741     /* Set MAX PCI retry to zero. */
3742     Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
3743     if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
3744     {
3745         if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
3746         {
3747             Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
3748         }
3749     }
3750     MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
3751
3752     /* Restore PCI command register. */
3753     MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
3754         pDevice->PciCommandStatusWords);
3755
3756     /* Disable PCI-X relaxed ordering bit. */
3757     MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
3758     Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
3759     MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
3760
3761     /* Enable memory arbiter. */
3762     REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
3763
3764 #ifdef BIG_ENDIAN_PCI      /* This from jfd */
3765         Value32 = GRC_MODE_WORD_SWAP_DATA|
3766                   GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
3767 #else
3768 #ifdef BIG_ENDIAN_HOST
3769     /* Reconfigure the mode register. */
3770     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
3771               GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3772               GRC_MODE_BYTE_SWAP_DATA |
3773               GRC_MODE_WORD_SWAP_DATA;
3774 #else
3775     /* Reconfigure the mode register. */
3776     Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
3777 #endif
3778 #endif
3779     REG_WR(pDevice, Grc.Mode, Value32);
3780
3781     /* Prevent PXE from restarting. */
3782     MEM_WR_OFFSET(pDevice, 0x0b50, T3_MAGIC_NUM);
3783
3784     if(pDevice->EnableTbi) {
3785         pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
3786         REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
3787     }
3788     else {
3789         REG_WR(pDevice, MacCtrl.Mode, 0);
3790     }
3791
3792     /* Wait for the firmware to finish initialization. */
3793     for(j = 0; j < 100000; j++)
3794     {
3795         MM_Wait(10);
3796
3797         Value32 = MEM_RD_OFFSET(pDevice, 0x0b50);
3798         if(Value32 == ~T3_MAGIC_NUM)
3799         {
3800             break;
3801         }
3802     }
3803     return LM_STATUS_SUCCESS;
3804 }
3805
3806 /******************************************************************************/
3807 /* Description:                                                               */
3808 /*                                                                            */
3809 /* Return:                                                                    */
3810 /******************************************************************************/
3811 __inline static void
3812 LM_ServiceTxInterrupt(
3813 PLM_DEVICE_BLOCK pDevice) {
3814     PLM_PACKET pPacket;
3815     LM_UINT32 HwConIdx;
3816     LM_UINT32 SwConIdx;
3817
3818     HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3819
3820     /* Get our copy of the consumer index.  The buffer descriptors */
3821     /* that are in between the consumer indices are freed. */
3822     SwConIdx = pDevice->SendConIdx;
3823
3824     /* Move the packets from the TxPacketActiveQ that are sent out to */
3825     /* the TxPacketXmittedQ.  Packets that are sent use the */
3826     /* descriptors that are between SwConIdx and HwConIdx. */
3827     while(SwConIdx != HwConIdx)
3828     {
3829         /* Get the packet that was sent from the TxPacketActiveQ. */
3830         pPacket = (PLM_PACKET) QQ_PopHead(
3831             &pDevice->TxPacketActiveQ.Container);
3832
3833         /* Set the return status. */
3834         pPacket->PacketStatus = LM_STATUS_SUCCESS;
3835
3836         /* Put the packet in the TxPacketXmittedQ for indication later. */
3837         QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
3838
3839         /* Move to the next packet's BD. */
3840         SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
3841             T3_SEND_RCB_ENTRY_COUNT_MASK;
3842
3843         /* Update the number of unused BDs. */
3844         atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3845
3846         /* Get the new updated HwConIdx. */
3847         HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3848     } /* while */
3849
3850     /* Save the new SwConIdx. */
3851     pDevice->SendConIdx = SwConIdx;
3852
3853 } /* LM_ServiceTxInterrupt */
3854
3855
3856 /******************************************************************************/
3857 /* Description:                                                               */
3858 /*                                                                            */
3859 /* Return:                                                                    */
3860 /******************************************************************************/
3861 __inline static void
3862 LM_ServiceRxInterrupt(
3863 PLM_DEVICE_BLOCK pDevice) {
3864     PLM_PACKET pPacket;
3865     PT3_RCV_BD pRcvBd;
3866     LM_UINT32 HwRcvRetProdIdx;
3867     LM_UINT32 SwRcvRetConIdx;
3868
3869     /* Loop thru the receive return rings for received packets. */
3870     HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3871
3872     SwRcvRetConIdx = pDevice->RcvRetConIdx;
3873     while(SwRcvRetConIdx != HwRcvRetProdIdx)
3874     {
3875         pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
3876
3877         /* Get the received packet descriptor. */
3878         pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3879             MM_UINT_PTR(pRcvBd->Opaque));
3880
3881         /* Check the error flag. */
3882         if(pRcvBd->ErrorFlag &&
3883             pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
3884         {
3885             pPacket->PacketStatus = LM_STATUS_FAILURE;
3886
3887             pDevice->RxCounters.RxPacketErrCnt++;
3888
3889             if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
3890             {
3891                 pDevice->RxCounters.RxErrCrcCnt++;
3892             }
3893
3894             if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
3895             {
3896                 pDevice->RxCounters.RxErrCollCnt++;
3897             }
3898
3899             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
3900             {
3901                 pDevice->RxCounters.RxErrLinkLostCnt++;
3902             }
3903
3904             if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
3905             {
3906                 pDevice->RxCounters.RxErrPhyDecodeCnt++;
3907             }
3908
3909             if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
3910             {
3911                 pDevice->RxCounters.RxErrOddNibbleCnt++;
3912             }
3913
3914             if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
3915             {
3916                 pDevice->RxCounters.RxErrMacAbortCnt++;
3917             }
3918
3919             if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
3920             {
3921                 pDevice->RxCounters.RxErrShortPacketCnt++;
3922             }
3923
3924             if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
3925             {
3926                 pDevice->RxCounters.RxErrNoResourceCnt++;
3927             }
3928
3929             if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
3930             {
3931                 pDevice->RxCounters.RxErrLargePacketCnt++;
3932             }
3933         }
3934         else
3935         {
3936             pPacket->PacketStatus = LM_STATUS_SUCCESS;
3937             pPacket->PacketSize = pRcvBd->Len - 4;
3938
3939             pPacket->Flags = pRcvBd->Flags;
3940             if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
3941             {
3942                 pPacket->VlanTag = pRcvBd->VlanTag;
3943             }
3944
3945             pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
3946         }
3947
3948         /* Put the packet descriptor containing the received packet */
3949         /* buffer in the RxPacketReceivedQ for indication later. */
3950         QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
3951
3952         /* Go to the next buffer descriptor. */
3953         SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
3954             T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
3955
3956         /* Get the updated HwRcvRetProdIdx. */
3957         HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3958     } /* while */
3959
3960     pDevice->RcvRetConIdx = SwRcvRetConIdx;
3961
3962     /* Update the receive return ring consumer index. */
3963     MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
3964 } /* LM_ServiceRxInterrupt */
3965
3966
3967 /******************************************************************************/
3968 /* Description:                                                               */
3969 /*    This is the interrupt event handler routine. It acknowledges all        */
3970 /*    pending interrupts and process all pending events.                      */
3971 /*                                                                            */
3972 /* Return:                                                                    */
3973 /*    LM_STATUS_SUCCESS                                                       */
3974 /******************************************************************************/
3975 LM_STATUS
3976 LM_ServiceInterrupts(
3977     PLM_DEVICE_BLOCK pDevice)
3978 {
3979     LM_UINT32 Value32;
3980     int ServicePhyInt = FALSE;
3981
3982     /* Setup the phy chip whenever the link status changes. */
3983     if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
3984     {
3985         Value32 = REG_RD(pDevice, MacCtrl.Status);
3986         if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
3987         {
3988             if (Value32 & MAC_STATUS_MI_INTERRUPT)
3989             {
3990                 ServicePhyInt = TRUE;
3991             }
3992         }
3993         else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
3994         {
3995             ServicePhyInt = TRUE;
3996         }
3997     }
3998     else
3999     {
4000         if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
4001         {
4002             pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4003                 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4004             ServicePhyInt = TRUE;
4005         }
4006     }
4007 #if INCLUDE_TBI_SUPPORT
4008     if (pDevice->IgnoreTbiLinkChange == TRUE)
4009     {
4010         ServicePhyInt = FALSE;
4011     }
4012 #endif
4013     if (ServicePhyInt == TRUE)
4014     {
4015         LM_SetupPhy(pDevice);
4016     }
4017
4018     /* Service receive and transmit interrupts. */
4019     LM_ServiceRxInterrupt(pDevice);
4020     LM_ServiceTxInterrupt(pDevice);
4021
4022     /* No spinlock for this queue since this routine is serialized. */
4023     if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
4024     {
4025         /* Indicate receive packets. */
4026         MM_IndicateRxPackets(pDevice);
4027         /*       LM_QueueRxPackets(pDevice); */
4028     }
4029
4030     /* No spinlock for this queue since this routine is serialized. */
4031     if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
4032     {
4033         MM_IndicateTxPackets(pDevice);
4034     }
4035
4036     return LM_STATUS_SUCCESS;
4037 } /* LM_ServiceInterrupts */
4038
4039
4040 /******************************************************************************/
4041 /* Description:                                                               */
4042 /*                                                                            */
4043 /* Return:                                                                    */
4044 /******************************************************************************/
4045 LM_STATUS
4046 LM_MulticastAdd(
4047 PLM_DEVICE_BLOCK pDevice,
4048 PLM_UINT8 pMcAddress) {
4049     PLM_UINT8 pEntry;
4050     LM_UINT32 j;
4051
4052     pEntry = pDevice->McTable[0];
4053     for(j = 0; j < pDevice->McEntryCount; j++)
4054     {
4055         if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
4056         {
4057             /* Found a match, increment the instance count. */
4058             pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
4059
4060             return LM_STATUS_SUCCESS;
4061         }
4062
4063         pEntry += LM_MC_ENTRY_SIZE;
4064     }
4065
4066     if(pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE)
4067     {
4068         return LM_STATUS_FAILURE;
4069     }
4070
4071     pEntry = pDevice->McTable[pDevice->McEntryCount];
4072
4073     COPY_ETH_ADDRESS(pMcAddress, pEntry);
4074     pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
4075
4076     pDevice->McEntryCount++;
4077
4078     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
4079
4080     return LM_STATUS_SUCCESS;
4081 } /* LM_MulticastAdd */
4082
4083
4084 /******************************************************************************/
4085 /* Description:                                                               */
4086 /*                                                                            */
4087 /* Return:                                                                    */
4088 /******************************************************************************/
4089 LM_STATUS
4090 LM_MulticastDel(
4091 PLM_DEVICE_BLOCK pDevice,
4092 PLM_UINT8 pMcAddress) {
4093     PLM_UINT8 pEntry;
4094     LM_UINT32 j;
4095
4096     pEntry = pDevice->McTable[0];
4097     for(j = 0; j < pDevice->McEntryCount; j++)
4098     {
4099         if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
4100         {
4101             /* Found a match, decrement the instance count. */
4102             pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
4103
4104             /* No more instance left, remove the address from the table. */
4105             /* Move the last entry in the table to the delete slot. */
4106             if(pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
4107                 pDevice->McEntryCount > 1)
4108             {
4109
4110                 COPY_ETH_ADDRESS(
4111                     pDevice->McTable[pDevice->McEntryCount-1], pEntry);
4112                 pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
4113                     pDevice->McTable[pDevice->McEntryCount-1]
4114                     [LM_MC_INSTANCE_COUNT_INDEX];
4115             }
4116             pDevice->McEntryCount--;
4117
4118             /* Update the receive mask if the table is empty. */
4119             if(pDevice->McEntryCount == 0)
4120             {
4121                 LM_SetReceiveMask(pDevice,
4122                     pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4123             }
4124
4125             return LM_STATUS_SUCCESS;
4126         }
4127
4128         pEntry += LM_MC_ENTRY_SIZE;
4129     }
4130
4131     return LM_STATUS_FAILURE;
4132 } /* LM_MulticastDel */
4133
4134
4135 /******************************************************************************/
4136 /* Description:                                                               */
4137 /*                                                                            */
4138 /* Return:                                                                    */
4139 /******************************************************************************/
4140 LM_STATUS
4141 LM_MulticastClear(
4142 PLM_DEVICE_BLOCK pDevice) {
4143     pDevice->McEntryCount = 0;
4144
4145     LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4146
4147     return LM_STATUS_SUCCESS;
4148 } /* LM_MulticastClear */
4149
4150
4151 /******************************************************************************/
4152 /* Description:                                                               */
4153 /*                                                                            */
4154 /* Return:                                                                    */
4155 /******************************************************************************/
4156 LM_STATUS
4157 LM_SetMacAddress(
4158     PLM_DEVICE_BLOCK pDevice,
4159     PLM_UINT8 pMacAddress)
4160 {
4161     LM_UINT32 j;
4162
4163     for(j = 0; j < 4; j++)
4164     {
4165         REG_WR(pDevice, MacCtrl.MacAddr[j].High,
4166             (pMacAddress[0] << 8) | pMacAddress[1]);
4167         REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
4168             (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4169             (pMacAddress[4] << 8) | pMacAddress[5]);
4170     }
4171
4172     return LM_STATUS_SUCCESS;
4173 }
4174
4175
4176 /******************************************************************************/
4177 /* Description:                                                               */
4178 /*    Sets up the default line speed, and duplex modes based on the requested */
4179 /*    media type.                                                             */
4180 /*                                                                            */
4181 /* Return:                                                                    */
4182 /*    None.                                                                   */
4183 /******************************************************************************/
4184 static LM_STATUS
4185 LM_TranslateRequestedMediaType(
4186 LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
4187 PLM_MEDIA_TYPE pMediaType,
4188 PLM_LINE_SPEED pLineSpeed,
4189 PLM_DUPLEX_MODE pDuplexMode) {
4190     *pMediaType = LM_MEDIA_TYPE_AUTO;
4191     *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
4192     *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4193
4194     /* determine media type */
4195     switch(RequestedMediaType) {
4196         case LM_REQUESTED_MEDIA_TYPE_BNC:
4197             *pMediaType = LM_MEDIA_TYPE_BNC;
4198             *pLineSpeed = LM_LINE_SPEED_10MBPS;
4199             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4200             break;
4201
4202         case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
4203             *pMediaType = LM_MEDIA_TYPE_UTP;
4204             break;
4205
4206         case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
4207             *pMediaType = LM_MEDIA_TYPE_UTP;
4208             *pLineSpeed = LM_LINE_SPEED_10MBPS;
4209             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4210             break;
4211
4212         case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
4213             *pMediaType = LM_MEDIA_TYPE_UTP;
4214             *pLineSpeed = LM_LINE_SPEED_10MBPS;
4215             *pDuplexMode = LM_DUPLEX_MODE_FULL;
4216             break;
4217
4218         case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
4219             *pMediaType = LM_MEDIA_TYPE_UTP;
4220             *pLineSpeed = LM_LINE_SPEED_100MBPS;
4221             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4222             break;
4223
4224         case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
4225             *pMediaType = LM_MEDIA_TYPE_UTP;
4226             *pLineSpeed = LM_LINE_SPEED_100MBPS;
4227             *pDuplexMode = LM_DUPLEX_MODE_FULL;
4228             break;
4229
4230         case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
4231             *pMediaType = LM_MEDIA_TYPE_UTP;
4232             *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4233             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4234             break;
4235
4236         case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
4237             *pMediaType = LM_MEDIA_TYPE_UTP;
4238             *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4239             *pDuplexMode = LM_DUPLEX_MODE_FULL;
4240             break;
4241
4242         case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
4243             *pMediaType = LM_MEDIA_TYPE_FIBER;
4244             *pLineSpeed = LM_LINE_SPEED_100MBPS;
4245             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4246             break;
4247
4248         case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
4249             *pMediaType = LM_MEDIA_TYPE_FIBER;
4250             *pLineSpeed = LM_LINE_SPEED_100MBPS;
4251             *pDuplexMode = LM_DUPLEX_MODE_FULL;
4252             break;
4253
4254         case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
4255             *pMediaType = LM_MEDIA_TYPE_FIBER;
4256             *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4257             *pDuplexMode = LM_DUPLEX_MODE_HALF;
4258             break;
4259
4260         case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
4261             *pMediaType = LM_MEDIA_TYPE_FIBER;
4262             *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4263             *pDuplexMode = LM_DUPLEX_MODE_FULL;
4264             break;
4265
4266         default:
4267             break;
4268     } /* switch */
4269
4270     return LM_STATUS_SUCCESS;
4271 } /* LM_TranslateRequestedMediaType */
4272
4273 /******************************************************************************/
4274 /* Description:                                                               */
4275 /*                                                                            */
4276 /* Return:                                                                    */
4277 /*    LM_STATUS_LINK_ACTIVE                                                   */
4278 /*    LM_STATUS_LINK_DOWN                                                     */
4279 /******************************************************************************/
4280 static LM_STATUS
4281 LM_InitBcm540xPhy(
4282 PLM_DEVICE_BLOCK pDevice)
4283 {
4284     LM_LINE_SPEED CurrentLineSpeed;
4285     LM_DUPLEX_MODE CurrentDuplexMode;
4286     LM_STATUS CurrentLinkStatus;
4287     LM_UINT32 Value32;
4288     LM_UINT32 j;
4289
4290 #if 1  /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
4291     LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x2);
4292 #endif
4293     if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4294     {
4295         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4296         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4297
4298         if(!pDevice->InitDone)
4299         {
4300             Value32 = 0;
4301         }
4302
4303         if(!(Value32 & PHY_STATUS_LINK_PASS))
4304         {
4305             LM_WritePhy(pDevice, BCM5401_AUX_CTRL,  0x0c20);
4306
4307             LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4308             LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4309
4310             LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4311             LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4312
4313             LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4314             LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4315
4316             LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4317             LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4318
4319             LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4320             LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4321
4322             LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4323             for(j = 0; j < 1000; j++)
4324             {
4325                 MM_Wait(10);
4326
4327                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4328                 if(Value32 & PHY_STATUS_LINK_PASS)
4329                 {
4330                     MM_Wait(40);
4331                     break;
4332                 }
4333             }
4334
4335             if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
4336             {
4337                 if(!(Value32 & PHY_STATUS_LINK_PASS) &&
4338                     (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
4339                 {
4340                     LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
4341                     for(j = 0; j < 100; j++)
4342                     {
4343                         MM_Wait(10);
4344
4345                         LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4346                         if(!(Value32 & PHY_CTRL_PHY_RESET))
4347                         {
4348                             MM_Wait(40);
4349                             break;
4350                         }
4351                     }
4352
4353                     LM_WritePhy(pDevice, BCM5401_AUX_CTRL,  0x0c20);
4354
4355                     LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4356                     LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4357
4358                     LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4359                     LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4360
4361                     LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4362                     LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4363
4364                     LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4365                     LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4366
4367                     LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4368                     LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4369                 }
4370             }
4371         }
4372     }
4373     else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
4374         pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
4375     {
4376         /* Bug: 5701 A0, B0 TX CRC workaround. */
4377         LM_WritePhy(pDevice, 0x15, 0x0a75);
4378         LM_WritePhy(pDevice, 0x1c, 0x8c68);
4379         LM_WritePhy(pDevice, 0x1c, 0x8d68);
4380         LM_WritePhy(pDevice, 0x1c, 0x8c68);
4381     }
4382
4383     /* Acknowledge interrupts. */
4384     LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
4385     LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
4386
4387     /* Configure the interrupt mask. */
4388     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
4389     {
4390         LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
4391     }
4392
4393     /* Configure PHY led mode. */
4394     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
4395         (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
4396     {
4397         if(pDevice->LedMode == LED_MODE_THREE_LINK)
4398         {
4399             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
4400                 BCM540X_EXT_CTRL_LINK3_LED_MODE);
4401         }
4402         else
4403         {
4404             LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
4405         }
4406     }
4407
4408     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4409
4410     /* Get current link and duplex mode. */
4411     for(j = 0; j < 100; j++)
4412     {
4413         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4414         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4415
4416         if(Value32 & PHY_STATUS_LINK_PASS)
4417         {
4418             break;
4419         }
4420         MM_Wait(40);
4421     }
4422
4423     if(Value32 & PHY_STATUS_LINK_PASS)
4424     {
4425
4426         /* Determine the current line and duplex settings. */
4427         LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4428         for(j = 0; j < 2000; j++)
4429         {
4430             MM_Wait(10);
4431
4432             LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4433             if(Value32)
4434             {
4435                 break;
4436             }
4437         }
4438
4439         switch(Value32 & BCM540X_AUX_SPEED_MASK)
4440         {
4441             case BCM540X_AUX_10BASET_HD:
4442                 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4443                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4444                 break;
4445
4446             case BCM540X_AUX_10BASET_FD:
4447                 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4448                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4449                 break;
4450
4451             case BCM540X_AUX_100BASETX_HD:
4452                 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4453                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4454                 break;
4455
4456             case BCM540X_AUX_100BASETX_FD:
4457                 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4458                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4459                 break;
4460
4461             case BCM540X_AUX_100BASET_HD:
4462                 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4463                 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4464                 break;
4465
4466             case BCM540X_AUX_100BASET_FD:
4467                 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4468                 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4469                 break;
4470
4471             default:
4472
4473                 CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
4474                 CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4475                 break;
4476         }
4477
4478         /* Make sure we are in auto-neg mode. */
4479         for (j = 0; j < 200; j++)
4480         {
4481             LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4482             if(Value32 && Value32 != 0x7fff)
4483             {
4484                 break;
4485             }
4486
4487             if(Value32 == 0 && pDevice->RequestedMediaType ==
4488                 LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS)
4489             {
4490                 break;
4491             }
4492
4493             MM_Wait(10);
4494         }
4495
4496         /* Use the current line settings for "auto" mode. */
4497         if(pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
4498             pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
4499         {
4500             if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
4501             {
4502                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4503
4504                 /* We may be exiting low power mode and the link is in */
4505                 /* 10mb.  In this case, we need to restart autoneg. */
4506                 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &Value32);
4507                 pDevice->advertising1000 = Value32;
4508                 /* 5702FE supports 10/100Mb only. */
4509                 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5703 ||
4510                     pDevice->BondId != GRC_MISC_BD_ID_5702FE)
4511                 {
4512                     if(!(Value32 & (BCM540X_AN_AD_1000BASET_HALF |
4513                         BCM540X_AN_AD_1000BASET_FULL)))
4514                     {
4515                         CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4516                     }
4517                 }
4518             }
4519             else
4520             {
4521                 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4522             }
4523         }
4524         else
4525         {
4526             /* Force line settings. */
4527             /* Use the current setting if it matches the user's requested */
4528             /* setting. */
4529             LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4530             if((pDevice->LineSpeed == CurrentLineSpeed) &&
4531                 (pDevice->DuplexMode == CurrentDuplexMode))
4532             {
4533                 if ((pDevice->DisableAutoNeg &&
4534                     !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
4535                     (!pDevice->DisableAutoNeg &&
4536                     (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
4537                 {
4538                     CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4539                 }
4540                 else
4541                 {
4542                     CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4543                 }
4544             }
4545             else
4546             {
4547                 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4548             }
4549         }
4550
4551         /* Save line settings. */
4552         pDevice->LineSpeed = CurrentLineSpeed;
4553         pDevice->DuplexMode = CurrentDuplexMode;
4554         pDevice->MediaType = LM_MEDIA_TYPE_UTP;
4555     }
4556
4557     return CurrentLinkStatus;
4558 } /* LM_InitBcm540xPhy */
4559
4560 /******************************************************************************/
4561 /* Description:                                                               */
4562 /*                                                                            */
4563 /* Return:                                                                    */
4564 /******************************************************************************/
4565 LM_STATUS
4566 LM_SetFlowControl(
4567     PLM_DEVICE_BLOCK pDevice,
4568     LM_UINT32 LocalPhyAd,
4569     LM_UINT32 RemotePhyAd)
4570 {
4571     LM_FLOW_CONTROL FlowCap;
4572
4573     /* Resolve flow control. */
4574     FlowCap = LM_FLOW_CONTROL_NONE;
4575
4576     /* See Table 28B-3 of 802.3ab-1999 spec. */
4577     if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
4578     {
4579         if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
4580         {
4581             if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
4582             {
4583                 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
4584                 {
4585                     FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4586                         LM_FLOW_CONTROL_RECEIVE_PAUSE;
4587                 }
4588                 else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
4589                 {
4590                     FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
4591                 }
4592             }
4593             else
4594             {
4595                 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
4596                 {
4597                     FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4598                         LM_FLOW_CONTROL_RECEIVE_PAUSE;
4599                 }
4600             }
4601         }
4602         else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
4603         {
4604             if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
4605                 (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
4606             {
4607                 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4608             }
4609         }
4610     }
4611     else
4612     {
4613         FlowCap = pDevice->FlowControlCap;
4614     }
4615
4616     /* Enable/disable rx PAUSE. */
4617     pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
4618     if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
4619         (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4620         pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
4621     {
4622         pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
4623         pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
4624
4625     }
4626     REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
4627
4628     /* Enable/disable tx PAUSE. */
4629     pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
4630     if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
4631         (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4632         pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
4633     {
4634         pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4635         pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
4636
4637     }
4638     REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
4639
4640     return LM_STATUS_SUCCESS;
4641 }
4642
4643
4644 #if INCLUDE_TBI_SUPPORT
4645 /******************************************************************************/
4646 /* Description:                                                               */
4647 /*                                                                            */
4648 /* Return:                                                                    */
4649 /******************************************************************************/
4650 STATIC LM_STATUS
4651 LM_InitBcm800xPhy(
4652     PLM_DEVICE_BLOCK pDevice)
4653 {
4654     LM_UINT32 Value32;
4655     LM_UINT32 j;
4656
4657     Value32 = REG_RD(pDevice, MacCtrl.Status);
4658
4659     /* Reset the SERDES during init and when we have link. */
4660     if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
4661     {
4662         /* Set PLL lock range. */
4663         LM_WritePhy(pDevice, 0x16, 0x8007);
4664
4665         /* Software reset. */
4666         LM_WritePhy(pDevice, 0x00, 0x8000);
4667
4668         /* Wait for reset to complete. */
4669         for(j = 0; j < 500; j++)
4670         {
4671             MM_Wait(10);
4672         }
4673
4674         /* Config mode; seletct PMA/Ch 1 regs. */
4675         LM_WritePhy(pDevice, 0x10, 0x8411);
4676
4677         /* Enable auto-lock and comdet, select txclk for tx. */
4678         LM_WritePhy(pDevice, 0x11, 0x0a10);
4679
4680         LM_WritePhy(pDevice, 0x18, 0x00a0);
4681         LM_WritePhy(pDevice, 0x16, 0x41ff);
4682
4683         /* Assert and deassert POR. */
4684         LM_WritePhy(pDevice, 0x13, 0x0400);
4685         MM_Wait(40);
4686         LM_WritePhy(pDevice, 0x13, 0x0000);
4687
4688         LM_WritePhy(pDevice, 0x11, 0x0a50);
4689         MM_Wait(40);
4690         LM_WritePhy(pDevice, 0x11, 0x0a10);
4691
4692         /* Delay for signal to stabilize. */
4693         for(j = 0; j < 15000; j++)
4694         {
4695             MM_Wait(10);
4696         }
4697
4698         /* Deselect the channel register so we can read the PHY id later. */
4699         LM_WritePhy(pDevice, 0x10, 0x8011);
4700     }
4701
4702     return LM_STATUS_SUCCESS;
4703 }
4704
4705
4706 /******************************************************************************/
4707 /* Description:                                                               */
4708 /*                                                                            */
4709 /* Return:                                                                    */
4710 /******************************************************************************/
4711 STATIC LM_STATUS
4712 LM_SetupFiberPhy(
4713     PLM_DEVICE_BLOCK pDevice)
4714 {
4715     LM_STATUS CurrentLinkStatus;
4716     AUTONEG_STATUS AnStatus = 0;
4717     LM_UINT32 Value32;
4718     LM_UINT32 Cnt;
4719     LM_UINT32 j, k;
4720
4721     pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
4722
4723     /* Initialize the send_config register. */
4724     REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
4725
4726     /* Enable TBI and full duplex mode. */
4727     pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
4728     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4729
4730     /* Initialize the BCM8002 SERDES PHY. */
4731     switch(pDevice->PhyId & PHY_ID_MASK)
4732     {
4733         case PHY_BCM8002_PHY_ID:
4734             LM_InitBcm800xPhy(pDevice);
4735             break;
4736
4737         default:
4738             break;
4739     }
4740
4741     /* Enable link change interrupt. */
4742     REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4743
4744     /* Default to link down. */
4745     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4746
4747     /* Get the link status. */
4748     Value32 = REG_RD(pDevice, MacCtrl.Status);
4749     if(Value32 & MAC_STATUS_PCS_SYNCED)
4750     {
4751         if((pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO) ||
4752             (pDevice->DisableAutoNeg == FALSE))
4753         {
4754             /* auto-negotiation mode. */
4755             /* Initialize the autoneg default capaiblities. */
4756             AutonegInit(&pDevice->AnInfo);
4757
4758             /* Set the context pointer to point to the main device structure. */
4759             pDevice->AnInfo.pContext = pDevice;
4760
4761             /* Setup flow control advertisement register. */
4762             Value32 = GetPhyAdFlowCntrlSettings(pDevice);
4763             if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
4764             {
4765                 pDevice->AnInfo.mr_adv_sym_pause = 1;
4766             }
4767             else
4768             {
4769                 pDevice->AnInfo.mr_adv_sym_pause = 0;
4770             }
4771
4772             if(Value32 & PHY_AN_AD_ASYM_PAUSE)
4773             {
4774                 pDevice->AnInfo.mr_adv_asym_pause = 1;
4775             }
4776             else
4777             {
4778                 pDevice->AnInfo.mr_adv_asym_pause = 0;
4779             }
4780
4781             /* Try to autoneg up to six times. */
4782             if (pDevice->IgnoreTbiLinkChange)
4783             {
4784                 Cnt = 1;
4785             }
4786             else
4787             {
4788                 Cnt = 6;
4789             }
4790             for (j = 0; j < Cnt; j++)
4791             {
4792                 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
4793
4794                 Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
4795                 REG_WR(pDevice, MacCtrl.Mode, Value32);
4796                 MM_Wait(20);
4797
4798                 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4799                     MAC_MODE_SEND_CONFIGS);
4800
4801                 MM_Wait(20);
4802
4803                 pDevice->AnInfo.State = AN_STATE_UNKNOWN;
4804                 pDevice->AnInfo.CurrentTime_us = 0;
4805
4806                 REG_WR(pDevice, Grc.Timer, 0);
4807                 for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
4808                     (k < 75000); k++)
4809                 {
4810                     AnStatus = Autoneg8023z(&pDevice->AnInfo);
4811
4812                     if((AnStatus == AUTONEG_STATUS_DONE) ||
4813                         (AnStatus == AUTONEG_STATUS_FAILED))
4814                     {
4815                         break;
4816                     }
4817
4818                     pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
4819
4820                 }
4821                 if((AnStatus == AUTONEG_STATUS_DONE) ||
4822                     (AnStatus == AUTONEG_STATUS_FAILED))
4823                 {
4824                     break;
4825                 }
4826                 if (j >= 1)
4827                 {
4828                     if (!(REG_RD(pDevice, MacCtrl.Status) &
4829                         MAC_STATUS_PCS_SYNCED)) {
4830                         break;
4831                     }
4832                 }
4833             }
4834
4835             /* Stop sending configs. */
4836             MM_AnTxIdle(&pDevice->AnInfo);
4837
4838             /* Resolve flow control settings. */
4839             if((AnStatus == AUTONEG_STATUS_DONE) &&
4840                 pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
4841                 pDevice->AnInfo.mr_lp_adv_full_duplex)
4842                 {
4843                 LM_UINT32 RemotePhyAd;
4844                 LM_UINT32 LocalPhyAd;
4845
4846                 LocalPhyAd = 0;
4847                 if(pDevice->AnInfo.mr_adv_sym_pause)
4848                 {
4849                     LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
4850                 }
4851
4852                 if(pDevice->AnInfo.mr_adv_asym_pause)
4853                 {
4854                     LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
4855                 }
4856
4857                 RemotePhyAd = 0;
4858                 if(pDevice->AnInfo.mr_lp_adv_sym_pause)
4859                 {
4860                     RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
4861                 }
4862
4863                 if(pDevice->AnInfo.mr_lp_adv_asym_pause)
4864                 {
4865                     RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
4866                 }
4867
4868                 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
4869
4870                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4871             }
4872             for (j = 0; j < 30; j++)
4873             {
4874                 MM_Wait(20);
4875                 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4876                     MAC_STATUS_CFG_CHANGED);
4877                 MM_Wait(20);
4878                 if ((REG_RD(pDevice, MacCtrl.Status) &
4879                     (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4880                     break;
4881             }
4882             if (pDevice->PollTbiLink)
4883             {
4884                 Value32 = REG_RD(pDevice, MacCtrl.Status);
4885                 if (Value32 & MAC_STATUS_RECEIVING_CFG)
4886                 {
4887                     pDevice->IgnoreTbiLinkChange = TRUE;
4888                 }
4889                 else
4890                 {
4891                     pDevice->IgnoreTbiLinkChange = FALSE;
4892                 }
4893             }
4894             Value32 = REG_RD(pDevice, MacCtrl.Status);
4895             if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
4896                  (Value32 & MAC_STATUS_PCS_SYNCED) &&
4897                  ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
4898             {
4899                 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4900             }
4901         }
4902         else
4903         {
4904             /* We are forcing line speed. */
4905             pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
4906             LM_SetFlowControl(pDevice, 0, 0);
4907
4908             CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4909             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4910                 MAC_MODE_SEND_CONFIGS);
4911         }
4912     }
4913     /* Set the link polarity bit. */
4914     pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4915     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4916
4917     pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4918         (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4919
4920     for (j = 0; j < 100; j++)
4921     {
4922         REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4923             MAC_STATUS_CFG_CHANGED);
4924         MM_Wait(5);
4925         if ((REG_RD(pDevice, MacCtrl.Status) &
4926             (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4927             break;
4928     }
4929
4930     Value32 = REG_RD(pDevice, MacCtrl.Status);
4931     if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
4932     {
4933         CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4934         if (pDevice->DisableAutoNeg == FALSE)
4935         {
4936             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4937                 MAC_MODE_SEND_CONFIGS);
4938             MM_Wait(1);
4939             REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4940         }
4941     }
4942
4943     /* Initialize the current link status. */
4944     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
4945     {
4946         pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
4947         pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
4948         REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4949             LED_CTRL_1000MBPS_LED_ON);
4950     }
4951     else
4952     {
4953         pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
4954         pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4955         REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4956             LED_CTRL_OVERRIDE_TRAFFIC_LED);
4957     }
4958
4959     /* Indicate link status. */
4960     if (pDevice->LinkStatus != CurrentLinkStatus) {
4961         pDevice->LinkStatus = CurrentLinkStatus;
4962         MM_IndicateStatus(pDevice, CurrentLinkStatus);
4963     }
4964
4965     return LM_STATUS_SUCCESS;
4966 }
4967 #endif /* INCLUDE_TBI_SUPPORT */
4968
4969
4970 /******************************************************************************/
4971 /* Description:                                                               */
4972 /*                                                                            */
4973 /* Return:                                                                    */
4974 /******************************************************************************/
4975 LM_STATUS
4976 LM_SetupCopperPhy(
4977     PLM_DEVICE_BLOCK pDevice)
4978 {
4979     LM_STATUS CurrentLinkStatus;
4980     LM_UINT32 Value32;
4981
4982     /* Assume there is not link first. */
4983     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4984
4985     /* Disable phy link change attention. */
4986     REG_WR(pDevice, MacCtrl.MacEvent, 0);
4987
4988     /* Clear link change attention. */
4989     REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4990         MAC_STATUS_CFG_CHANGED);
4991
4992     /* Disable auto-polling for the moment. */
4993     pDevice->MiMode = 0xc0000;
4994     REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
4995     MM_Wait(40);
4996
4997     /* Determine the requested line speed and duplex. */
4998     pDevice->OldLineSpeed = pDevice->LineSpeed;
4999     LM_TranslateRequestedMediaType(pDevice->RequestedMediaType,
5000         &pDevice->MediaType, &pDevice->LineSpeed, &pDevice->DuplexMode);
5001
5002     /* Initialize the phy chip. */
5003     switch(pDevice->PhyId & PHY_ID_MASK)
5004     {
5005         case PHY_BCM5400_PHY_ID:
5006         case PHY_BCM5401_PHY_ID:
5007         case PHY_BCM5411_PHY_ID:
5008         case PHY_BCM5701_PHY_ID:
5009         case PHY_BCM5703_PHY_ID:
5010         case PHY_BCM5704_PHY_ID:
5011             CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
5012             break;
5013
5014         default:
5015             break;
5016     }
5017
5018     if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
5019     {
5020         CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5021     }
5022
5023     /* Setup flow control. */
5024     pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5025     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5026     {
5027         LM_FLOW_CONTROL FlowCap;     /* Flow control capability. */
5028
5029         FlowCap = LM_FLOW_CONTROL_NONE;
5030
5031         if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
5032         {
5033             if(pDevice->DisableAutoNeg == FALSE ||
5034                 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5035                 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
5036             {
5037                 LM_UINT32 ExpectedPhyAd;
5038                 LM_UINT32 LocalPhyAd;
5039                 LM_UINT32 RemotePhyAd;
5040
5041                 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
5042                 pDevice->advertising = LocalPhyAd;
5043                 LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
5044
5045                 ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5046
5047                 if(LocalPhyAd != ExpectedPhyAd)
5048                 {
5049                     CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5050                 }
5051                 else
5052                 {
5053                     LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
5054                         &RemotePhyAd);
5055
5056                     LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5057                 }
5058             }
5059             else
5060             {
5061                 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5062                 LM_SetFlowControl(pDevice, 0, 0);
5063             }
5064         }
5065     }
5066
5067     if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
5068     {
5069         LM_ForceAutoNeg(pDevice, pDevice->RequestedMediaType);
5070
5071         /* If we force line speed, we make get link right away. */
5072         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5073         LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5074         if(Value32 & PHY_STATUS_LINK_PASS)
5075         {
5076             CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5077         }
5078     }
5079
5080     /* GMII interface. */
5081     pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
5082     if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5083     {
5084         if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
5085             pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
5086         {
5087             pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
5088         }
5089         else
5090         {
5091             pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5092         }
5093     }
5094     else {
5095         pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5096     }
5097
5098     /* Set the MAC to operate in the appropriate duplex mode. */
5099     pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
5100     if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
5101     {
5102         pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
5103     }
5104
5105     /* Set the link polarity bit. */
5106     pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5107     if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5108     {
5109         if((pDevice->LedMode == LED_MODE_LINK10) ||
5110              (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
5111              pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
5112         {
5113             pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5114         }
5115     }
5116     else
5117     {
5118         if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5119         {
5120             pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5121         }
5122
5123         /* Set LED mode. */
5124         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5125             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5126         {
5127             Value32 = LED_CTRL_PHY_MODE_1;
5128         }
5129         else
5130         {
5131             if(pDevice->LedMode == LED_MODE_OUTPUT)
5132             {
5133                 Value32 = LED_CTRL_PHY_MODE_2;
5134             }
5135             else
5136             {
5137                 Value32 = LED_CTRL_PHY_MODE_1;
5138             }
5139         }
5140         REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
5141     }
5142
5143     REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5144
5145     /* Enable auto polling. */
5146     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5147     {
5148         pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
5149         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5150     }
5151
5152     /* Enable phy link change attention. */
5153     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5154     {
5155         REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
5156     }
5157     else
5158     {
5159         REG_WR(pDevice, MacCtrl.MacEvent,
5160             MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5161     }
5162     if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
5163         (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
5164         (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
5165         (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
5166           (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
5167          !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
5168     {
5169         MM_Wait(120);
5170         REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5171             MAC_STATUS_CFG_CHANGED);
5172         MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
5173             T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
5174     }
5175
5176     /* Indicate link status. */
5177     if (pDevice->LinkStatus != CurrentLinkStatus) {
5178         pDevice->LinkStatus = CurrentLinkStatus;
5179         MM_IndicateStatus(pDevice, CurrentLinkStatus);
5180     }
5181
5182     return LM_STATUS_SUCCESS;
5183 } /* LM_SetupCopperPhy */
5184
5185 /******************************************************************************/
5186 /* Description:                                                               */
5187 /*                                                                            */
5188 /* Return:                                                                    */
5189 /******************************************************************************/
5190 LM_STATUS
5191 LM_SetupPhy(
5192     PLM_DEVICE_BLOCK pDevice)
5193 {
5194     LM_STATUS LmStatus;
5195     LM_UINT32 Value32;
5196
5197 #if INCLUDE_TBI_SUPPORT
5198     if(pDevice->EnableTbi)
5199     {
5200         LmStatus = LM_SetupFiberPhy(pDevice);
5201     }
5202     else
5203 #endif /* INCLUDE_TBI_SUPPORT */
5204     {
5205         LmStatus = LM_SetupCopperPhy(pDevice);
5206     }
5207     if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
5208     {
5209         if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
5210         {
5211             Value32 = REG_RD(pDevice, PciCfg.PciState);
5212             REG_WR(pDevice, PciCfg.PciState,
5213                 Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
5214         }
5215     }
5216     if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
5217         (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
5218     {
5219         REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
5220     }
5221     else
5222     {
5223         REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
5224     }
5225
5226     return LmStatus;
5227 }
5228
5229 /******************************************************************************/
5230 /* Description:                                                               */
5231 /*                                                                            */
5232 /* Return:                                                                    */
5233 /******************************************************************************/
5234 LM_VOID
5235 LM_ReadPhy(
5236 PLM_DEVICE_BLOCK pDevice,
5237 LM_UINT32 PhyReg,
5238 PLM_UINT32 pData32) {
5239     LM_UINT32 Value32;
5240     LM_UINT32 j;
5241
5242     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5243     {
5244         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
5245             ~MI_MODE_AUTO_POLLING_ENABLE);
5246         MM_Wait(40);
5247     }
5248
5249     Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
5250         ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
5251         MI_COM_CMD_READ | MI_COM_START;
5252
5253     REG_WR(pDevice, MacCtrl.MiCom, Value32);
5254
5255     for(j = 0; j < 20; j++)
5256     {
5257         MM_Wait(25);
5258
5259         Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5260
5261         if(!(Value32 & MI_COM_BUSY))
5262         {
5263             MM_Wait(5);
5264             Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5265             Value32 &= MI_COM_PHY_DATA_MASK;
5266             break;
5267         }
5268     }
5269
5270     if(Value32 & MI_COM_BUSY)
5271     {
5272         Value32 = 0;
5273     }
5274
5275     *pData32 = Value32;
5276
5277     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5278     {
5279         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5280         MM_Wait(40);
5281     }
5282 } /* LM_ReadPhy */
5283
5284
5285 /******************************************************************************/
5286 /* Description:                                                               */
5287 /*                                                                            */
5288 /* Return:                                                                    */
5289 /******************************************************************************/
5290 LM_VOID
5291 LM_WritePhy(
5292 PLM_DEVICE_BLOCK pDevice,
5293 LM_UINT32 PhyReg,
5294 LM_UINT32 Data32) {
5295     LM_UINT32 Value32;
5296     LM_UINT32 j;
5297
5298     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5299     {
5300         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
5301             ~MI_MODE_AUTO_POLLING_ENABLE);
5302         MM_Wait(40);
5303     }
5304
5305     Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
5306         ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
5307         (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
5308
5309     REG_WR(pDevice, MacCtrl.MiCom, Value32);
5310
5311     for(j = 0; j < 20; j++)
5312     {
5313         MM_Wait(25);
5314
5315         Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5316
5317         if(!(Value32 & MI_COM_BUSY))
5318         {
5319             MM_Wait(5);
5320             break;
5321         }
5322     }
5323
5324     if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5325     {
5326         REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5327         MM_Wait(40);
5328     }
5329 } /* LM_WritePhy */
5330
5331
5332 /******************************************************************************/
5333 /* Description:                                                               */
5334 /*                                                                            */
5335 /* Return:                                                                    */
5336 /******************************************************************************/
5337 LM_STATUS
5338 LM_SetPowerState(
5339 PLM_DEVICE_BLOCK pDevice,
5340 LM_POWER_STATE PowerLevel) {
5341     LM_UINT32 PmeSupport;
5342     LM_UINT32 Value32;
5343     LM_UINT32 PmCtrl;
5344
5345     /* make sureindirect accesses are enabled*/
5346     MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
5347
5348     /* Clear the PME_ASSERT bit and the power state bits.  Also enable */
5349     /* the PME bit. */
5350     MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
5351
5352     PmCtrl |= T3_PM_PME_ASSERTED;
5353     PmCtrl &= ~T3_PM_POWER_STATE_MASK;
5354
5355     /* Set the appropriate power state. */
5356     if(PowerLevel == LM_POWER_STATE_D0)
5357     {
5358
5359         /* Bring the card out of low power mode. */
5360         PmCtrl |= T3_PM_POWER_STATE_D0;
5361         MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5362
5363         REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
5364         MM_Wait (40);
5365 #if 0   /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
5366         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
5367 #endif
5368
5369         return LM_STATUS_SUCCESS;
5370     }
5371     else if(PowerLevel == LM_POWER_STATE_D1)
5372     {
5373         PmCtrl |= T3_PM_POWER_STATE_D1;
5374     }
5375     else if(PowerLevel == LM_POWER_STATE_D2)
5376     {
5377         PmCtrl |= T3_PM_POWER_STATE_D2;
5378     }
5379     else if(PowerLevel == LM_POWER_STATE_D3)
5380     {
5381         PmCtrl |= T3_PM_POWER_STATE_D3;
5382     }
5383     else
5384     {
5385         return LM_STATUS_FAILURE;
5386     }
5387     PmCtrl |= T3_PM_PME_ENABLE;
5388
5389     /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
5390     /* setting new line speed. */
5391     Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
5392     REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
5393
5394     if(!pDevice->RestoreOnWakeUp)
5395     {
5396         pDevice->RestoreOnWakeUp = TRUE;
5397         pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
5398         pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
5399     }
5400
5401     /* Force auto-negotiation to 10 line speed. */
5402     pDevice->DisableAutoNeg = FALSE;
5403     pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
5404     LM_SetupPhy(pDevice);
5405
5406     /* Put the driver in the initial state, and go through the power down */
5407     /* sequence. */
5408     LM_Halt(pDevice);
5409
5410     MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
5411
5412     if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
5413     {
5414
5415         /* Enable WOL. */
5416         LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
5417         MM_Wait(40);
5418
5419         /* Set LED mode. */
5420         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5421             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5422         {
5423             Value32 = LED_CTRL_PHY_MODE_1;
5424         }
5425         else
5426         {
5427             if(pDevice->LedMode == LED_MODE_OUTPUT)
5428             {
5429                 Value32 = LED_CTRL_PHY_MODE_2;
5430             }
5431             else
5432             {
5433                 Value32 = LED_CTRL_PHY_MODE_1;
5434             }
5435         }
5436
5437         Value32 = MAC_MODE_PORT_MODE_MII;
5438         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5439         {
5440             if(pDevice->LedMode == LED_MODE_LINK10 ||
5441                 pDevice->WolSpeed == WOL_SPEED_10MB)
5442             {
5443                 Value32 |= MAC_MODE_LINK_POLARITY;
5444             }
5445         }
5446         else
5447         {
5448             Value32 |= MAC_MODE_LINK_POLARITY;
5449         }
5450         REG_WR(pDevice, MacCtrl.Mode, Value32);
5451         MM_Wait(40); MM_Wait(40); MM_Wait(40);
5452
5453         /* Always enable magic packet wake-up if we have vaux. */
5454         if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
5455             (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
5456         {
5457             Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
5458         }
5459
5460         REG_WR(pDevice, MacCtrl.Mode, Value32);
5461
5462         /* Enable the receiver. */
5463         REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
5464     }
5465
5466     /* Disable tx/rx clocks, and seletect an alternate clock. */
5467     if(pDevice->WolSpeed == WOL_SPEED_100MB)
5468     {
5469         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5470             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5471         {
5472             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5473                 T3_PCI_SELECT_ALTERNATE_CLOCK;
5474         }
5475         else
5476         {
5477             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
5478         }
5479         REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5480
5481         MM_Wait(40);
5482
5483         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5484             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5485         {
5486             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5487                 T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
5488         }
5489         else
5490         {
5491             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5492                 T3_PCI_44MHZ_CORE_CLOCK;
5493         }
5494
5495         REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5496
5497         MM_Wait(40);
5498
5499         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5500             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5501         {
5502             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5503                 T3_PCI_44MHZ_CORE_CLOCK;
5504         }
5505         else
5506         {
5507             Value32 = T3_PCI_44MHZ_CORE_CLOCK;
5508         }
5509
5510         REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5511     }
5512     else
5513     {
5514         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5515             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5516         {
5517             Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5518                 T3_PCI_SELECT_ALTERNATE_CLOCK |
5519                 T3_PCI_POWER_DOWN_PCI_PLL133;
5520         }
5521         else
5522         {
5523             Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5524                 T3_PCI_POWER_DOWN_PCI_PLL133;
5525         }
5526
5527         REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5528     }
5529
5530     MM_Wait(40);
5531
5532     if(!pDevice->EepromWp && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE))
5533     {
5534         /* Switch adapter to auxilliary power. */
5535         if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5536             T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5537         {
5538             /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5539             REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5540                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5541                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5542                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5543                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5544                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5545                 MM_Wait(40);
5546         }
5547         else
5548         {
5549             /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
5550             REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5551                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5552                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5553                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5554                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5555                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5556                 MM_Wait(40);
5557
5558             /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
5559             REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5560                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5561                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5562                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5563                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5564                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5565                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5566                 MM_Wait(40);
5567
5568             /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5569             REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5570                 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5571                 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5572                 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5573                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5574                 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5575                 MM_Wait(40);
5576         }
5577     }
5578
5579     /* Set the phy to low power mode. */
5580     /* Put the the hardware in low power mode. */
5581     MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5582
5583     return LM_STATUS_SUCCESS;
5584 } /* LM_SetPowerState */
5585
5586
5587 /******************************************************************************/
5588 /* Description:                                                               */
5589 /*                                                                            */
5590 /* Return:                                                                    */
5591 /******************************************************************************/
5592 static LM_UINT32
5593 GetPhyAdFlowCntrlSettings(
5594     PLM_DEVICE_BLOCK pDevice)
5595 {
5596     LM_UINT32 Value32;
5597
5598     Value32 = 0;
5599
5600     /* Auto negotiation flow control only when autonegotiation is enabled. */
5601     if(pDevice->DisableAutoNeg == FALSE ||
5602         pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5603         pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
5604     {
5605         /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
5606         if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
5607             ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
5608             (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
5609         {
5610             Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
5611         }
5612         else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
5613         {
5614             Value32 |= PHY_AN_AD_ASYM_PAUSE;
5615         }
5616         else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
5617         {
5618             Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
5619         }
5620     }
5621
5622     return Value32;
5623 }
5624
5625
5626 /******************************************************************************/
5627 /* Description:                                                               */
5628 /*                                                                            */
5629 /* Return:                                                                    */
5630 /*    LM_STATUS_FAILURE                                                       */
5631 /*    LM_STATUS_SUCCESS                                                       */
5632 /*                                                                            */
5633 /******************************************************************************/
5634 static LM_STATUS
5635 LM_ForceAutoNegBcm540xPhy(
5636 PLM_DEVICE_BLOCK pDevice,
5637 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5638 {
5639     LM_MEDIA_TYPE MediaType;
5640     LM_LINE_SPEED LineSpeed;
5641     LM_DUPLEX_MODE DuplexMode;
5642     LM_UINT32 NewPhyCtrl;
5643     LM_UINT32 Value32;
5644     LM_UINT32 Cnt;
5645
5646     /* Get the interface type, line speed, and duplex mode. */
5647     LM_TranslateRequestedMediaType(RequestedMediaType, &MediaType, &LineSpeed,
5648         &DuplexMode);
5649
5650     if (pDevice->RestoreOnWakeUp)
5651     {
5652         LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5653         pDevice->advertising1000 = 0;
5654         Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
5655         if (pDevice->WolSpeed == WOL_SPEED_100MB)
5656         {
5657             Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5658         }
5659         Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5660         Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5661         LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5662         pDevice->advertising = Value32;
5663     }
5664     /* Setup the auto-negotiation advertisement register. */
5665     else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
5666     {
5667         /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
5668         Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
5669             PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
5670             PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5671         Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5672
5673         LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5674         pDevice->advertising = Value32;
5675
5676         /* Advertise 1000Mbps */
5677         Value32 = BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
5678
5679 #if INCLUDE_5701_AX_FIX
5680         /* Bug: workaround for CRC error in gigabit mode when we are in */
5681         /* slave mode.  This will force the PHY to operate in */
5682         /* master mode. */
5683         if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5684             pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
5685         {
5686             Value32 |= BCM540X_CONFIG_AS_MASTER |
5687                 BCM540X_ENABLE_CONFIG_AS_MASTER;
5688         }
5689 #endif
5690
5691         LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5692         pDevice->advertising1000 = Value32;
5693     }
5694     else
5695     {
5696         if(LineSpeed == LM_LINE_SPEED_1000MBPS)
5697         {
5698             Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5699             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5700
5701             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5702             pDevice->advertising = Value32;
5703
5704             if(DuplexMode != LM_DUPLEX_MODE_FULL)
5705             {
5706                 Value32 = BCM540X_AN_AD_1000BASET_HALF;
5707             }
5708             else
5709             {
5710                 Value32 = BCM540X_AN_AD_1000BASET_FULL;
5711             }
5712
5713             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5714             pDevice->advertising1000 = Value32;
5715         }
5716         else if(LineSpeed == LM_LINE_SPEED_100MBPS)
5717         {
5718             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5719             pDevice->advertising1000 = 0;
5720
5721             if(DuplexMode != LM_DUPLEX_MODE_FULL)
5722             {
5723                 Value32 = PHY_AN_AD_100BASETX_HALF;
5724             }
5725             else
5726             {
5727                 Value32 = PHY_AN_AD_100BASETX_FULL;
5728             }
5729
5730             Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5731             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5732
5733             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5734             pDevice->advertising = Value32;
5735         }
5736         else if(LineSpeed == LM_LINE_SPEED_10MBPS)
5737         {
5738             LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5739             pDevice->advertising1000 = 0;
5740
5741             if(DuplexMode != LM_DUPLEX_MODE_FULL)
5742             {
5743                 Value32 = PHY_AN_AD_10BASET_HALF;
5744             }
5745             else
5746             {
5747                 Value32 = PHY_AN_AD_10BASET_FULL;
5748             }
5749
5750             Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5751             Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5752
5753             LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5754             pDevice->advertising = Value32;
5755         }
5756     }
5757
5758     /* Force line speed if auto-negotiation is disabled. */
5759     if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
5760     {
5761         /* This code path is executed only when there is link. */
5762         pDevice->MediaType = MediaType;
5763         pDevice->LineSpeed = LineSpeed;
5764         pDevice->DuplexMode = DuplexMode;
5765
5766         /* Force line seepd. */
5767         NewPhyCtrl = 0;
5768         switch(LineSpeed)
5769         {
5770             case LM_LINE_SPEED_10MBPS:
5771                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
5772                 break;
5773             case LM_LINE_SPEED_100MBPS:
5774                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
5775                 break;
5776             case LM_LINE_SPEED_1000MBPS:
5777                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5778                 break;
5779             default:
5780                 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5781                 break;
5782         }
5783
5784         if(DuplexMode == LM_DUPLEX_MODE_FULL)
5785         {
5786             NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
5787         }
5788
5789         /* Don't do anything if the PHY_CTRL is already what we wanted. */
5790         LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5791         if(Value32 != NewPhyCtrl)
5792         {
5793             /* Temporary bring the link down before forcing line speed. */
5794             LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
5795
5796             /* Wait for link to go down. */
5797             for(Cnt = 0; Cnt < 15000; Cnt++)
5798             {
5799                 MM_Wait(10);
5800
5801                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5802                 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5803
5804                 if(!(Value32 & PHY_STATUS_LINK_PASS))
5805                 {
5806                     MM_Wait(40);
5807                     break;
5808                 }
5809             }
5810
5811             LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
5812             MM_Wait(40);
5813         }
5814     }
5815     else
5816     {
5817         LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
5818             PHY_CTRL_RESTART_AUTO_NEG);
5819     }
5820
5821     return LM_STATUS_SUCCESS;
5822 } /* LM_ForceAutoNegBcm540xPhy */
5823
5824
5825 /******************************************************************************/
5826 /* Description:                                                               */
5827 /*                                                                            */
5828 /* Return:                                                                    */
5829 /******************************************************************************/
5830 static LM_STATUS
5831 LM_ForceAutoNeg(
5832 PLM_DEVICE_BLOCK pDevice,
5833 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5834 {
5835     LM_STATUS LmStatus;
5836
5837     /* Initialize the phy chip. */
5838     switch(pDevice->PhyId & PHY_ID_MASK)
5839     {
5840         case PHY_BCM5400_PHY_ID:
5841         case PHY_BCM5401_PHY_ID:
5842         case PHY_BCM5411_PHY_ID:
5843         case PHY_BCM5701_PHY_ID:
5844         case PHY_BCM5703_PHY_ID:
5845         case PHY_BCM5704_PHY_ID:
5846             LmStatus = LM_ForceAutoNegBcm540xPhy(pDevice, RequestedMediaType);
5847             break;
5848
5849         default:
5850             LmStatus = LM_STATUS_FAILURE;
5851             break;
5852     }
5853
5854     return LmStatus;
5855 } /* LM_ForceAutoNeg */
5856
5857 /******************************************************************************/
5858 /* Description:                                                               */
5859 /*                                                                            */
5860 /* Return:                                                                    */
5861 /******************************************************************************/
5862 LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
5863                           PT3_FWIMG_INFO pFwImg,
5864                           LM_UINT32 LoadCpu,
5865                           LM_UINT32 StartCpu)
5866 {
5867     LM_UINT32 i;
5868     LM_UINT32 address;
5869
5870     if (LoadCpu & T3_RX_CPU_ID)
5871     {
5872         if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
5873         {
5874             return LM_STATUS_FAILURE;
5875         }
5876
5877         /* First of all clear scrach pad memory */
5878         for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i+=4)
5879         {
5880             LM_RegWrInd(pDevice,T3_RX_CPU_SPAD_ADDR+i,0);
5881         }
5882
5883         /* Copy code first */
5884         address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5885         for (i = 0; i <= pFwImg->Text.Length; i+=4)
5886         {
5887             LM_RegWrInd(pDevice,address+i,
5888                         ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
5889         }
5890
5891         address = T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5892         for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
5893         {
5894             LM_RegWrInd(pDevice,address+i,
5895                         ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
5896         }
5897
5898         address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5899         for (i= 0; i <= pFwImg->Data.Length; i+=4)
5900         {
5901             LM_RegWrInd(pDevice,address+i,
5902                         ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
5903         }
5904     }
5905
5906     if (LoadCpu & T3_TX_CPU_ID)
5907     {
5908         if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
5909         {
5910             return LM_STATUS_FAILURE;
5911         }
5912
5913         /* First of all clear scrach pad memory */
5914         for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
5915         {
5916             LM_RegWrInd(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
5917         }
5918
5919         /* Copy code first */
5920         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5921         for (i= 0; i <= pFwImg->Text.Length; i+=4)
5922         {
5923             LM_RegWrInd(pDevice,address+i,
5924                         ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
5925         }
5926
5927         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5928         for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
5929         {
5930             LM_RegWrInd(pDevice,address+i,
5931                         ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
5932         }
5933
5934         address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5935         for (i= 0; i <= pFwImg->Data.Length; i+=4)
5936         {
5937             LM_RegWrInd(pDevice,address+i,
5938                         ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
5939         }
5940     }
5941
5942     if (StartCpu & T3_RX_CPU_ID)
5943     {
5944         /* Start Rx CPU */
5945         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5946         REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
5947         for (i = 0 ; i < 5; i++)
5948         {
5949           if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
5950              break;
5951
5952           REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5953           REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
5954           REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
5955           MM_Wait(1000);
5956         }
5957
5958         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5959         REG_WR(pDevice,rxCpu.reg.mode, 0);
5960     }
5961
5962     if (StartCpu & T3_TX_CPU_ID)
5963     {
5964         /* Start Tx CPU */
5965         REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
5966         REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
5967         for (i = 0 ; i < 5; i++)
5968         {
5969           if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
5970              break;
5971
5972           REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
5973           REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
5974           REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
5975           MM_Wait(1000);
5976         }
5977
5978         REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
5979         REG_WR(pDevice,txCpu.reg.mode, 0);
5980     }
5981
5982     return LM_STATUS_SUCCESS;
5983 }
5984
5985 STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
5986 {
5987     LM_UINT32 i;
5988
5989     if (cpu_number == T3_RX_CPU_ID)
5990     {
5991         for (i = 0 ; i < 10000; i++)
5992         {
5993             REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5994             REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
5995
5996             if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
5997               break;
5998         }
5999
6000         REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
6001         REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
6002         MM_Wait(10);
6003     }
6004     else
6005     {
6006         for (i = 0 ; i < 10000; i++)
6007         {
6008             REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
6009             REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
6010
6011             if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
6012                break;
6013         }
6014     }
6015
6016   return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
6017 }
6018
6019
6020 int
6021 LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
6022 {
6023         LM_UINT32 Oldcfg;
6024         int j;
6025         int ret = 0;
6026
6027         if(BlinkDurationSec == 0)
6028         {
6029                 return 0;
6030         }
6031         if(BlinkDurationSec > 120)
6032         {
6033                 BlinkDurationSec = 120;
6034         }
6035
6036         Oldcfg = REG_RD(pDevice, MacCtrl.LedCtrl);
6037         for(j = 0; j < BlinkDurationSec * 2; j++)
6038         {
6039                 if(j % 2)
6040                 {
6041                         /* Turn on the LEDs. */
6042                         REG_WR(pDevice, MacCtrl.LedCtrl,
6043                                 LED_CTRL_OVERRIDE_LINK_LED |
6044                                 LED_CTRL_1000MBPS_LED_ON |
6045                                 LED_CTRL_100MBPS_LED_ON |
6046                                 LED_CTRL_10MBPS_LED_ON |
6047                                 LED_CTRL_OVERRIDE_TRAFFIC_LED |
6048                                 LED_CTRL_BLINK_TRAFFIC_LED |
6049                                 LED_CTRL_TRAFFIC_LED);
6050                 }
6051                 else
6052                 {
6053                         /* Turn off the LEDs. */
6054                         REG_WR(pDevice, MacCtrl.LedCtrl,
6055                                 LED_CTRL_OVERRIDE_LINK_LED |
6056                                 LED_CTRL_OVERRIDE_TRAFFIC_LED);
6057                 }
6058
6059 #ifndef EMBEDDED
6060                 current->state = TASK_INTERRUPTIBLE;
6061                 if (schedule_timeout(HZ/2) != 0) {
6062                         ret = -EINTR;
6063                         break;
6064                 }
6065 #else
6066                 udelay(100000);  /* 1s sleep */
6067 #endif
6068         }
6069         REG_WR(pDevice, MacCtrl.LedCtrl, Oldcfg);
6070         return ret;
6071 }
6072
6073 int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
6074                    LM_PHYSICAL_ADDRESS host_addr_phy, int length,
6075                    int dma_read)
6076 {
6077     T3_DMA_DESC dma_desc;
6078     int i;
6079     LM_UINT32 dma_desc_addr;
6080     LM_UINT32 value32;
6081
6082     REG_WR(pDevice, BufMgr.Mode, 0);
6083     REG_WR(pDevice, Ftq.Reset, 0);
6084
6085     dma_desc.host_addr.High = host_addr_phy.High;
6086     dma_desc.host_addr.Low = host_addr_phy.Low;
6087     dma_desc.nic_mbuf = 0x2100;
6088     dma_desc.len = length;
6089     dma_desc.flags = 0x00000004; /* Generate Rx-CPU event */
6090
6091     if (dma_read)
6092     {
6093         dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
6094             T3_QID_DMA_HIGH_PRI_READ;
6095         REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
6096     }
6097     else
6098     {
6099         dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
6100             T3_QID_DMA_HIGH_PRI_WRITE;
6101         REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
6102     }
6103
6104     dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
6105
6106     /* Writing this DMA descriptor to DMA memory */
6107     for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
6108     {
6109         value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
6110         MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
6111         MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, cpu_to_le32(value32));
6112     }
6113     MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
6114
6115     if (dma_read)
6116         REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
6117     else
6118         REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
6119
6120     for (i = 0; i < 40; i++)
6121     {
6122         if (dma_read)
6123             value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
6124         else
6125             value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
6126
6127         if ((value32 & 0xffff) == dma_desc_addr)
6128             break;
6129
6130         MM_Wait(10);
6131     }
6132
6133     return LM_STATUS_SUCCESS;
6134 }
6135
6136 STATIC LM_STATUS
6137 LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
6138            LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
6139 {
6140     int j;
6141     LM_UINT32 *ptr;
6142     int dma_success = 0;
6143
6144     if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
6145         T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
6146     {
6147         return LM_STATUS_SUCCESS;
6148     }
6149     while (!dma_success)
6150     {
6151         /* Fill data with incremental patterns */
6152         ptr = (LM_UINT32 *)pBufferVirt;
6153         for (j = 0; j < BufferSize/4; j++)
6154             *ptr++ = j;
6155
6156         if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
6157         {
6158             return LM_STATUS_FAILURE;
6159         }
6160
6161         MM_Wait(40);
6162         ptr = (LM_UINT32 *)pBufferVirt;
6163         /* Fill data with zero */
6164         for (j = 0; j < BufferSize/4; j++)
6165             *ptr++ = 0;
6166
6167         if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
6168         {
6169             return LM_STATUS_FAILURE;
6170         }
6171
6172         MM_Wait(40);
6173         /* Check for data */
6174         ptr = (LM_UINT32 *)pBufferVirt;
6175         for (j = 0; j < BufferSize/4; j++)
6176         {
6177             if (*ptr++ != j)
6178             {
6179                 if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
6180                     == DMA_CTRL_WRITE_BOUNDARY_DISABLE)
6181                 {
6182                     pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
6183                          ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
6184                           DMA_CTRL_WRITE_BOUNDARY_16;
6185                     REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
6186                            pDevice->DmaReadWriteCtrl);
6187                     break;
6188                  }
6189                  else
6190                  {
6191                      return LM_STATUS_FAILURE;
6192                  }
6193             }
6194         }
6195         if (j == (BufferSize/4))
6196             dma_success = 1;
6197     }
6198     return LM_STATUS_SUCCESS;
6199 }
6200 #endif /* CFG_CMD_NET, !CONFIG_NET_MULTI, CONFIG_TIGON3 */