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