blob: c20dbe5cd1fcac3ef18f394e9ddf6de48b689f4f [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/******************************************************************************/
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>
wdenkc6097192002-11-03 00:24:07 +000014#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>
wdenk4fc95692003-02-28 00:49:47 +000022#include "bcm570x_mm.h"
wdenkc6097192002-11-03 00:24:07 +000023
24#define EMBEDDED 1
25/******************************************************************************/
26/* Local functions. */
27/******************************************************************************/
28
29LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
30LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
31
32static 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
37static 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
42static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,
43 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
44static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,
45 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
46static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
47STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
48 LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
49#if INCLUDE_TBI_SUPPORT
50STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
51STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
52#endif
53STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
54STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
55STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
56 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
57STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
58STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
59STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
60 PT3_SND_BD pSendBd);
61
62/******************************************************************************/
63/* External functions. */
64/******************************************************************************/
65
66LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
67
68
69/******************************************************************************/
70/* Description: */
71/* */
72/* Return: */
73/******************************************************************************/
74LM_UINT32
75LM_RegRdInd(
76PLM_DEVICE_BLOCK pDevice,
77LM_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/******************************************************************************/
99LM_VOID
100LM_RegWrInd(
101PLM_DEVICE_BLOCK pDevice,
102LM_UINT32 Register,
103LM_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/******************************************************************************/
122LM_UINT32
123LM_MemRdInd(
124PLM_DEVICE_BLOCK pDevice,
125LM_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/******************************************************************************/
149LM_VOID
150LM_MemWrInd(
151PLM_DEVICE_BLOCK pDevice,
152LM_UINT32 MemAddr,
153LM_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/******************************************************************************/
172LM_STATUS
173LM_QueueRxPackets(
174PLM_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/******************************************************************************/
277STATIC LM_VOID
278LM_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/******************************************************************************/
319STATIC LM_STATUS
320LM_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/******************************************************************************/
372STATIC LM_STATUS
373LM_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
471STATIC void
472LM_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
533STATIC void
534LM_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
596STATIC void
597LM_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/******************************************************************************/
668LM_STATUS
669LM_GetAdapterInfo(
670PLM_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
1588STATIC PLM_ADAPTER_INFO
1589LM_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/******************************************************************************/
1646LM_STATUS
1647LM_InitializeAdapter(
1648PLM_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/******************************************************************************/
1886LM_STATUS
1887LM_CntrlBlock(
1888PLM_DEVICE_BLOCK pDevice,
1889LM_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/******************************************************************************/
2304LM_STATUS
2305LM_ResetAdapter(
2306PLM_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/******************************************************************************/
2988LM_STATUS
2989LM_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/******************************************************************************/
3008LM_STATUS
3009LM_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
3038LM_STATUS
3039LM_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
3169LM_STATUS
3170LM_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
3305STATIC LM_STATUS
3306LM_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
3346ComputeCrc32(
3347unsigned char *pBuffer,
3348unsigned 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/******************************************************************************/
3384LM_STATUS
3385LM_SetReceiveMask(
3386PLM_DEVICE_BLOCK pDevice,
3387LM_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/******************************************************************************/
3538LM_STATUS
3539LM_Abort(
3540PLM_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/******************************************************************************/
3681LM_STATUS
3682LM_Halt(
3683PLM_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
3719STATIC LM_STATUS
3720LM_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
3823LM_ServiceTxInterrupt(
3824PLM_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
3874LM_ServiceRxInterrupt(
3875PLM_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/******************************************************************************/
3988LM_STATUS
3989LM_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/******************************************************************************/
4059LM_STATUS
4060LM_MulticastAdd(
4061PLM_DEVICE_BLOCK pDevice,
4062PLM_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/******************************************************************************/
4104LM_STATUS
4105LM_MulticastDel(
4106PLM_DEVICE_BLOCK pDevice,
4107PLM_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/******************************************************************************/
4156LM_STATUS
4157LM_MulticastClear(
4158PLM_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/******************************************************************************/
4173LM_STATUS
4174LM_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/******************************************************************************/
4201static LM_STATUS
4202LM_TranslateRequestedMediaType(
4203LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
4204PLM_MEDIA_TYPE pMediaType,
4205PLM_LINE_SPEED pLineSpeed,
4206PLM_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/******************************************************************************/
4297static LM_STATUS
4298LM_InitBcm540xPhy(
4299PLM_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/******************************************************************************/
4582LM_STATUS
4583LM_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/******************************************************************************/
4667STATIC LM_STATUS
4668LM_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/******************************************************************************/
4729STATIC LM_STATUS
4730LM_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/******************************************************************************/
4993LM_STATUS
4994LM_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/******************************************************************************/
5208LM_STATUS
5209LM_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/******************************************************************************/
5252LM_VOID
5253LM_ReadPhy(
5254PLM_DEVICE_BLOCK pDevice,
5255LM_UINT32 PhyReg,
5256PLM_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/******************************************************************************/
5309LM_VOID
5310LM_WritePhy(
5311PLM_DEVICE_BLOCK pDevice,
5312LM_UINT32 PhyReg,
5313LM_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/******************************************************************************/
5356LM_STATUS
5357LM_SetPowerState(
5358PLM_DEVICE_BLOCK pDevice,
5359LM_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/******************************************************************************/
5612static LM_UINT32
5613GetPhyAdFlowCntrlSettings(
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/******************************************************************************/
5655static LM_STATUS
5656LM_ForceAutoNegBcm540xPhy(
5657PLM_DEVICE_BLOCK pDevice,
5658LM_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/******************************************************************************/
5852static LM_STATUS
5853LM_ForceAutoNeg(
5854PLM_DEVICE_BLOCK pDevice,
5855LM_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/******************************************************************************/
5884LM_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
6007STATIC 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
6042int
6043LM_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
6095int 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
6158STATIC LM_STATUS
6159LM_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 */