BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / network / bcm570x / tigon3.c
blobc669848bbcaa17720b81b737d58f92e70ea5662f
1 /******************************************************************************/
2 /* */
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 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 /******************************************************************************/
14 #include "mm.h"
18 /******************************************************************************/
19 /* Local functions. */
20 /******************************************************************************/
22 LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
23 LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
25 static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
26 static LM_VOID LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice);
28 LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
29 LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
31 static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice);
32 static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
33 STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
34 LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
35 #if INCLUDE_TBI_SUPPORT
36 STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
37 STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
38 #endif
39 STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
40 STATIC LM_VOID LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice);
41 STATIC LM_STATUS LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice);
42 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
43 LM_VOID LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2);
44 STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
45 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
46 STATIC LM_STATUS LM_DisableChip(PLM_DEVICE_BLOCK pDevice);
47 STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
48 STATIC LM_STATUS LM_DisableFW(PLM_DEVICE_BLOCK pDevice);
49 STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
50 PT3_SND_BD pSendBd);
51 STATIC LM_VOID LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice,
52 LM_RESET_TYPE Mode);
53 STATIC LM_VOID LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice,
54 LM_RESET_TYPE Mode);
55 STATIC LM_VOID LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice,
56 LM_RESET_TYPE Mode);
57 STATIC void LM_GetPhyId(LM_DEVICE_BLOCK *pDevice);
59 /******************************************************************************/
60 /* External functions. */
61 /******************************************************************************/
63 LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
64 #if INCLUDE_TCP_SEG_SUPPORT
65 LM_STATUS LM_LoadStkOffLdFirmware(PLM_DEVICE_BLOCK pDevice);
66 LM_UINT32 LM_GetStkOffLdFirmwareSize(PLM_DEVICE_BLOCK pDevice);
67 #endif
69 LM_UINT32
70 LM_RegRd(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
72 #if PCIX_TARGET_WORKAROUND
73 if (pDevice->Flags & UNDI_FIX_FLAG)
75 return (LM_RegRdInd(pDevice, Register));
77 else
78 #endif
80 return (REG_RD_OFFSET(pDevice, Register));
84 /* Mainly used to flush posted write before delaying */
85 LM_VOID
86 LM_RegRdBack(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register)
88 LM_UINT32 dummy;
90 #if PCIX_TARGET_WORKAROUND
91 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
93 return;
95 else
96 #endif
98 if (pDevice->Flags & REG_RD_BACK_FLAG)
99 return;
101 dummy = REG_RD_OFFSET(pDevice, Register);
105 LM_VOID
106 LM_RegWr(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Register, LM_UINT32 Value32,
107 LM_UINT32 ReadBack)
109 #if PCIX_TARGET_WORKAROUND
110 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG)
112 LM_RegWrInd(pDevice, Register, Value32);
114 else
115 #endif
117 LM_UINT32 dummy;
119 REG_WR_OFFSET(pDevice, Register, Value32);
120 if (ReadBack && (pDevice->Flags & REG_RD_BACK_FLAG))
122 dummy = REG_RD_OFFSET(pDevice, Register);
127 /******************************************************************************/
128 /* Description: */
129 /* */
130 /* Return: */
131 /******************************************************************************/
132 LM_UINT32
133 LM_RegRdInd(
134 PLM_DEVICE_BLOCK pDevice,
135 LM_UINT32 Register) {
136 LM_UINT32 Value32;
138 MM_ACQUIRE_UNDI_LOCK(pDevice);
139 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
140 MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
141 MM_RELEASE_UNDI_LOCK(pDevice);
143 return MM_SWAP_LE32(Value32);
144 } /* LM_RegRdInd */
148 /******************************************************************************/
149 /* Description: */
150 /* */
151 /* Return: */
152 /******************************************************************************/
153 LM_VOID
154 LM_RegWrInd(
155 PLM_DEVICE_BLOCK pDevice,
156 LM_UINT32 Register,
157 LM_UINT32 Value32) {
159 MM_ACQUIRE_UNDI_LOCK(pDevice);
160 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
161 MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, MM_SWAP_LE32(Value32));
162 MM_RELEASE_UNDI_LOCK(pDevice);
163 } /* LM_RegWrInd */
167 /******************************************************************************/
168 /* Description: */
169 /* */
170 /* Return: */
171 /******************************************************************************/
172 LM_UINT32
173 LM_MemRdInd(
174 PLM_DEVICE_BLOCK pDevice,
175 LM_UINT32 MemAddr) {
176 LM_UINT32 Value32;
178 MM_ACQUIRE_UNDI_LOCK(pDevice);
179 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
180 MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
181 MM_RELEASE_UNDI_LOCK(pDevice);
183 return MM_SWAP_LE32(Value32);
184 } /* LM_MemRdInd */
188 /******************************************************************************/
189 /* Description: */
190 /* */
191 /* Return: */
192 /******************************************************************************/
193 LM_VOID
194 LM_MemWrInd(
195 PLM_DEVICE_BLOCK pDevice,
196 LM_UINT32 MemAddr,
197 LM_UINT32 Value32) {
198 MM_ACQUIRE_UNDI_LOCK(pDevice);
199 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
200 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, MM_SWAP_LE32(Value32));
201 MM_RELEASE_UNDI_LOCK(pDevice);
202 } /* LM_MemWrInd */
205 /******************************************************************************/
206 /* Description: */
207 /* */
208 /* Return: */
209 /******************************************************************************/
210 LM_STATUS
211 LM_QueueRxPackets(
212 PLM_DEVICE_BLOCK pDevice) {
213 LM_STATUS Lmstatus;
214 PLM_PACKET pPacket;
215 PT3_RCV_BD pRcvBd = 0;
216 LM_UINT32 StdBdAdded = 0;
217 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
218 LM_UINT32 JumboBdAdded = 0;
219 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
220 LM_UINT32 ConIdx, Idx;
221 LM_UINT32 Diff = 0;
223 Lmstatus = LM_STATUS_SUCCESS;
225 if (pDevice->Flags & RX_BD_LIMIT_64_FLAG)
227 ConIdx = pDevice->pStatusBlkVirt->RcvStdConIdx;
228 Diff = (pDevice->RxStdProdIdx - ConIdx) &
229 T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
230 if (Diff >= 56)
232 if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
234 pDevice->QueueAgain = TRUE;
236 return LM_STATUS_SUCCESS;
240 pDevice->QueueAgain = FALSE;
242 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
243 while(pPacket) {
244 switch(pPacket->u.Rx.RcvProdRing) {
245 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
246 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
247 /* Initialize the buffer descriptor. */
248 Idx = pDevice->RxJumboProdIdx;
249 pRcvBd = &pDevice->pRxJumboBdVirt[Idx];
251 pPacket->u.Rx.RcvRingProdIdx = Idx;
252 pDevice->RxJumboRing[Idx] = pPacket;
253 /* Update the producer index. */
254 pDevice->RxJumboProdIdx = (Idx + 1) &
255 T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
257 JumboBdAdded++;
258 break;
259 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
261 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
262 /* Initialize the buffer descriptor. */
263 Idx = pDevice->RxStdProdIdx;
264 pRcvBd = &pDevice->pRxStdBdVirt[Idx];
266 pPacket->u.Rx.RcvRingProdIdx = Idx;
267 pDevice->RxStdRing[Idx] = pPacket;
268 /* Update the producer index. */
269 pDevice->RxStdProdIdx = (Idx + 1) &
270 T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
272 StdBdAdded++;
273 break;
275 case T3_UNKNOWN_RCV_PROD_RING:
276 default:
277 Lmstatus = LM_STATUS_FAILURE;
278 break;
279 } /* switch */
281 /* Bail out if there is any error. */
282 if(Lmstatus != LM_STATUS_SUCCESS)
284 break;
287 /* Initialize the receive buffer pointer */
288 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
290 /* The opaque field may point to an offset from a fix addr. */
291 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
292 MM_UINT_PTR(pDevice->pPacketDescBase));
294 if ((pDevice->Flags & RX_BD_LIMIT_64_FLAG) &&
295 ((Diff + StdBdAdded) >= 63))
297 if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container))
299 pDevice->QueueAgain = TRUE;
301 break;
303 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
304 } /* while */
306 MM_WMB();
307 /* Update the procedure index. */
308 if(StdBdAdded)
310 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low,
311 pDevice->RxStdProdIdx);
312 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
314 MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
317 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
318 if(JumboBdAdded)
320 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
321 pDevice->RxJumboProdIdx);
322 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
324 MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
327 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
329 return Lmstatus;
330 } /* LM_QueueRxPackets */
333 /******************************************************************************/
334 /* Description: */
335 /* */
336 /* Return: */
337 /******************************************************************************/
338 STATIC LM_VOID
339 LM_NvramInit(
340 PLM_DEVICE_BLOCK pDevice)
342 LM_UINT32 Value32;
344 pDevice->NvramSize = 0;
345 /* Intialize clock period and state machine. */
346 Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
347 SEEPROM_ADDR_FSM_RESET;
348 REG_WR(pDevice, Grc.EepromAddr, Value32);
349 REG_RD_BACK(pDevice, Grc.EepromAddr);
351 MM_Wait(100);
353 /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
354 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
355 REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
357 /* Set the 5701 compatibility mode if we are using EEPROM. */
358 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
359 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
361 Value32 = REG_RD(pDevice, Nvram.Config1);
362 if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
364 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
366 REG_WR(pDevice, Nvram.NvmAccess,
367 REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
369 /* Use the new interface to read EEPROM. */
370 Value32 &= ~FLASH_COMPAT_BYPASS;
372 REG_WR(pDevice, Nvram.Config1, Value32);
374 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
376 REG_WR(pDevice, Nvram.NvmAccess,
377 REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
380 else {
381 pDevice->NvramSize = 0x20000;
382 pDevice->Flags |= FLASH_DETECTED_FLAG;
386 if (pDevice->NvramSize == 0)
388 Value32 = 0;
389 LM_NvramRead(pDevice, 0, &Value32);
390 Value32 = MM_SWAP_BE32(Value32);
391 if (Value32 != 0x669955aa) {
392 pDevice->NvramSize = SEEPROM_CHIP_SIZE;
393 return;
396 /* size eeprom */
397 pDevice->NvramSize = 0x800;
398 while (pDevice->NvramSize < SEEPROM_CHIP_SIZE) {
399 if (LM_NvramRead(pDevice, pDevice->NvramSize, &Value32) !=
400 LM_STATUS_SUCCESS) {
401 pDevice->NvramSize = SEEPROM_CHIP_SIZE;
402 break;
404 Value32 = MM_SWAP_BE32(Value32);
405 if (Value32 == 0x669955aa)
406 break;
407 pDevice->NvramSize <<= 1;
410 } /* LM_NvRamInit */
413 /******************************************************************************/
414 /* Description: */
415 /* */
416 /* Return: */
417 /******************************************************************************/
418 STATIC LM_STATUS
419 LM_EepromRead(
420 PLM_DEVICE_BLOCK pDevice,
421 LM_UINT32 Offset,
422 LM_UINT32 *pData)
424 LM_UINT32 Value32;
425 LM_UINT32 Addr;
426 LM_UINT32 Dev;
427 LM_UINT32 j;
429 if(Offset > SEEPROM_CHIP_SIZE)
431 return LM_STATUS_FAILURE;
434 Dev = Offset / SEEPROM_CHIP_SIZE;
435 Addr = Offset % SEEPROM_CHIP_SIZE;
437 Value32 = REG_RD(pDevice, Grc.EepromAddr);
438 Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
439 SEEPROM_ADDR_RW_MASK);
440 REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
441 SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
443 for(j = 0; j < 1000; j++)
445 Value32 = REG_RD(pDevice, Grc.EepromAddr);
446 if(Value32 & SEEPROM_ADDR_COMPLETE)
448 break;
450 MM_Wait(20);
453 if(Value32 & SEEPROM_ADDR_COMPLETE)
455 Value32 = REG_RD(pDevice, Grc.EepromData);
456 /* The endianess of the eeprom and flash interface is different */
457 *pData = MM_SWAP_LE32(Value32);
459 return LM_STATUS_SUCCESS;
462 return LM_STATUS_FAILURE;
463 } /* LM_EepromRead */
465 #ifdef ETHTOOL_SEEPROM
467 STATIC LM_STATUS
468 LM_EepromWriteBlock(
469 PLM_DEVICE_BLOCK pDevice,
470 LM_UINT32 Offset,
471 LM_UINT32 *pData,
472 LM_UINT32 Size)
474 LM_UINT32 Value32 = 0;
475 LM_UINT32 Addr;
476 LM_UINT32 Dev;
477 LM_UINT32 i, j;
479 if(Offset > SEEPROM_CHIP_SIZE)
481 return LM_STATUS_FAILURE;
484 /* Enable EEPROM write. */
485 if (pDevice->Flags & EEPROM_WP_FLAG)
487 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
488 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
489 REG_RD_BACK(pDevice, Grc.LocalCtrl);
490 MM_Wait(40);
492 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
493 if(Value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1)
495 return LM_STATUS_FAILURE;
499 for (i = 0; i < Size ; i++, pData++, Offset += 4) {
501 Dev = Offset / SEEPROM_CHIP_SIZE;
502 Addr = Offset % SEEPROM_CHIP_SIZE;
504 /* Set the write value to the eeprom */
505 REG_WR(pDevice, Grc.EepromData, MM_SWAP_LE32(*pData));
507 Value32 = REG_RD(pDevice, Grc.EepromAddr);
508 Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
509 SEEPROM_ADDR_RW_MASK);
511 REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
512 SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_WRITE);
514 for(j = 0; j < 1000; j++)
516 Value32 = REG_RD(pDevice, Grc.EepromAddr);
517 if(Value32 & SEEPROM_ADDR_COMPLETE)
519 break;
521 MM_Wait(10);
525 /* Write-protect EEPROM. */
526 if (pDevice->Flags & EEPROM_WP_FLAG)
528 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
529 GRC_MISC_LOCAL_CTRL_GPIO_OE1 | GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
530 REG_RD_BACK(pDevice, Grc.LocalCtrl);
531 MM_Wait(40);
534 if(Value32 & SEEPROM_ADDR_COMPLETE)
536 return LM_STATUS_SUCCESS;
539 return LM_STATUS_FAILURE;
540 } /* LM_EepromWriteBlock */
541 #endif
543 #define NVRAM_MAXWAIT 8000
544 LM_STATUS
545 LM_NvramGetLock(LM_DEVICE_BLOCK *pDevice)
547 int j;
549 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
550 /* worst case wait time for Nvram arbitration using serial eprom is */
551 /* about 45 msec on a 5704 with the other channel loading boot code */
552 for (j = 0; j < NVRAM_MAXWAIT; j++)
554 if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
556 break;
558 MM_Wait(20);
560 if (j == NVRAM_MAXWAIT)
562 return LM_STATUS_FAILURE;
564 return LM_STATUS_SUCCESS;
567 LM_STATUS
568 LM_NvramReleaseLock(LM_DEVICE_BLOCK *pDevice)
570 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
571 return LM_STATUS_SUCCESS;
574 /******************************************************************************/
575 /* Description: */
576 /* */
577 /* Return: */
578 /******************************************************************************/
579 LM_STATUS
580 LM_NvramRead(
581 PLM_DEVICE_BLOCK pDevice,
582 LM_UINT32 Offset,
583 LM_UINT32 *pData)
585 LM_UINT32 Value32;
586 LM_STATUS Status;
587 LM_UINT32 j;
589 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
590 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
592 Status = LM_EepromRead(pDevice, Offset, pData);
594 else
596 /* Determine if we have flash or EEPROM. */
597 Value32 = REG_RD(pDevice, Nvram.Config1);
598 if(Value32 & FLASH_INTERFACE_ENABLE)
600 if(Value32 & FLASH_SSRAM_BUFFERED_MODE)
602 Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
603 BUFFERED_FLASH_PAGE_POS) +
604 (Offset % BUFFERED_FLASH_PAGE_SIZE);
608 if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
610 return LM_STATUS_FAILURE;
613 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
615 REG_WR(pDevice, Nvram.NvmAccess,
616 REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
619 /* Read from flash or EEPROM with the new 5703/02 interface. */
620 REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
622 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
623 NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
625 /* Wait for the done bit to clear. */
626 for(j = 0; j < 1000; j++)
628 MM_Wait(10);
630 Value32 = REG_RD(pDevice, Nvram.Cmd);
631 if(Value32 & NVRAM_CMD_DONE)
633 MM_Wait(10);
635 *pData = REG_RD(pDevice, Nvram.ReadData);
637 /* Data is swapped so that the byte stream is the same */
638 /* in big and little endian systems. */
639 /* Caller will do additional swapping depending on */
640 /* how it wants to look at the data. */
641 *pData = MM_SWAP_BE32(*pData);
643 break;
647 LM_NvramReleaseLock(pDevice);
648 if(Value32 & NVRAM_CMD_DONE)
650 Status = LM_STATUS_SUCCESS;
652 else
654 Status = LM_STATUS_FAILURE;
658 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
660 REG_WR(pDevice, Nvram.NvmAccess,
661 REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
664 return Status;
665 } /* LM_NvramRead */
668 #ifdef ETHTOOL_SEEPROM
669 /******************************************************************************/
670 /* Description: */
671 /* */
672 /* Return: */
673 /******************************************************************************/
674 LM_STATUS
675 LM_NvramWriteBlock(
676 PLM_DEVICE_BLOCK pDevice,
677 LM_UINT32 Offset,
678 LM_UINT32 *pData,
679 LM_UINT32 Size)
681 LM_UINT32 Value32 = 0;
682 LM_UINT32 ControlReg;
683 LM_UINT32 AddrOffset;
684 LM_STATUS Status;
685 LM_UINT32 i , j;
686 LM_UINT32 BufferedFlash;
688 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
689 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
691 Status = LM_EepromWriteBlock(pDevice, Offset, pData, Size);
693 else
695 if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
697 return LM_STATUS_FAILURE;
700 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
702 REG_WR(pDevice, Nvram.NvmAccess,
703 REG_RD(pDevice, Nvram.NvmAccess) | ACCESS_EN);
706 /* Enable EEPROM write. */
707 if (pDevice->Flags & EEPROM_WP_FLAG)
709 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
710 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
711 REG_RD_BACK(pDevice, Grc.LocalCtrl);
712 MM_Wait(40);
714 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
715 if(Value32 & GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1)
717 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
719 REG_WR(pDevice, Nvram.NvmAccess,
720 REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
722 return LM_STATUS_FAILURE;
726 REG_WR(pDevice, Grc.Mode, pDevice->GrcMode |
727 GRC_MODE_NVRAM_WRITE_ENABLE);
729 BufferedFlash = FALSE;
730 Value32 = REG_RD(pDevice, Nvram.Config1);
731 if(Value32 & FLASH_INTERFACE_ENABLE)
733 if(Value32 & FLASH_SSRAM_BUFFERED_MODE)
735 BufferedFlash = TRUE;
739 for (i = 0 ; i < Size ; i++, pData++, Offset += 4) {
741 /* Swap the data so that the byte stream will */
742 /* be written the same in little and big endian systems */
743 Value32 = MM_SWAP_BE32(*pData);
745 /* set the desired write data value to the flash */
746 REG_WR(pDevice, Nvram.WriteData, Value32);
748 /* set targeted address */
749 AddrOffset = Offset;
751 /* Determine if we have flash or buffered flash. */
752 if(BufferedFlash)
754 AddrOffset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
755 BUFFERED_FLASH_PAGE_POS) +
756 (Offset % BUFFERED_FLASH_PAGE_SIZE);
759 /* Write to flash or EEPROM with the new 5703/02 interface. */
760 REG_WR(pDevice, Nvram.Addr, AddrOffset & NVRAM_ADDRESS_MASK);
762 ControlReg = NVRAM_CMD_DO_IT | NVRAM_CMD_DONE | NVRAM_CMD_WR;
763 if(i == 0)
765 ControlReg |= NVRAM_CMD_FIRST;
767 if(i == (Size - 1))
769 ControlReg |= NVRAM_CMD_LAST;
772 if(BufferedFlash)
774 /* Set CMD_FIRST when we are at the beginning of a page. */
775 if(!(AddrOffset & BUFFERED_FLASH_BYTE_ADDR_MASK))
777 ControlReg |= NVRAM_CMD_FIRST;
779 else if((AddrOffset & BUFFERED_FLASH_BYTE_ADDR_MASK) ==
780 (BUFFERED_FLASH_PAGE_SIZE - 4))
782 ControlReg |= NVRAM_CMD_LAST;
786 REG_WR(pDevice, Nvram.Cmd, ControlReg);
788 /* Wait for the done bit to go High. */
789 for(j = 0; j < 4000 ; j++)
791 MM_Wait(10);
793 Value32 = REG_RD(pDevice, Nvram.Cmd);
795 if(Value32 & NVRAM_CMD_DONE)
797 MM_Wait(5);
798 break;
803 REG_WR(pDevice, Grc.Mode, pDevice->GrcMode);
805 /* Write-protect EEPROM. */
806 if(pDevice->Flags & EEPROM_WP_FLAG)
808 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
809 GRC_MISC_LOCAL_CTRL_GPIO_OE1 | GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
810 REG_RD_BACK(pDevice, Grc.LocalCtrl);
811 MM_Wait(40);
814 /* Relinquish nvram interface. */
815 LM_NvramReleaseLock(pDevice);
817 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
819 REG_WR(pDevice, Nvram.NvmAccess,
820 REG_RD(pDevice, Nvram.NvmAccess) & ~ACCESS_EN);
823 if(Value32 & NVRAM_CMD_DONE)
825 Status = LM_STATUS_SUCCESS;
827 else
829 Status = LM_STATUS_FAILURE;
833 return Status;
834 } /* LM_NvramWriteBlock */
835 #endif
837 STATIC void
838 LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
840 #ifdef BCM_PROC_FS
841 LM_UINT32 Vpd_arr[256/4];
842 LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
843 LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
844 LM_UINT32 Value32;
845 unsigned int j;
847 /* Read PN from VPD */
848 for (j = 0; j < 256; j += 4, Vpd_dptr++ )
850 if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
851 printf("VPD read failed\n");
852 return;
854 *Vpd_dptr = Value32;
856 for (j = 0; j < 256; )
858 unsigned int Vpd_r_len;
859 unsigned int Vpd_r_end;
861 if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
863 j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
865 else if (Vpd[j] == 0x90)
867 Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
868 j += 3;
869 Vpd_r_end = Vpd_r_len + j;
870 while (j < Vpd_r_end)
872 if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
874 unsigned int len = Vpd[j + 2];
876 if (len <= 24)
878 memcpy(pDevice->PartNo, &Vpd[j + 3], len);
880 break;
882 else
884 if (Vpd[j + 2] == 0)
886 break;
888 j = j + Vpd[j + 2];
891 break;
893 else {
894 break;
897 #endif
900 STATIC void
901 LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
903 #ifdef BCM_PROC_FS
904 LM_UINT32 Value32, offset, ver_offset, start_addr;
905 int i;
907 if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
908 return;
909 Value32 = MM_SWAP_BE32(Value32);
910 if (Value32 != 0x669955aa)
911 return;
912 if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
913 return;
915 offset = MM_SWAP_BE32(offset);
917 if((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
918 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) &&
919 ((REG_RD(pDevice, Nvram.Config1) & BUFFERED_FLASH) == BUFFERED_FLASH))
921 offset = (offset >> BUFFERED_FLASH_PAGE_POS) *
922 BUFFERED_FLASH_PAGE_SIZE + (offset & BUFFERED_FLASH_BYTE_ADDR_MASK);
924 if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
925 return;
927 Value32 = MM_SWAP_BE32(Value32);
928 if ((((Value32 & ~0x0f00) == 0x0e000003) ||
929 ((Value32 & ~0xff00) == 0x0c000003)) &&
930 (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
931 (Value32 == 0)) {
933 if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
934 return;
935 if (LM_NvramRead(pDevice, 4, &start_addr) != LM_STATUS_SUCCESS)
936 return;
937 ver_offset = MM_SWAP_BE32(ver_offset);
938 start_addr = MM_SWAP_BE32(start_addr);
939 offset += ver_offset - start_addr;
940 for (i = 0; i < 16; i += 4) {
941 if (LM_NvramRead(pDevice, offset + i, &Value32) !=
942 LM_STATUS_SUCCESS)
944 return;
946 *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = Value32;
949 else {
950 char c;
952 if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
953 return;
955 Value32 = MM_SWAP_BE32(Value32);
956 i = 0;
957 c = ((Value32 & 0xff00) >> 8);
959 if (c < 10) {
960 pDevice->BootCodeVer[i++] = c + '0';
962 else {
963 pDevice->BootCodeVer[i++] = (c / 10) + '0';
964 pDevice->BootCodeVer[i++] = (c % 10) + '0';
966 pDevice->BootCodeVer[i++] = '.';
967 c = Value32 & 0xff;
968 if (c < 10) {
969 pDevice->BootCodeVer[i++] = '0';
970 pDevice->BootCodeVer[i++] = c + '0';
972 else {
973 pDevice->BootCodeVer[i++] = (c / 10) + '0';
974 pDevice->BootCodeVer[i++] = (c % 10) + '0';
976 pDevice->BootCodeVer[i] = 0;
978 #endif
981 STATIC void
982 LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
984 #ifdef BCM_PROC_FS
985 LM_UINT32 PciState = pDevice->PciState;
986 LM_UINT32 ClockCtrl;
987 char *SpeedStr = "";
989 if (pDevice->Flags & PCI_EXPRESS_FLAG)
991 strcpy(pDevice->BusSpeedStr, "PCI Express");
992 return;
994 if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
996 strcpy(pDevice->BusSpeedStr, "32-bit ");
998 else
1000 strcpy(pDevice->BusSpeedStr, "64-bit ");
1002 if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
1004 strcat(pDevice->BusSpeedStr, "PCI ");
1005 if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
1007 SpeedStr = "66MHz";
1009 else
1011 SpeedStr = "33MHz";
1014 else
1016 strcat(pDevice->BusSpeedStr, "PCIX ");
1017 if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
1019 SpeedStr = "133MHz";
1021 else
1023 ClockCtrl = pDevice->ClockCtrl & 0x1f;
1024 switch (ClockCtrl)
1026 case 0:
1027 SpeedStr = "33MHz";
1028 break;
1030 case 2:
1031 SpeedStr = "50MHz";
1032 break;
1034 case 4:
1035 SpeedStr = "66MHz";
1036 break;
1038 case 6:
1039 SpeedStr = "100MHz";
1040 break;
1042 case 7:
1043 SpeedStr = "133MHz";
1044 break;
1048 strcat(pDevice->BusSpeedStr, SpeedStr);
1049 #endif
1052 /******************************************************************************/
1053 /* Description: */
1054 /* This routine initializes default parameters and reads the PCI */
1055 /* configurations. */
1056 /* */
1057 /* Return: */
1058 /* LM_STATUS_SUCCESS */
1059 /******************************************************************************/
1060 LM_STATUS
1061 LM_GetAdapterInfo(
1062 PLM_DEVICE_BLOCK pDevice)
1064 PLM_ADAPTER_INFO pAdapterInfo;
1065 LM_UINT32 Value32, LedCfg;
1066 LM_STATUS Status;
1067 LM_UINT32 EeSigFound;
1068 LM_UINT32 EePhyTypeSerdes = 0;
1069 LM_UINT32 EePhyId = 0;
1071 /* Get Device Id and Vendor Id */
1072 Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
1073 if(Status != LM_STATUS_SUCCESS)
1075 return Status;
1077 pDevice->PciVendorId = (LM_UINT16) Value32;
1078 pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
1080 Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
1081 if(Status != LM_STATUS_SUCCESS)
1083 return Status;
1085 pDevice->PciRevId = (LM_UINT8) Value32;
1087 /* Get chip revision id. */
1088 Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
1089 pDevice->ChipRevId = Value32 >> 16;
1091 /* detremine if it is PCIE system */
1092 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1094 Status = MM_ReadConfig32(pDevice, T3_MSI_CAPABILITY_ID_REG, &Value32);
1095 if (((Value32 >> 8) & 0xff) == T3_PCIE_CAPABILITY_ID_REG)
1097 Status = MM_ReadConfig32(pDevice, T3_PCIE_CAPABILITY_ID_REG,
1098 &Value32);
1099 if ((Value32 & 0xff) == T3_PCIE_CAPABILITY_ID)
1101 pDevice->Flags |= PCI_EXPRESS_FLAG;
1106 /* Get subsystem vendor. */
1107 Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
1108 if(Status != LM_STATUS_SUCCESS)
1110 return Status;
1112 pDevice->SubsystemVendorId = (LM_UINT16) Value32;
1114 /* Get PCI subsystem id. */
1115 pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
1117 /* Get the cache line size. */
1118 MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
1119 pDevice->CacheLineSize = (LM_UINT8) Value32;
1120 pDevice->SavedCacheLineReg = Value32;
1122 if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
1123 pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
1124 pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
1126 pDevice->Flags &= ~UNDI_FIX_FLAG;
1128 #if !PCIX_TARGET_WORKAROUND
1129 pDevice->Flags &= ~UNDI_FIX_FLAG;
1130 #endif
1131 /* Map the memory base to system address space. */
1132 if (!(pDevice->Flags & UNDI_FIX_FLAG))
1134 Status = MM_MapMemBase(pDevice);
1135 if(Status != LM_STATUS_SUCCESS)
1137 return Status;
1139 /* Initialize the memory view pointer. */
1140 pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
1143 if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) ||
1144 (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
1146 pDevice->Flags |= TX_4G_WORKAROUND_FLAG;
1148 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1150 pDevice->Flags |= REG_RD_BACK_FLAG;
1152 #ifdef INCLUDE_5750_A0_FIX
1153 if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
1154 (pDevice->ChipRevId == T3_CHIP_ID_5750_A0))
1156 pDevice->Flags |= REG_RD_BACK_FLAG;
1158 #endif
1159 #if PCIX_TARGET_WORKAROUND
1160 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
1161 if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
1163 /* Enable PCI-X workaround only if we are running on 5700 BX. */
1164 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
1166 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1169 if (pDevice->Flags & UNDI_FIX_FLAG)
1171 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1173 #endif
1174 /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
1175 /* management register may be clobbered which may cause the */
1176 /* BCM5700 to go into D3 state. While in this state, we will */
1177 /* not have memory mapped register access. As a workaround, we */
1178 /* need to restore the device to D0 state. */
1179 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
1180 Value32 |= T3_PM_PME_ASSERTED;
1181 Value32 &= ~T3_PM_POWER_STATE_MASK;
1182 Value32 |= T3_PM_POWER_STATE_D0;
1183 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
1185 /* read the current PCI command word */
1186 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
1188 /* Make sure bus-mastering is enabled. */
1189 Value32 |= PCI_BUSMASTER_ENABLE;
1191 #if PCIX_TARGET_WORKAROUND
1192 /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
1193 are enabled */
1194 if (pDevice->Flags & ENABLE_PCIX_FIX_FLAG) {
1195 Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
1196 PCI_PARITY_ERROR_ENABLE);
1198 if (pDevice->Flags & UNDI_FIX_FLAG)
1200 Value32 &= ~PCI_MEM_SPACE_ENABLE;
1203 #endif
1205 if (pDevice->Flags & ENABLE_MWI_FLAG)
1207 Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
1209 else {
1210 Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
1213 /* save the value we are going to write into the PCI command word */
1214 pDevice->PciCommandStatusWords = Value32;
1216 Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
1217 if(Status != LM_STATUS_SUCCESS)
1219 return Status;
1222 /* Setup the mode registers. */
1223 pDevice->MiscHostCtrl =
1224 MISC_HOST_CTRL_MASK_PCI_INT |
1225 MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
1226 #ifdef BIG_ENDIAN_HOST
1227 MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
1228 #endif /* BIG_ENDIAN_HOST */
1229 MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
1230 MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
1231 /* write to PCI misc host ctr first in order to enable indirect accesses */
1232 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
1234 /* Set power state to D0. */
1235 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
1237 /* Preserve HOST_STACK_UP bit in case ASF firmware is running */
1238 Value32 = REG_RD(pDevice, Grc.Mode) & GRC_MODE_HOST_STACK_UP;
1239 #ifdef BIG_ENDIAN_HOST
1240 Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
1241 GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
1242 #else
1243 Value32 |= GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
1244 #endif
1245 REG_WR(pDevice, Grc.Mode, Value32);
1247 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1249 REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
1250 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
1251 REG_RD_BACK(pDevice, Grc.LocalCtrl);
1253 MM_Wait(40);
1255 /* Enable indirect memory access */
1256 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
1258 LM_SwitchClocks(pDevice);
1260 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
1262 /* Check to see if PXE ran and did not shutdown properly */
1263 if ((REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE) ||
1264 !(REG_RD(pDevice, PciCfg.MiscHostCtrl) & MISC_HOST_CTRL_MASK_PCI_INT))
1266 LM_DisableInterrupt(pDevice);
1267 /* assume ASF is enabled */
1268 pDevice->AsfFlags = ASF_ENABLED;
1269 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1271 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
1273 LM_ShutdownChip(pDevice, LM_SHUTDOWN_RESET);
1274 pDevice->AsfFlags = 0;
1276 #if PCIX_TARGET_WORKAROUND
1277 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
1278 if (!(pDevice->Flags & ENABLE_PCIX_FIX_FLAG) &&
1279 ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
1281 if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1282 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1283 pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
1284 pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
1286 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300]), 0);
1287 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]), 0);
1288 MM_MEMWRITEL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x301]),
1289 0xffffffff);
1290 if (MM_MEMREADL(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
1292 pDevice->Flags |= ENABLE_PCIX_FIX_FLAG;
1296 #endif
1298 LM_NvramInit(pDevice);
1300 Status = LM_STATUS_FAILURE;
1301 /* Get the node address. First try to get in from the shared memory. */
1302 /* If the signature is not present, then get it from the NVRAM. */
1303 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
1304 if((Value32 >> 16) == 0x484b)
1306 int i;
1308 pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
1309 pDevice->NodeAddress[1] = (LM_UINT8) Value32;
1311 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
1313 pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
1314 pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
1315 pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
1316 pDevice->NodeAddress[5] = (LM_UINT8) Value32;
1318 /* Check for null MAC address which can happen with older boot code */
1319 for (i = 0; i < 6; i++)
1321 if (pDevice->NodeAddress[i] != 0)
1323 Status = LM_STATUS_SUCCESS;
1324 break;
1328 if (Status != LM_STATUS_SUCCESS)
1330 int MacOffset;
1332 MacOffset = 0x7c;
1333 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
1335 if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
1337 MacOffset = 0xcc;
1339 /* workaround - need to reset nvram if */
1340 /* the boot code is not running */
1341 if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
1343 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
1345 else
1347 LM_NvramReleaseLock(pDevice);
1350 Status = LM_NvramRead(pDevice, MacOffset, &Value32);
1351 if(Status == LM_STATUS_SUCCESS)
1353 LM_UINT8 *c = (LM_UINT8 *) &Value32;
1355 pDevice->NodeAddress[0] = c[2];
1356 pDevice->NodeAddress[1] = c[3];
1358 Status = LM_NvramRead(pDevice, MacOffset + 4, &Value32);
1360 c = (LM_UINT8 *) &Value32;
1361 pDevice->NodeAddress[2] = c[0];
1362 pDevice->NodeAddress[3] = c[1];
1363 pDevice->NodeAddress[4] = c[2];
1364 pDevice->NodeAddress[5] = c[3];
1368 if(Status != LM_STATUS_SUCCESS)
1370 Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].High);
1371 pDevice->NodeAddress[0] = (Value32 >> 8) & 0xff;
1372 pDevice->NodeAddress[1] = Value32 & 0xff;
1373 Value32 = REG_RD(pDevice, MacCtrl.MacAddr[0].Low);
1374 pDevice->NodeAddress[2] = (Value32 >> 24) & 0xff;
1375 pDevice->NodeAddress[3] = (Value32 >> 16) & 0xff;
1376 pDevice->NodeAddress[4] = (Value32 >> 8) & 0xff;
1377 pDevice->NodeAddress[5] = Value32 & 0xff;
1378 printf("WARNING: Cannot get MAC addr from NVRAM, using %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
1379 pDevice->NodeAddress[0], pDevice->NodeAddress[1],
1380 pDevice->NodeAddress[2], pDevice->NodeAddress[3],
1381 pDevice->NodeAddress[4], pDevice->NodeAddress[5]);
1384 memcpy(pDevice->PermanentNodeAddress, pDevice->NodeAddress, 6);
1386 /* Initialize the default values. */
1387 pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
1388 pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
1389 pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
1390 pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
1391 pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
1392 pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
1393 pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
1394 pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
1395 pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
1396 pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
1397 pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
1398 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1399 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1400 pDevice->DisableAutoNeg = FALSE;
1401 pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
1402 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
1404 pDevice->PhyFlags = 0;
1406 if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
1407 pDevice->Flags |= DELAY_PCI_GRANT_FLAG;
1409 pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO;
1410 pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
1411 pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1412 pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
1413 #if INCLUDE_TBI_SUPPORT
1414 pDevice->TbiFlags = 0;
1415 pDevice->IgnoreTbiLinkChange = FALSE;
1416 #endif
1417 #if INCLUDE_TCP_SEG_SUPPORT
1418 pDevice->LargeSendMaxSize = T3_TCP_SEG_MAX_OFFLOAD_SIZE;
1419 pDevice->LargeSendMinNumSeg = T3_TCP_SEG_MIN_NUM_SEG;
1420 #endif
1422 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
1423 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
1424 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
1426 pDevice->PhyFlags |= PHY_RESET_ON_LINKDOWN;
1427 pDevice->PhyFlags |= PHY_CHECK_TAPS_AFTER_RESET;
1429 if ((T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5703_AX) ||
1430 (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_AX))
1432 pDevice->PhyFlags |= PHY_ADC_FIX;
1434 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
1436 pDevice->PhyFlags |= PHY_5704_A0_FIX;
1438 if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
1440 pDevice->PhyFlags |= PHY_5705_5750_FIX;
1442 /* Ethernet@Wirespeed is supported on 5701,5702,5703,5704,5705a0,5705a1 */
1443 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
1444 !((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
1445 (pDevice->ChipRevId != T3_CHIP_ID_5705_A0) &&
1446 (pDevice->ChipRevId != T3_CHIP_ID_5705_A1)))
1448 pDevice->PhyFlags |= PHY_ETHERNET_WIRESPEED;
1451 switch (T3_ASIC_REV(pDevice->ChipRevId))
1453 case T3_ASIC_REV_5704:
1454 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1455 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
1456 break;
1457 default:
1458 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1459 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
1460 break;
1463 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
1464 pDevice->QueueRxPackets = TRUE;
1466 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1467 pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
1468 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1470 pDevice->RxJumboDescCnt = 0;
1472 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1474 pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
1476 if(((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
1477 ((pDevice->BondId == 0x10000) || (pDevice->BondId == 0x18000))) ||
1478 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) &&
1479 ((pDevice->BondId == 0x14000) || (pDevice->BondId == 0x1c000))))
1481 return LM_STATUS_UNKNOWN_ADAPTER;
1483 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1485 if ((pDevice->BondId == 0x8000) || (pDevice->BondId == 0x4000))
1487 pDevice->PhyFlags |= PHY_NO_GIGABIT;
1490 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1492 if ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
1493 (pDevice->BondId == GRC_MISC_BD_ID_5788M))
1495 pDevice->Flags |= BCM5788_FLAG;
1497 if ((pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901)) ||
1498 (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5901A2)) ||
1499 (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5705F)))
1501 pDevice->PhyFlags |= PHY_NO_GIGABIT;
1504 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1506 if (pDevice->PciDeviceId == T3_PCI_DEVICE_ID(T3_PCI_ID_BCM5751F))
1508 pDevice->PhyFlags |= PHY_NO_GIGABIT;
1512 /* CIOBE multisplit has a bug */
1513 #if 0
1514 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) &&
1515 (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
1517 pDevice->Flags |= MULTI_SPLIT_ENABLE_FLAG;
1518 pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
1520 #endif
1522 /* Get Eeprom info. */
1523 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
1524 if (Value32 == T3_NIC_DATA_SIG)
1526 EeSigFound = TRUE;
1527 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
1529 if (Value32 & T3_NIC_MINI_PCI)
1531 pDevice->Flags |= MINI_PCI_FLAG;
1533 /* Determine PHY type. */
1534 switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
1536 case T3_NIC_CFG_PHY_TYPE_COPPER:
1537 EePhyTypeSerdes = FALSE;
1538 break;
1540 case T3_NIC_CFG_PHY_TYPE_FIBER:
1541 EePhyTypeSerdes = TRUE;
1542 break;
1544 default:
1545 EePhyTypeSerdes = FALSE;
1546 break;
1549 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1551 LedCfg = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2);
1552 LedCfg = LedCfg & (T3_NIC_CFG_LED_MODE_MASK |
1553 T3_SHASTA_EXT_LED_MODE_MASK);
1555 else
1557 /* Determine PHY led mode. for legacy devices */
1558 LedCfg = Value32 & T3_NIC_CFG_LED_MODE_MASK;
1561 switch (LedCfg)
1563 default:
1564 case T3_NIC_CFG_LED_PHY_MODE_1:
1565 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
1566 break;
1568 case T3_NIC_CFG_LED_PHY_MODE_2:
1569 pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
1570 break;
1572 case T3_NIC_CFG_LED_MAC_MODE:
1573 pDevice->LedCtrl = LED_CTRL_MAC_MODE;
1574 break;
1576 case T3_SHASTA_EXT_LED_SHARED_TRAFFIC_LINK_MODE:
1577 pDevice->LedCtrl = LED_CTRL_SHARED_TRAFFIC_LINK;
1578 if ((pDevice->ChipRevId != T3_CHIP_ID_5750_A0) &&
1579 (pDevice->ChipRevId != T3_CHIP_ID_5750_A1))
1581 pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
1582 LED_CTRL_PHY_MODE_2;
1584 break;
1586 case T3_SHASTA_EXT_LED_MAC_MODE:
1587 pDevice->LedCtrl = LED_CTRL_SHASTA_MAC_MODE;
1588 break;
1590 case T3_SHASTA_EXT_LED_WIRELESS_COMBO_MODE:
1591 pDevice->LedCtrl = LED_CTRL_WIRELESS_COMBO;
1592 if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
1594 pDevice->LedCtrl |= LED_CTRL_PHY_MODE_1 |
1595 LED_CTRL_PHY_MODE_2;
1597 break;
1601 if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1602 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)) &&
1603 (pDevice->SubsystemVendorId == T3_SVID_DELL))
1605 pDevice->LedCtrl = LED_CTRL_PHY_MODE_2;
1608 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
1609 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) ||
1610 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
1612 /* Enable EEPROM write protection. */
1613 if(Value32 & T3_NIC_EEPROM_WP)
1615 pDevice->Flags |= EEPROM_WP_FLAG;
1618 pDevice->AsfFlags = 0;
1619 #ifdef BCM_ASF
1620 if (Value32 & T3_NIC_CFG_ENABLE_ASF)
1622 pDevice->AsfFlags |= ASF_ENABLED;
1623 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
1625 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
1628 #endif
1629 if (Value32 & T3_NIC_FIBER_WOL_CAPABLE)
1631 pDevice->Flags |= FIBER_WOL_CAPABLE_FLAG;
1633 if (Value32 & T3_NIC_WOL_LIMIT_10)
1635 pDevice->Flags |= WOL_LIMIT_10MBPS_FLAG;
1638 /* Get the PHY Id. */
1639 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1640 if (Value32)
1642 EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1643 PHY_ID1_OUI_MASK) << 10;
1645 Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1647 EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1648 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1650 else
1652 EePhyId = 0;
1653 if (!EePhyTypeSerdes && !(pDevice->AsfFlags & ASF_ENABLED))
1655 /* reset PHY if boot code couldn't read the PHY ID */
1656 LM_ResetPhy(pDevice);
1659 if (MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR2) & BIT_17)
1661 pDevice->PhyFlags |= PHY_CAPACITIVE_COUPLING;
1664 else
1666 EeSigFound = FALSE;
1669 /* Set the PHY address. */
1670 pDevice->PhyAddr = PHY_DEVICE_ID;
1672 /* Disable auto polling. */
1673 pDevice->MiMode = 0xc0000;
1674 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
1675 REG_RD_BACK(pDevice, MacCtrl.MiMode);
1676 MM_Wait(80);
1678 if (pDevice->AsfFlags & ASF_ENABLED)
1680 /* Reading PHY registers will contend with ASF */
1681 pDevice->PhyId = 0;
1683 else
1685 /* Get the PHY id. */
1686 LM_GetPhyId(pDevice);
1689 /* Set the EnableTbi flag to false if we have a copper PHY. */
1690 switch(pDevice->PhyId & PHY_ID_MASK)
1692 case PHY_BCM5400_PHY_ID:
1693 case PHY_BCM5401_PHY_ID:
1694 case PHY_BCM5411_PHY_ID:
1695 case PHY_BCM5701_PHY_ID:
1696 case PHY_BCM5703_PHY_ID:
1697 case PHY_BCM5704_PHY_ID:
1698 case PHY_BCM5705_PHY_ID:
1699 case PHY_BCM5750_PHY_ID:
1700 break;
1702 case PHY_BCM8002_PHY_ID:
1703 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1704 break;
1706 default:
1708 if (EeSigFound)
1710 pDevice->PhyId = EePhyId;
1711 if (EePhyTypeSerdes)
1713 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1716 else if ((pAdapterInfo = LM_GetAdapterInfoBySsid(
1717 pDevice->SubsystemVendorId,
1718 pDevice->SubsystemId)))
1720 pDevice->PhyId = pAdapterInfo->PhyId;
1721 if (pAdapterInfo->Serdes)
1723 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1726 else
1728 if (UNKNOWN_PHY_ID(pDevice->PhyId))
1730 LM_ResetPhy(pDevice);
1731 LM_GetPhyId(pDevice);
1734 break;
1737 if(UNKNOWN_PHY_ID(pDevice->PhyId) &&
1738 !(pDevice->TbiFlags & ENABLE_TBI_FLAG))
1740 pDevice->TbiFlags |= ENABLE_TBI_FLAG;
1741 printf("PHY ID unknown, assume it is SerDes\n");
1744 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1746 if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
1748 pDevice->SavedCacheLineReg &= 0xffff00ff;
1749 pDevice->SavedCacheLineReg |= 0x4000;
1753 pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1754 LM_ACCEPT_UNICAST;
1756 pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1757 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM | LM_TASK_OFFLOAD_RX_TCP_CHECKSUM |
1758 LM_TASK_OFFLOAD_RX_UDP_CHECKSUM;
1760 if (pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
1762 pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1763 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1766 #if INCLUDE_TCP_SEG_SUPPORT
1767 pDevice->TaskOffloadCap |= LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1769 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
1770 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
1771 (pDevice->ChipRevId == T3_CHIP_ID_5705_A0))
1773 pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1775 #endif
1777 #ifdef BCM_ASF
1778 if (pDevice->AsfFlags & ASF_ENABLED)
1780 if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
1782 pDevice->TaskOffloadCap &= ~LM_TASK_OFFLOAD_TCP_SEGMENTATION;
1785 #endif
1787 /* Change driver parameters. */
1788 Status = MM_GetConfig(pDevice);
1789 if(Status != LM_STATUS_SUCCESS)
1791 return Status;
1794 if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
1796 pDevice->Flags &= ~NIC_SEND_BD_FLAG;
1799 /* Save the current phy link status. */
1800 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
1801 !(pDevice->AsfFlags & ASF_ENABLED))
1803 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1804 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1806 /* If we don't have link reset the PHY. */
1807 if(!(Value32 & PHY_STATUS_LINK_PASS) ||
1808 (pDevice->PhyFlags & PHY_RESET_ON_INIT))
1811 LM_ResetPhy(pDevice);
1813 if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
1815 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1816 PHY_AN_AD_ALL_SPEEDS;
1817 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
1818 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
1820 Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS ;
1821 #if INCLUDE_5701_AX_FIX
1822 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1823 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1825 Value32 |= BCM540X_CONFIG_AS_MASTER |
1826 BCM540X_ENABLE_CONFIG_AS_MASTER;
1828 #endif
1829 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
1831 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
1832 PHY_CTRL_RESTART_AUTO_NEG);
1836 LM_SetEthWireSpeed(pDevice);
1838 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &pDevice->advertising);
1839 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG,
1840 &pDevice->advertising1000);
1842 LM_PhyTapPowerMgmt(pDevice);
1844 #if INCLUDE_TBI_SUPPORT
1845 if(pDevice->TbiFlags & ENABLE_TBI_FLAG)
1847 if (!(pDevice->Flags & FIBER_WOL_CAPABLE_FLAG))
1849 pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1851 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1852 if (pDevice->TbiFlags & TBI_PURE_POLLING_FLAG)
1854 pDevice->IgnoreTbiLinkChange = TRUE;
1857 else
1859 pDevice->TbiFlags = 0;
1861 #endif /* INCLUDE_TBI_SUPPORT */
1863 /* UseTaggedStatus is only valid for 5701 and later. */
1864 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
1865 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
1866 ((pDevice->BondId == GRC_MISC_BD_ID_5788) ||
1867 (pDevice->BondId == GRC_MISC_BD_ID_5788M))))
1869 pDevice->Flags &= ~USE_TAGGED_STATUS_FLAG;
1870 pDevice->CoalesceMode = 0;
1872 else
1874 pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1875 HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1878 /* Set the status block size. */
1879 if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1880 T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
1882 pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1885 /* Check the DURING_INT coalescing ticks parameters. */
1886 if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
1888 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1890 pDevice->RxCoalescingTicksDuringInt =
1891 DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1894 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1896 pDevice->TxCoalescingTicksDuringInt =
1897 DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1900 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1902 pDevice->RxMaxCoalescedFramesDuringInt =
1903 DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1906 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1908 pDevice->TxMaxCoalescedFramesDuringInt =
1909 DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1912 else
1914 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1916 pDevice->RxCoalescingTicksDuringInt = 0;
1919 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1921 pDevice->TxCoalescingTicksDuringInt = 0;
1924 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1926 pDevice->RxMaxCoalescedFramesDuringInt = 0;
1929 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1931 pDevice->TxMaxCoalescedFramesDuringInt = 0;
1935 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1936 if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
1938 pDevice->RxJumboDescCnt = 0;
1939 if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1941 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1944 else if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
1946 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1947 pDevice->RxJumboDescCnt = 0;
1949 else
1951 pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
1952 COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
1954 if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
1956 pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1957 pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
1959 pDevice->TxMtu = pDevice->RxMtu;
1962 #else
1963 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1964 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1966 pDevice->RxPacketDescCnt =
1967 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1968 pDevice->RxJumboDescCnt +
1969 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1970 pDevice->RxStdDescCnt;
1972 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1974 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1977 if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
1979 pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1982 /* Configure the proper ways to get link change interrupt. */
1983 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
1985 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1987 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1989 else
1991 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1994 else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
1996 /* Auto-polling does not work on 5700_AX and 5700_BX. */
1997 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1999 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
2003 /* Determine the method to get link change status. */
2004 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
2006 /* The link status bit in the status block does not work on 5700_AX */
2007 /* and 5700_BX chips. */
2008 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2010 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2012 else
2014 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
2018 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
2019 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2021 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2024 if (!EeSigFound)
2026 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
2029 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2030 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
2032 /* bug? 5701 in LINK10 mode does not seem to work when */
2033 /* PhyIntMode is LINK_READY. */
2034 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
2035 #if INCLUDE_TBI_SUPPORT
2036 !(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
2037 #endif
2038 pDevice->LedCtrl == LED_CTRL_PHY_MODE_2)
2040 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
2041 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
2043 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
2045 pDevice->LedCtrl = LED_CTRL_PHY_MODE_1;
2049 #ifdef BCM_WOL
2050 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2051 pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
2052 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
2053 pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
2055 pDevice->WolSpeed = WOL_SPEED_10MB;
2057 else
2059 if (pDevice->Flags & WOL_LIMIT_10MBPS_FLAG)
2061 pDevice->WolSpeed = WOL_SPEED_10MB;
2063 else
2065 pDevice->WolSpeed = WOL_SPEED_100MB;
2068 #endif
2070 pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
2072 pDevice->DmaReadFifoSize = 0;
2073 if (((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
2074 (pDevice->ChipRevId != T3_CHIP_ID_5705_A0)) ||
2075 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750))
2077 #if INCLUDE_TCP_SEG_SUPPORT
2078 if ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION) &&
2079 ((pDevice->ChipRevId == T3_CHIP_ID_5705_A1) ||
2080 (pDevice->ChipRevId == T3_CHIP_ID_5705_A2)))
2082 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_SIZE_128;
2084 else
2085 #endif
2087 if (!(pDevice->PciState & T3_PCI_STATE_HIGH_BUS_SPEED) &&
2088 !(pDevice->Flags & BCM5788_FLAG) &&
2089 !(pDevice->Flags & PCI_EXPRESS_FLAG))
2091 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
2092 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A1)
2094 pDevice->Flags |= RX_BD_LIMIT_64_FLAG;
2096 pDevice->Flags |= DMA_WR_MODE_RX_ACCELERATE_FLAG;
2098 else if (pDevice->Flags & PCI_EXPRESS_FLAG)
2100 pDevice->DmaReadFifoSize = DMA_READ_MODE_FIFO_LONG_BURST;
2105 LM_ReadVPD(pDevice);
2106 LM_ReadBootCodeVersion(pDevice);
2107 LM_GetBusSpeed(pDevice);
2109 return LM_STATUS_SUCCESS;
2110 } /* LM_GetAdapterInfo */
2112 STATIC PLM_ADAPTER_INFO
2113 LM_GetAdapterInfoBySsid(
2114 LM_UINT16 Svid,
2115 LM_UINT16 Ssid)
2117 static LM_ADAPTER_INFO AdapterArr[] =
2119 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
2120 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
2121 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
2122 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
2123 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
2124 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
2125 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
2126 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
2127 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
2128 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5703_PHY_ID, 0},
2129 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5703_PHY_ID, 0},
2131 { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
2132 { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
2133 { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
2134 { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
2135 { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
2137 { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
2138 { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
2139 { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
2140 { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
2142 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
2143 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
2144 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
2145 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
2146 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
2148 { 0x1014, 0x0281, 0, 1 },
2150 LM_UINT32 j;
2152 for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
2154 if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
2156 return &AdapterArr[j];
2160 return NULL;
2165 /******************************************************************************/
2166 /* Description: */
2167 /* This routine sets up receive/transmit buffer descriptions queues. */
2168 /* */
2169 /* Return: */
2170 /* LM_STATUS_SUCCESS */
2171 /******************************************************************************/
2172 LM_STATUS
2173 LM_InitializeAdapter(
2174 PLM_DEVICE_BLOCK pDevice)
2176 LM_PHYSICAL_ADDRESS MemPhy;
2177 PLM_UINT8 pMemVirt;
2178 PLM_PACKET pPacket;
2179 LM_STATUS Status;
2180 LM_UINT32 Size;
2181 LM_UINT32 Value32, j;
2182 LM_UINT32 DmaWrCmd, DmaRdCmd, DmaWrBdry, DmaRdBdry;
2184 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
2185 j = 0;
2186 while (((Value32 & 0x3ff) != (pDevice->PciCommandStatusWords & 0x3ff)) &&
2187 (j < 1000))
2189 /* On PCIE devices, there are some rare cases where the device */
2190 /* is in the process of link-training at this point */
2191 MM_Wait(200);
2192 MM_WriteConfig32(pDevice, PCI_COMMAND_REG, pDevice->PciCommandStatusWords);
2193 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
2194 j++;
2196 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
2197 /* Set power state to D0. */
2198 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
2200 /* Intialize the queues. */
2201 QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
2202 MAX_RX_PACKET_DESC_COUNT);
2203 QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
2204 MAX_RX_PACKET_DESC_COUNT);
2206 QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
2207 QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
2209 if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2211 pDevice->RcvRetRcbEntryCount = 512;
2212 pDevice->RcvRetRcbEntryCountMask = 511;
2214 else
2216 pDevice->RcvRetRcbEntryCount = T3_RCV_RETURN_RCB_ENTRY_COUNT;
2217 pDevice->RcvRetRcbEntryCountMask = T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
2220 /* Allocate shared memory for: status block, the buffers for receive */
2221 /* rings -- standard, mini, jumbo, and return rings. */
2222 Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
2223 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
2224 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2225 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
2226 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2227 (pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
2229 /* Memory for host based Send BD. */
2230 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2232 Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
2235 /* Allocate the memory block. */
2236 Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
2237 if(Status != LM_STATUS_SUCCESS)
2239 return Status;
2242 DmaWrCmd = DMA_CTRL_WRITE_CMD;
2243 DmaRdCmd = DMA_CTRL_READ_CMD;
2244 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_DISABLE;
2245 DmaRdBdry = DMA_CTRL_READ_BOUNDARY_DISABLE;
2246 #ifdef BCM_DISCONNECT_AT_CACHELINE
2247 /* This code is intended for PPC64 and other similar architectures */
2248 /* Only the following chips support this */
2249 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
2250 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) ||
2251 (pDevice->Flags & PCI_EXPRESS_FLAG))
2253 switch(pDevice->CacheLineSize * 4)
2255 case 16:
2256 case 32:
2257 case 64:
2258 case 128:
2259 if (!(pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
2260 !(pDevice->Flags & PCI_EXPRESS_FLAG))
2262 /* PCI-X */
2263 /* use 384 which is a multiple of 16,32,64,128 */
2264 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_384_PCIX;
2265 break;
2267 else if (pDevice->Flags & PCI_EXPRESS_FLAG)
2269 /* PCI Express */
2270 /* use 128 which is a multiple of 16,32,64,128 */
2271 DmaWrCmd = DMA_CTRL_WRITE_BOUNDARY_128_PCIE;
2272 break;
2274 /* fall through */
2275 case 256:
2276 /* use 256 which is a multiple of 16,32,64,128,256 */
2277 if ((pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) &&
2278 !(pDevice->Flags & PCI_EXPRESS_FLAG))
2280 /* PCI */
2281 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256;
2283 else if (!(pDevice->Flags & PCI_EXPRESS_FLAG))
2285 /* PCI-X */
2286 DmaWrBdry = DMA_CTRL_WRITE_BOUNDARY_256_PCIX;
2288 break;
2291 #endif
2292 pDevice->DmaReadWriteCtrl = DmaWrCmd | DmaRdCmd | DmaWrBdry | DmaRdBdry;
2293 /* Program DMA Read/Write */
2294 if (pDevice->Flags & PCI_EXPRESS_FLAG)
2296 pDevice->DmaReadWriteCtrl |= 0x001f0000;
2298 else if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
2300 if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2302 pDevice->DmaReadWriteCtrl |= 0x003f0000;
2304 else
2306 pDevice->DmaReadWriteCtrl |= 0x003f000f;
2309 else
2311 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2312 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
2314 /* set bit 23 to enable a PCIX hardware fix */
2315 pDevice->DmaReadWriteCtrl |= 0x009f0000;
2317 Value32 = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
2318 if ((Value32 == 0x6) || (Value32 == 0x7))
2320 pDevice->Flags |= ONE_DMA_AT_ONCE_FLAG;
2323 else
2325 pDevice->DmaReadWriteCtrl |= 0x001b000f;
2328 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) ||
2329 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
2331 pDevice->DmaReadWriteCtrl &= 0xfffffff0;
2334 if (pDevice->Flags & ONE_DMA_AT_ONCE_FLAG)
2336 pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
2338 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2340 LM_SwitchClocks(pDevice);
2342 if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
2344 return LM_STATUS_FAILURE;
2347 /* Status block. */
2348 pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
2349 pDevice->StatusBlkPhy = MemPhy;
2350 pMemVirt += T3_STATUS_BLOCK_SIZE;
2351 LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
2353 /* Statistics block. */
2354 pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
2355 pDevice->StatsBlkPhy = MemPhy;
2356 pMemVirt += sizeof(T3_STATS_BLOCK);
2357 LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
2359 /* Receive standard BD buffer. */
2360 pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
2361 pDevice->RxStdBdPhy = MemPhy;
2363 pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
2364 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2365 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
2367 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2368 /* Receive jumbo BD buffer. */
2369 pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
2370 pDevice->RxJumboBdPhy = MemPhy;
2372 pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
2373 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2374 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
2375 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2377 /* Receive return BD buffer. */
2378 pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
2379 pDevice->RcvRetBdPhy = MemPhy;
2381 pMemVirt += pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD);
2382 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2383 pDevice->RcvRetRcbEntryCount * sizeof(T3_RCV_BD));
2385 /* Set up Send BD. */
2386 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2388 pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
2389 pDevice->SendBdPhy = MemPhy;
2391 pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
2392 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
2393 sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
2395 #ifdef BCM_NIC_SEND_BD
2396 else
2398 pDevice->pSendBdVirt = (PT3_SND_BD)
2399 pDevice->pMemView->uIntMem.First32k.BufferDesc;
2400 pDevice->SendBdPhy.High = 0;
2401 pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
2403 #endif
2405 /* Allocate memory for packet descriptors. */
2406 Size = (pDevice->RxPacketDescCnt +
2407 pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
2408 Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
2409 if(Status != LM_STATUS_SUCCESS)
2411 return Status;
2413 pDevice->pPacketDescBase = (PLM_VOID) pPacket;
2415 /* Create transmit packet descriptors from the memory block and add them */
2416 /* to the TxPacketFreeQ for each send ring. */
2417 for(j = 0; j < pDevice->TxPacketDescCnt; j++)
2419 /* Ring index. */
2420 pPacket->Flags = 0;
2422 /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
2423 QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
2425 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
2426 /* is the total size of the packet descriptor including the */
2427 /* os-specific extensions in the UM_PACKET structure. */
2428 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2429 } /* for(j.. */
2431 /* Create receive packet descriptors from the memory block and add them */
2432 /* to the RxPacketFreeQ. Create the Standard packet descriptors. */
2433 for(j = 0; j < pDevice->RxStdDescCnt; j++)
2435 /* Receive producer ring. */
2436 pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
2438 /* Receive buffer size. */
2439 pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
2441 /* Add the descriptor to RxPacketFreeQ. */
2442 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
2444 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
2445 /* is the total size of the packet descriptor including the */
2446 /* os-specific extensions in the UM_PACKET structure. */
2447 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2448 } /* for */
2450 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2451 /* Create the Jumbo packet descriptors. */
2452 for(j = 0; j < pDevice->RxJumboDescCnt; j++)
2454 /* Receive producer ring. */
2455 pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
2457 /* Receive buffer size. */
2458 pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
2460 /* Add the descriptor to RxPacketFreeQ. */
2461 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
2463 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
2464 /* is the total size of the packet descriptor including the */
2465 /* os-specific extensions in the UM_PACKET structure. */
2466 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
2467 } /* for */
2468 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2470 /* Initialize the rest of the packet descriptors. */
2471 Status = MM_InitializeUmPackets(pDevice);
2472 if(Status != LM_STATUS_SUCCESS)
2474 return Status;
2475 } /* if */
2477 /* Default receive mask. */
2478 pDevice->ReceiveMask &= LM_KEEP_VLAN_TAG;
2479 pDevice->ReceiveMask |= LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
2480 LM_ACCEPT_UNICAST;
2482 /* Make sure we are in the first 32k memory window or NicSendBd. */
2483 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
2485 /* Initialize the hardware. */
2486 Status = LM_ResetAdapter(pDevice);
2487 if(Status != LM_STATUS_SUCCESS)
2489 return Status;
2492 /* We are done with initialization. */
2493 pDevice->InitDone = TRUE;
2495 return LM_STATUS_SUCCESS;
2496 } /* LM_InitializeAdapter */
2499 LM_STATUS
2500 LM_DisableChip(PLM_DEVICE_BLOCK pDevice)
2502 LM_UINT32 data;
2504 pDevice->RxMode &= ~RX_MODE_ENABLE;
2505 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2506 if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
2508 MM_Wait(20);
2510 data = REG_RD(pDevice, RcvBdIn.Mode);
2511 data &= ~RCV_BD_IN_MODE_ENABLE;
2512 REG_WR(pDevice, RcvBdIn.Mode,data);
2513 if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
2515 MM_Wait(20);
2517 data = REG_RD(pDevice, RcvListPlmt.Mode);
2518 data &= ~RCV_LIST_PLMT_MODE_ENABLE;
2519 REG_WR(pDevice, RcvListPlmt.Mode,data);
2520 if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
2522 MM_Wait(20);
2524 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2526 data = REG_RD(pDevice, RcvListSel.Mode);
2527 data &= ~RCV_LIST_SEL_MODE_ENABLE;
2528 REG_WR(pDevice, RcvListSel.Mode,data);
2529 if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
2531 MM_Wait(20);
2534 data = REG_RD(pDevice, RcvDataBdIn.Mode);
2535 data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
2536 REG_WR(pDevice, RcvDataBdIn.Mode,data);
2537 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
2539 MM_Wait(20);
2541 data = REG_RD(pDevice, RcvDataComp.Mode);
2542 data &= ~RCV_DATA_COMP_MODE_ENABLE;
2543 REG_WR(pDevice, RcvDataComp.Mode,data);
2544 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
2546 MM_Wait(20);
2548 data = REG_RD(pDevice, RcvBdComp.Mode);
2549 data &= ~RCV_BD_COMP_MODE_ENABLE;
2550 REG_WR(pDevice, RcvBdComp.Mode,data);
2551 if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
2553 MM_Wait(20);
2555 data = REG_RD(pDevice, SndBdSel.Mode);
2556 data &= ~SND_BD_SEL_MODE_ENABLE;
2557 REG_WR(pDevice, SndBdSel.Mode, data);
2558 if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
2560 MM_Wait(20);
2562 data = REG_RD(pDevice, SndBdIn.Mode);
2563 data &= ~SND_BD_IN_MODE_ENABLE;
2564 REG_WR(pDevice, SndBdIn.Mode, data);
2565 if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
2567 MM_Wait(20);
2569 data = REG_RD(pDevice, SndDataIn.Mode);
2570 data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2571 REG_WR(pDevice, SndDataIn.Mode,data);
2572 if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
2574 MM_Wait(20);
2576 data = REG_RD(pDevice, DmaRead.Mode);
2577 data &= ~DMA_READ_MODE_ENABLE;
2578 REG_WR(pDevice, DmaRead.Mode, data);
2579 if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
2581 MM_Wait(20);
2583 data = REG_RD(pDevice, SndDataComp.Mode);
2584 data &= ~SND_DATA_COMP_MODE_ENABLE;
2585 REG_WR(pDevice, SndDataComp.Mode, data);
2586 if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
2588 MM_Wait(20);
2590 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2592 data = REG_RD(pDevice,DmaComp.Mode);
2593 data &= ~DMA_COMP_MODE_ENABLE;
2594 REG_WR(pDevice, DmaComp.Mode, data);
2595 if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
2597 MM_Wait(20);
2600 data = REG_RD(pDevice, SndBdComp.Mode);
2601 data &= ~SND_BD_COMP_MODE_ENABLE;
2602 REG_WR(pDevice, SndBdComp.Mode, data);
2603 if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
2605 MM_Wait(20);
2607 /* Clear TDE bit */
2608 pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
2609 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
2610 pDevice->TxMode &= ~TX_MODE_ENABLE;
2611 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2612 if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
2614 MM_Wait(20);
2616 data = REG_RD(pDevice, HostCoalesce.Mode);
2617 data &= ~HOST_COALESCE_ENABLE;
2618 REG_WR(pDevice, HostCoalesce.Mode, data);
2619 if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
2621 MM_Wait(20);
2623 data = REG_RD(pDevice, DmaWrite.Mode);
2624 data &= ~DMA_WRITE_MODE_ENABLE;
2625 REG_WR(pDevice, DmaWrite.Mode,data);
2626 if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
2628 MM_Wait(20);
2630 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2632 data = REG_RD(pDevice, MbufClusterFree.Mode);
2633 data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
2634 REG_WR(pDevice, MbufClusterFree.Mode,data);
2635 if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
2637 MM_Wait(20);
2640 /* Reset all FTQs */
2641 REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2642 REG_WR(pDevice, Ftq.Reset, 0x0);
2644 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2646 data = REG_RD(pDevice, BufMgr.Mode);
2647 data &= ~BUFMGR_MODE_ENABLE;
2648 REG_WR(pDevice, BufMgr.Mode,data);
2649 if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
2651 MM_Wait(20);
2653 data = REG_RD(pDevice, MemArbiter.Mode);
2654 data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2655 REG_WR(pDevice, MemArbiter.Mode, data);
2656 if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
2658 MM_Wait(20);
2661 return LM_STATUS_SUCCESS;
2664 LM_STATUS
2665 LM_DisableFW(PLM_DEVICE_BLOCK pDevice)
2667 #ifdef BCM_ASF
2668 int j;
2669 LM_UINT32 Value32;
2671 if (pDevice->AsfFlags & ASF_ENABLED)
2673 MEM_WR_OFFSET(pDevice, T3_CMD_MAILBOX, T3_CMD_NICDRV_PAUSE_FW);
2674 Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
2675 REG_WR(pDevice, Grc.RxCpuEvent, Value32 | BIT_14);
2676 for (j = 0; j < 100; j++)
2678 Value32 = REG_RD(pDevice, Grc.RxCpuEvent);
2679 if (!(Value32 & BIT_14))
2681 break;
2683 MM_Wait(1);
2686 #endif
2687 return LM_STATUS_SUCCESS;
2690 /******************************************************************************/
2691 /* Description: */
2692 /* This function reinitializes the adapter. */
2693 /* */
2694 /* Return: */
2695 /* LM_STATUS_SUCCESS */
2696 /******************************************************************************/
2697 LM_STATUS
2698 LM_ResetAdapter(
2699 PLM_DEVICE_BLOCK pDevice)
2701 LM_UINT32 Value32;
2702 LM_UINT32 j, k;
2703 int reset_count = 0;
2705 /* Disable interrupt. */
2706 LM_DisableInterrupt(pDevice);
2708 restart_reset:
2709 LM_DisableFW(pDevice);
2711 /* May get a spurious interrupt */
2712 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2714 LM_WritePreResetSignatures(pDevice, LM_INIT_RESET);
2715 /* Disable transmit and receive DMA engines. Abort all pending requests. */
2716 if(pDevice->InitDone)
2718 LM_Abort(pDevice);
2721 pDevice->ShuttingDown = FALSE;
2723 LM_ResetChip(pDevice);
2725 LM_WriteLegacySignatures(pDevice, LM_INIT_RESET);
2727 /* Bug: Athlon fix for B3 silicon only. This bit does not do anything */
2728 /* in other chip revisions except 5750 */
2729 if ((pDevice->Flags & DELAY_PCI_GRANT_FLAG) &&
2730 !(pDevice->Flags & PCI_EXPRESS_FLAG))
2732 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | BIT_31);
2735 if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2737 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2739 Value32 = REG_RD(pDevice, PciCfg.PciState);
2740 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2741 REG_WR(pDevice, PciCfg.PciState, Value32);
2744 if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5704_BX)
2746 /* New bits defined in register 0x64 to enable some h/w fixes */
2747 /* These new bits are 'write-only' */
2748 Value32 = REG_RD(pDevice, PciCfg.MsiData);
2749 REG_WR(pDevice, PciCfg.MsiData, Value32 | BIT_26 | BIT_28 | BIT_29);
2752 /* Enable TaggedStatus mode. */
2753 if (pDevice->Flags & USE_TAGGED_STATUS_FLAG)
2755 pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2758 /* Restore PCI configuration registers. */
2759 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
2760 pDevice->SavedCacheLineReg);
2761 // LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2762 // (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2763 MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2764 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2766 /* Initialize the statistis Block */
2767 pDevice->pStatusBlkVirt->Status = 0;
2768 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2769 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2770 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2772 for(j = 0; j < 16; j++)
2774 pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2775 pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2778 for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
2780 pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2781 pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2782 pDevice->pRxStdBdVirt[k].Flags = RCV_BD_FLAG_END;
2783 pDevice->pRxStdBdVirt[k].Len = MAX_STD_RCV_BUFFER_SIZE;
2786 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2787 /* Receive jumbo BD buffer. */
2788 for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
2790 pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2791 pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2792 pDevice->pRxJumboBdVirt[k].Flags = RCV_BD_FLAG_END |
2793 RCV_BD_FLAG_JUMBO_RING;
2794 pDevice->pRxJumboBdVirt[k].Len = (LM_UINT16) pDevice->RxJumboBufferSize;
2796 #endif
2798 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2800 /* GRC mode control register. */
2801 Value32 =
2802 #ifdef BIG_ENDIAN_HOST
2803 GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2804 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2805 GRC_MODE_BYTE_SWAP_DATA |
2806 GRC_MODE_WORD_SWAP_DATA |
2807 #else
2808 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2809 GRC_MODE_BYTE_SWAP_DATA |
2810 GRC_MODE_WORD_SWAP_DATA |
2811 #endif
2812 GRC_MODE_INT_ON_MAC_ATTN |
2813 GRC_MODE_HOST_STACK_UP;
2815 /* Configure send BD mode. */
2816 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
2818 Value32 |= GRC_MODE_HOST_SEND_BDS;
2820 #ifdef BCM_NIC_SEND_BD
2821 else
2823 Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2825 #endif
2827 /* Configure pseudo checksum mode. */
2828 if (pDevice->Flags & NO_TX_PSEUDO_HDR_CSUM_FLAG)
2830 Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2833 if (pDevice->Flags & NO_RX_PSEUDO_HDR_CSUM_FLAG)
2835 Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2838 pDevice->GrcMode = Value32;
2839 REG_WR(pDevice, Grc.Mode, Value32);
2841 /* Setup the timer prescalar register. */
2842 Value32 = REG_RD(pDevice, Grc.MiscCfg) & ~0xff;
2843 /* Clock is always 66Mhz. */
2844 REG_WR(pDevice, Grc.MiscCfg, Value32 | (65 << 1));
2846 /* Set up the MBUF pool base address and size. */
2847 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
2849 #if INCLUDE_TCP_SEG_SUPPORT
2850 if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
2852 Value32 = LM_GetStkOffLdFirmwareSize(pDevice);
2853 Value32 = (Value32 + 0x7f) & ~0x7f;
2854 pDevice->MbufBase = T3_NIC_BCM5705_MBUF_POOL_ADDR + Value32;
2855 pDevice->MbufSize = T3_NIC_BCM5705_MBUF_POOL_SIZE - Value32 - 0xa00;
2856 REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2857 REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2859 #endif
2861 else if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
2863 REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2864 REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2866 /* Set up the DMA descriptor pool base address and size. */
2867 REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2868 REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2872 /* Configure MBUF and Threshold watermarks */
2873 /* Configure the DMA read MBUF low water mark. */
2874 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2876 if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2878 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2879 T3_DEF_DMA_MBUF_LOW_WMARK_5705);
2880 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2881 T3_DEF_RX_MAC_MBUF_LOW_WMARK_5705);
2882 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2883 T3_DEF_MBUF_HIGH_WMARK_5705);
2885 else
2887 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2888 T3_DEF_DMA_MBUF_LOW_WMARK);
2889 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2890 T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2891 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2892 T3_DEF_MBUF_HIGH_WMARK);
2895 else
2897 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2898 T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2899 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2900 T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2901 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2902 T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2905 REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2906 REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2908 /* Enable buffer manager. */
2909 REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2911 for(j = 0 ;j < 2000; j++)
2913 if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2914 break;
2915 MM_Wait(10);
2918 if(j >= 2000)
2920 return LM_STATUS_FAILURE;
2923 /* GRC reset will reset FTQ */
2924 #if 0
2925 /* Enable the FTQs. */
2926 REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2927 REG_WR(pDevice, Ftq.Reset, 0);
2929 /* Wait until FTQ is ready */
2930 for(j = 0; j < 2000; j++)
2932 if(REG_RD(pDevice, Ftq.Reset) == 0)
2933 break;
2934 MM_Wait(10);
2937 if(j >= 2000)
2939 return LM_STATUS_FAILURE;
2941 #endif
2943 /* Receive BD Ring replenish threshold. */
2944 REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
2946 /* Initialize the Standard Receive RCB. */
2947 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2948 pDevice->RxStdBdPhy.High);
2949 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2950 pDevice->RxStdBdPhy.Low);
2951 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2952 (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2954 if(T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
2956 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2957 512 << 16);
2959 else
2961 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2962 MAX_STD_RCV_BUFFER_SIZE << 16);
2964 /* Initialize the Jumbo Receive RCB. */
2965 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2966 T3_RCB_FLAG_RING_DISABLED);
2967 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2968 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2969 pDevice->RxJumboBdPhy.High);
2970 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2971 pDevice->RxJumboBdPhy.Low);
2972 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2973 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2974 (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2976 REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
2978 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2980 /* Initialize the Mini Receive RCB. */
2981 REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2982 T3_RCB_FLAG_RING_DISABLED);
2984 /* Disable all the unused rings. */
2985 for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2986 MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags,
2987 T3_RCB_FLAG_RING_DISABLED);
2988 } /* for */
2992 /* Initialize the indices. */
2993 pDevice->SendProdIdx = 0;
2994 pDevice->SendConIdx = 0;
2996 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2997 MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
2998 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2999 MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
3001 /* Set up host or NIC based send RCB. */
3002 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3004 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
3005 pDevice->SendBdPhy.High);
3006 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
3007 pDevice->SendBdPhy.Low);
3009 /* Setup the RCB. */
3010 MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
3011 T3_SEND_RCB_ENTRY_COUNT << 16);
3013 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3015 /* Set up the NIC ring address in the RCB. */
3016 MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
3018 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
3020 pDevice->pSendBdVirt[k].HostAddr.High = 0;
3021 pDevice->pSendBdVirt[k].HostAddr.Low = 0;
3024 #ifdef BCM_NIC_SEND_BD
3025 else
3027 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
3028 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
3029 MEM_WR(pDevice, SendRcb[0].NicRingAddr,
3030 pDevice->SendBdPhy.Low);
3032 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
3034 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.High), 0);
3035 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].HostAddr.Low), 0);
3036 MM_MEMWRITEL(&(pDevice->pSendBdVirt[k].u1.Len_Flags), 0);
3037 pDevice->ShadowSendBd[k].HostAddr.High = 0;
3038 pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
3041 #endif
3042 MM_ATOMIC_SET(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
3044 /* Configure the receive return rings. */
3045 for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
3047 MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
3050 pDevice->RcvRetConIdx = 0;
3052 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
3053 pDevice->RcvRetBdPhy.High);
3054 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
3055 pDevice->RcvRetBdPhy.Low);
3057 MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
3059 /* Setup the RCB. */
3060 MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
3061 pDevice->RcvRetRcbEntryCount << 16);
3063 /* Reinitialize RX ring producer index */
3064 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
3065 MB_REG_RD(pDevice, Mailbox.RcvStdProdIdx.Low);
3066 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
3067 MB_REG_RD(pDevice, Mailbox.RcvJumboProdIdx.Low);
3068 MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
3069 MB_REG_RD(pDevice, Mailbox.RcvMiniProdIdx.Low);
3071 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3072 pDevice->RxJumboProdIdx = 0;
3073 pDevice->RxJumboQueuedCnt = 0;
3074 #endif
3076 /* Reinitialize our copy of the indices. */
3077 pDevice->RxStdProdIdx = 0;
3078 pDevice->RxStdQueuedCnt = 0;
3080 #if T3_JUMBO_RCV_ENTRY_COUNT
3081 pDevice->RxJumboProdIdx = 0;
3082 #endif /* T3_JUMBO_RCV_ENTRY_COUNT */
3084 /* Configure the MAC address. */
3085 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
3087 /* Initialize the transmit random backoff seed. */
3088 Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
3089 pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
3090 pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
3091 MAC_TX_BACKOFF_SEED_MASK;
3092 REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
3094 /* Receive MTU. Frames larger than the MTU is marked as oversized. */
3095 REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8); /* CRC + VLAN. */
3097 /* Configure Time slot/IPG per 802.3 */
3098 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
3101 * Configure Receive Rules so that packets don't match
3102 * Programmble rule will be queued to Return Ring 1
3104 REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
3107 * Configure to have 16 Classes of Services (COS) and one
3108 * queue per class. Bad frames are queued to RRR#1.
3109 * And frames don't match rules are also queued to COS#1.
3111 REG_WR(pDevice, RcvListPlmt.Config, 0x181);
3113 /* Enable Receive Placement Statistics */
3114 if ((pDevice->DmaReadFifoSize == DMA_READ_MODE_FIFO_LONG_BURST) &&
3115 (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION))
3117 Value32 = REG_RD(pDevice, RcvListPlmt.StatsEnableMask);
3118 Value32 &= ~T3_DISABLE_LONG_BURST_READ_DYN_FIX;
3119 REG_WR(pDevice, RcvListPlmt.StatsEnableMask, Value32);
3121 else
3123 REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
3125 REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
3127 /* Enable Send Data Initator Statistics */
3128 REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
3129 REG_WR(pDevice, SndDataIn.StatsCtrl,
3130 T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
3131 T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
3133 /* Disable the host coalescing state machine before configuring it's */
3134 /* parameters. */
3135 REG_WR(pDevice, HostCoalesce.Mode, 0);
3136 for(j = 0; j < 2000; j++)
3138 Value32 = REG_RD(pDevice, HostCoalesce.Mode);
3139 if(!(Value32 & HOST_COALESCE_ENABLE))
3141 break;
3143 MM_Wait(10);
3146 /* Host coalescing configurations. */
3147 REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
3148 REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
3149 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
3150 pDevice->RxMaxCoalescedFrames);
3151 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
3152 pDevice->TxMaxCoalescedFrames);
3153 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3155 REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
3156 pDevice->RxCoalescingTicksDuringInt);
3157 REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
3158 pDevice->TxCoalescingTicksDuringInt);
3160 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
3161 pDevice->RxMaxCoalescedFramesDuringInt);
3162 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
3163 pDevice->TxMaxCoalescedFramesDuringInt);
3165 /* Initialize the address of the status block. The NIC will DMA */
3166 /* the status block to this memory which resides on the host. */
3167 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
3168 pDevice->StatusBlkPhy.High);
3169 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
3170 pDevice->StatusBlkPhy.Low);
3172 /* Initialize the address of the statistics block. The NIC will DMA */
3173 /* the statistics to this block of memory. */
3174 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3176 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
3177 pDevice->StatsBlkPhy.High);
3178 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
3179 pDevice->StatsBlkPhy.Low);
3181 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
3182 pDevice->StatsCoalescingTicks);
3184 REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
3185 REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
3188 /* Enable Host Coalesing state machine */
3189 REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
3190 pDevice->CoalesceMode);
3192 /* Enable the Receive BD Completion state machine. */
3193 REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
3194 RCV_BD_COMP_MODE_ATTN_ENABLE);
3196 /* Enable the Receive List Placement state machine. */
3197 REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
3199 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3201 /* Enable the Receive List Selector state machine. */
3202 REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
3203 RCV_LIST_SEL_MODE_ATTN_ENABLE);
3206 /* Clear the statistics block. */
3207 for(j = 0x0300; j < 0x0b00; j = j + 4)
3209 MEM_WR_OFFSET(pDevice, j, 0);
3212 /* Enable transmit DMA, clear statistics. */
3213 pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
3214 MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
3215 MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
3216 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
3217 MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
3219 /* GRC miscellaneous local control register. */
3220 pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
3221 GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
3223 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3225 pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
3226 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
3228 else if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) &&
3229 !(pDevice->Flags & EEPROM_WP_FLAG))
3231 /* Make sure we're on Vmain */
3232 /* The other port may cause us to be on Vaux */
3233 pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
3234 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2;
3237 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
3238 MM_Wait(40);
3240 /* Reset RX counters. */
3241 for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
3243 ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
3246 /* Reset TX counters. */
3247 for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
3249 ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
3252 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
3253 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3254 pDevice->LastTag = 0;
3256 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3258 /* Enable the DMA Completion state machine. */
3259 REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
3262 /* Enable the DMA Write state machine. */
3263 Value32 = DMA_WRITE_MODE_ENABLE |
3264 DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
3265 DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
3266 DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
3267 DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
3268 DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
3269 DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
3270 DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
3271 DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
3273 if (pDevice->Flags & DMA_WR_MODE_RX_ACCELERATE_FLAG)
3275 Value32 |= DMA_WRITE_MODE_RECEIVE_ACCELERATE;
3277 REG_WR(pDevice, DmaWrite.Mode, Value32);
3279 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
3281 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
3283 Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
3284 Value32 &= ~PCIX_CMD_MAX_BURST_MASK;
3285 Value32 |= PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL;
3286 REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
3288 else if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3290 Value32 = REG_RD(pDevice, PciCfg.PciXCapabilities);
3291 Value32 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
3292 Value32 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
3293 PCIX_CMD_MAX_BURST_MASK);
3294 if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
3296 Value32 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
3297 & PCIX_CMD_MAX_SPLIT_MASK;
3299 REG_WR(pDevice, PciCfg.PciXCapabilities, Value32);
3303 /* Enable the Read DMA state machine. */
3304 Value32 = DMA_READ_MODE_ENABLE |
3305 DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
3306 DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
3307 DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
3308 DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
3309 DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
3310 DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
3311 DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
3312 DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
3314 if (pDevice->Flags & MULTI_SPLIT_ENABLE_FLAG)
3316 Value32 |= DMA_READ_MODE_MULTI_SPLIT_ENABLE;
3319 if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3321 Value32 |= pDevice->DmaReadFifoSize;
3323 #if INCLUDE_TCP_SEG_SUPPORT
3324 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3326 Value32 |= BIT_27;
3328 #endif
3331 REG_WR(pDevice, DmaRead.Mode, Value32);
3333 /* Enable the Receive Data Completion state machine. */
3334 REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
3335 RCV_DATA_COMP_MODE_ATTN_ENABLE);
3337 if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3339 /* Enable the Mbuf Cluster Free state machine. */
3340 REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
3343 /* Enable the Send Data Completion state machine. */
3344 REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
3346 /* Enable the Send BD Completion state machine. */
3347 REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
3348 SND_BD_COMP_MODE_ATTN_ENABLE);
3350 /* Enable the Receive BD Initiator state machine. */
3351 REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
3352 RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
3354 /* Enable the Receive Data and Receive BD Initiator state machine. */
3355 REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
3356 RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
3358 /* Enable the Send Data Initiator state machine. */
3359 REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
3361 #if INCLUDE_TCP_SEG_SUPPORT
3362 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3364 REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE | 0x8);
3366 #endif
3368 /* Enable the Send BD Initiator state machine. */
3369 REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
3370 SND_BD_IN_MODE_ATTN_ENABLE);
3372 /* Enable the Send BD Selector state machine. */
3373 REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
3374 SND_BD_SEL_MODE_ATTN_ENABLE);
3376 #if INCLUDE_5701_AX_FIX
3377 /* Load the firmware for the 5701_A0 workaround. */
3378 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
3380 LM_LoadRlsFirmware(pDevice);
3382 #endif
3384 /* Queue Rx packet buffers. */
3385 if(pDevice->QueueRxPackets)
3387 LM_QueueRxPackets(pDevice);
3390 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
3392 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
3393 j = 0;
3394 while ((Value32 != MAX_STD_RCV_BUFFER_SIZE) && (j < 10))
3396 MM_Wait(20);
3397 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_STD_RCV_BUFFER_DESC_ADDR + 8);
3398 j++;
3400 if (j >= 10)
3402 reset_count++;
3403 LM_Abort(pDevice);
3404 if (reset_count > 5)
3405 return LM_STATUS_FAILURE;
3406 goto restart_reset;
3410 /* Enable the transmitter. */
3411 pDevice->TxMode = TX_MODE_ENABLE;
3412 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
3414 /* Enable the receiver. */
3415 pDevice->RxMode = (pDevice->RxMode & RX_MODE_KEEP_VLAN_TAG) |
3416 RX_MODE_ENABLE;
3417 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
3419 #ifdef BCM_WOL
3420 if (pDevice->RestoreOnWakeUp)
3422 pDevice->RestoreOnWakeUp = FALSE;
3423 pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
3424 pDevice->RequestedLineSpeed = pDevice->WakeUpRequestedLineSpeed;
3425 pDevice->RequestedDuplexMode = pDevice->WakeUpRequestedDuplexMode;
3427 #endif
3429 /* Disable auto polling. */
3430 pDevice->MiMode = 0xc0000;
3431 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
3433 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
3435 /* Activate Link to enable MAC state machine */
3436 REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
3438 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
3440 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
3441 REG_RD_BACK(pDevice, MacCtrl.RxMode);
3442 MM_Wait(10);
3443 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
3444 if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
3446 REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
3448 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
3450 /* Set SerDes drive transmission level to 1.2V */
3451 Value32 = REG_RD(pDevice, MacCtrl.SerdesCfg) & 0xfffff000;
3452 REG_WR(pDevice, MacCtrl.SerdesCfg, Value32 | 0x880);
3456 REG_WR(pDevice, MacCtrl.LowWaterMarkMaxRxFrame, 2);
3458 if (!pDevice->InitDone)
3460 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
3463 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
3464 ((pDevice->PhyId & PHY_ID_MASK) != PHY_BCM5401_PHY_ID))
3466 /* 5401 PHY needs a delay of about 1 second after PHY reset */
3467 /* Without the delay, it has problem linking at forced 10 half */
3468 /* So skip the reset... */
3469 LM_ResetPhy(pDevice);
3472 /* Setup the phy chip. */
3473 LM_SetupPhy(pDevice);
3475 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG)) {
3476 /* Clear CRC stats */
3477 LM_ReadPhy(pDevice, 0x1e, &Value32);
3478 LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
3479 LM_ReadPhy(pDevice, 0x14, &Value32);
3482 /* Set up the receive mask. */
3483 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
3485 #if INCLUDE_TCP_SEG_SUPPORT
3486 if (pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION)
3488 if (LM_LoadStkOffLdFirmware(pDevice) == LM_STATUS_FAILURE)
3490 return LM_STATUS_FAILURE;
3493 #endif
3494 LM_WritePostResetSignatures(pDevice, LM_INIT_RESET);
3496 return LM_STATUS_SUCCESS;
3497 } /* LM_ResetAdapter */
3500 /******************************************************************************/
3501 /* Description: */
3502 /* This routine disables the adapter from generating interrupts. */
3503 /* */
3504 /* Return: */
3505 /* LM_STATUS_SUCCESS */
3506 /******************************************************************************/
3507 LM_STATUS
3508 LM_DisableInterrupt(
3509 PLM_DEVICE_BLOCK pDevice)
3511 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
3512 MISC_HOST_CTRL_MASK_PCI_INT);
3513 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
3514 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3516 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3519 return LM_STATUS_SUCCESS;
3524 /******************************************************************************/
3525 /* Description: */
3526 /* This routine enables the adapter to generate interrupts. */
3527 /* */
3528 /* Return: */
3529 /* LM_STATUS_SUCCESS */
3530 /******************************************************************************/
3531 LM_STATUS
3532 LM_EnableInterrupt(
3533 PLM_DEVICE_BLOCK pDevice)
3535 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, pDevice->LastTag << 24);
3536 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3538 MB_REG_RD(pDevice, Mailbox.Interrupt[0].Low);
3541 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
3542 ~MISC_HOST_CTRL_MASK_PCI_INT);
3544 REG_WR(pDevice, HostCoalesce.Mode, pDevice->CoalesceMode |
3545 HOST_COALESCE_ENABLE | HOST_COALESCE_NOW);
3547 return LM_STATUS_SUCCESS;
3552 /******************************************************************************/
3553 /* Description: */
3554 /* This routine puts a packet on the wire if there is a transmit DMA */
3555 /* descriptor available; otherwise the packet is queued for later */
3556 /* transmission. If the second argue is NULL, this routine will put */
3557 /* the queued packet on the wire if possible. */
3558 /* */
3559 /* Return: */
3560 /* LM_STATUS_SUCCESS */
3561 /******************************************************************************/
3562 LM_STATUS
3563 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3565 LM_UINT32 FragCount;
3566 PT3_SND_BD pSendBd, pTmpSendBd;
3567 #ifdef BCM_NIC_SEND_BD
3568 PT3_SND_BD pShadowSendBd;
3569 T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
3570 #endif
3571 LM_UINT32 StartIdx, Idx;
3573 while (1)
3575 /* Initalize the send buffer descriptors. */
3576 StartIdx = Idx = pDevice->SendProdIdx;
3578 #ifdef BCM_NIC_SEND_BD
3579 if (pDevice->Flags & NIC_SEND_BD_FLAG)
3581 pTmpSendBd = pSendBd = &NicSendBdArr[0];
3583 else
3584 #endif
3586 pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
3589 /* Next producer index. */
3590 for(FragCount = 0; ; )
3592 LM_UINT32 Value32, Len;
3594 /* Initialize the pointer to the send buffer fragment. */
3595 MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3597 pSendBd->u2.VlanTag = pPacket->VlanTag;
3599 /* Setup the control flags and send buffer size. */
3600 Value32 = (Len << 16) | pPacket->Flags;
3602 #if INCLUDE_TCP_SEG_SUPPORT
3603 if (Value32 & (SND_BD_FLAG_CPU_PRE_DMA | SND_BD_FLAG_CPU_POST_DMA))
3605 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
3607 pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
3609 else if (FragCount == 0)
3611 pSendBd->u2.s2.Reserved = pPacket->u.Tx.MaxSegmentSize;
3613 else
3615 pSendBd->u2.s2.Reserved = 0;
3616 Value32 &= 0xffff0fff;
3619 #endif
3620 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3622 FragCount++;
3623 if (FragCount >= pPacket->u.Tx.FragCount)
3625 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3626 break;
3628 else
3630 pSendBd->u1.Len_Flags = Value32;
3633 pSendBd++;
3634 if ((Idx == 0) &&
3635 !(pDevice->Flags & NIC_SEND_BD_FLAG))
3637 pSendBd = &pDevice->pSendBdVirt[0];
3640 pDevice->SendRing[Idx] = 0;
3642 } /* for */
3643 if (pDevice->Flags & TX_4G_WORKAROUND_FLAG)
3645 if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
3646 LM_STATUS_SUCCESS)
3648 if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
3650 QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
3651 return LM_STATUS_FAILURE;
3653 continue;
3656 break;
3658 /* Put the packet descriptor in the ActiveQ. */
3659 pDevice->SendRing[StartIdx] = pPacket;
3661 #ifdef BCM_NIC_SEND_BD
3662 if (pDevice->Flags & NIC_SEND_BD_FLAG)
3664 pSendBd = &pDevice->pSendBdVirt[StartIdx];
3665 pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
3667 while (StartIdx != Idx)
3669 LM_UINT32 Value32;
3671 if ((Value32 = pTmpSendBd->HostAddr.High) !=
3672 pShadowSendBd->HostAddr.High)
3674 MM_MEMWRITEL(&(pSendBd->HostAddr.High), Value32);
3675 pShadowSendBd->HostAddr.High = Value32;
3678 MM_MEMWRITEL(&(pSendBd->HostAddr.Low), pTmpSendBd->HostAddr.Low);
3680 if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3681 pShadowSendBd->u1.Len_Flags)
3683 MM_MEMWRITEL(&(pSendBd->u1.Len_Flags), Value32);
3684 pShadowSendBd->u1.Len_Flags = Value32;
3687 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
3689 MM_MEMWRITEL(&(pSendBd->u2.VlanTag), pTmpSendBd->u2.VlanTag);
3692 StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3693 if (StartIdx == 0)
3695 pSendBd = &pDevice->pSendBdVirt[0];
3696 pShadowSendBd = &pDevice->ShadowSendBd[0];
3698 else
3700 pSendBd++;
3701 pShadowSendBd++;
3703 pTmpSendBd++;
3705 MM_WMB();
3706 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3708 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3710 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3712 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3714 MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
3717 else
3718 #endif
3720 MM_WMB();
3721 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3723 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3725 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3727 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
3729 MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
3733 /* Update the SendBdLeft count. */
3734 MM_ATOMIC_SUB(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
3736 /* Update the producer index. */
3737 pDevice->SendProdIdx = Idx;
3739 return LM_STATUS_SUCCESS;
3742 STATIC LM_STATUS
3743 LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3744 PT3_SND_BD pSendBd)
3746 int FragCount;
3747 LM_UINT32 Idx, Base, Len;
3749 Idx = pDevice->SendProdIdx;
3750 for(FragCount = 0; ; )
3752 Len = pSendBd->u1.Len_Flags >> 16;
3753 if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3754 ((Base + 8 + Len) < Base))
3756 return LM_STATUS_SUCCESS;
3758 FragCount++;
3759 if (FragCount >= pPacket->u.Tx.FragCount)
3761 break;
3763 pSendBd++;
3764 if (!(pDevice->Flags & NIC_SEND_BD_FLAG))
3766 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3767 if (Idx == 0)
3769 pSendBd = &pDevice->pSendBdVirt[0];
3773 return LM_STATUS_FAILURE;
3776 /******************************************************************************/
3777 /* Description: */
3778 /* */
3779 /* Return: */
3780 /******************************************************************************/
3781 LM_UINT32
3782 ComputeCrc32(LM_UINT8 *pBuffer, LM_UINT32 BufferSize)
3784 LM_UINT32 Reg;
3785 LM_UINT32 Tmp;
3786 int j, k;
3788 Reg = 0xffffffff;
3790 for(j = 0; j < BufferSize; j++)
3792 Reg ^= pBuffer[j];
3794 for(k = 0; k < 8; k++)
3796 Tmp = Reg & 0x01;
3798 Reg >>= 1;
3800 if(Tmp)
3802 Reg ^= 0xedb88320;
3807 return ~Reg;
3808 } /* ComputeCrc32 */
3812 /******************************************************************************/
3813 /* Description: */
3814 /* This routine sets the receive control register according to ReceiveMask */
3815 /* */
3816 /* Return: */
3817 /* LM_STATUS_SUCCESS */
3818 /******************************************************************************/
3819 LM_STATUS
3820 LM_SetReceiveMask(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Mask)
3822 LM_UINT32 ReceiveMask;
3823 LM_UINT32 RxMode;
3824 LM_UINT32 j, k;
3826 ReceiveMask = Mask;
3828 RxMode = pDevice->RxMode;
3830 if(Mask & LM_ACCEPT_UNICAST)
3832 Mask &= ~LM_ACCEPT_UNICAST;
3835 if(Mask & LM_ACCEPT_MULTICAST)
3837 Mask &= ~LM_ACCEPT_MULTICAST;
3840 if(Mask & LM_ACCEPT_ALL_MULTICAST)
3842 Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3845 if(Mask & LM_ACCEPT_BROADCAST)
3847 Mask &= ~LM_ACCEPT_BROADCAST;
3850 RxMode &= ~RX_MODE_KEEP_VLAN_TAG;
3851 if (Mask & LM_KEEP_VLAN_TAG)
3853 RxMode |= RX_MODE_KEEP_VLAN_TAG;
3854 Mask &= ~LM_KEEP_VLAN_TAG;
3857 RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3858 if(Mask & LM_PROMISCUOUS_MODE)
3860 RxMode |= RX_MODE_PROMISCUOUS_MODE;
3861 Mask &= ~LM_PROMISCUOUS_MODE;
3864 RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3865 if(Mask & LM_ACCEPT_ERROR_PACKET)
3867 RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3868 Mask &= ~LM_ACCEPT_ERROR_PACKET;
3871 /* Make sure all the bits are valid before committing changes. */
3872 if(Mask)
3874 return LM_STATUS_FAILURE;
3877 /* Commit the new filter. */
3878 pDevice->ReceiveMask = ReceiveMask;
3880 pDevice->RxMode = RxMode;
3882 if (pDevice->PowerLevel != LM_POWER_STATE_D0)
3884 return LM_STATUS_SUCCESS;
3887 REG_WR(pDevice, MacCtrl.RxMode, RxMode);
3889 /* Set up the MC hash table. */
3890 if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
3892 for(k = 0; k < 4; k++)
3894 REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
3897 else if(ReceiveMask & LM_ACCEPT_MULTICAST)
3899 for(k = 0; k < 4; k++)
3901 REG_WR(pDevice, MacCtrl.HashReg[k], pDevice->MulticastHash[k]);
3904 else
3906 /* Reject all multicast frames. */
3907 for(j = 0; j < 4; j++)
3909 REG_WR(pDevice, MacCtrl.HashReg[j], 0);
3913 /* By default, Tigon3 will accept broadcast frames. We need to setup */
3914 if(ReceiveMask & LM_ACCEPT_BROADCAST)
3916 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3917 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3918 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3919 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3920 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3921 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3922 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3923 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3925 else
3927 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3928 REJECT_BROADCAST_RULE1_RULE);
3929 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3930 REJECT_BROADCAST_RULE1_VALUE);
3931 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3932 REJECT_BROADCAST_RULE2_RULE);
3933 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3934 REJECT_BROADCAST_RULE2_VALUE);
3937 if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
3939 k = 16;
3941 else
3943 k = 8;
3945 #ifdef BCM_ASF
3946 if (pDevice->AsfFlags & ASF_ENABLED)
3948 k -= 4;
3950 #endif
3952 /* disable the rest of the rules. */
3953 for(j = RCV_LAST_RULE_IDX; j < k; j++)
3955 REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
3956 REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
3959 return LM_STATUS_SUCCESS;
3960 } /* LM_SetReceiveMask */
3964 /******************************************************************************/
3965 /* Description: */
3966 /* Disable the interrupt and put the transmitter and receiver engines in */
3967 /* an idle state. Also aborts all pending send requests and receive */
3968 /* buffers. */
3969 /* */
3970 /* Return: */
3971 /* LM_STATUS_SUCCESS */
3972 /******************************************************************************/
3973 LM_STATUS
3974 LM_Abort(
3975 PLM_DEVICE_BLOCK pDevice)
3977 PLM_PACKET pPacket;
3978 LM_UINT Idx;
3980 LM_DisableInterrupt(pDevice);
3982 LM_DisableChip(pDevice);
3984 /* Abort packets that have already queued to go out. */
3985 Idx = pDevice->SendConIdx;
3986 for ( ; ; )
3988 if ((pPacket = pDevice->SendRing[Idx]))
3990 pDevice->SendRing[Idx] = 0;
3991 pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3992 pDevice->TxCounters.TxPacketAbortedCnt++;
3994 MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
3995 Idx = (Idx + pPacket->u.Tx.FragCount) &
3996 T3_SEND_RCB_ENTRY_COUNT_MASK;
3998 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
4000 else
4002 break;
4006 /* Cleanup the receive return rings. */
4007 #ifdef BCM_NAPI_RXPOLL
4008 LM_ServiceRxPoll(pDevice, T3_RCV_RETURN_RCB_ENTRY_COUNT);
4009 #else
4010 LM_ServiceRxInterrupt(pDevice);
4011 #endif
4013 /* Indicate packets to the protocol. */
4014 MM_IndicateTxPackets(pDevice);
4016 #ifdef BCM_NAPI_RXPOLL
4018 /* Move the receive packet descriptors in the ReceivedQ to the */
4019 /* free queue. */
4020 for(; ;)
4022 pPacket = (PLM_PACKET) QQ_PopHead(
4023 &pDevice->RxPacketReceivedQ.Container);
4024 if(pPacket == NULL)
4026 break;
4028 MM_UnmapRxDma(pDevice, pPacket);
4029 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4031 #else
4032 /* Indicate received packets to the protocols. */
4033 MM_IndicateRxPackets(pDevice);
4034 #endif
4036 /* Clean up the Std Receive Producer ring. */
4037 /* Don't always trust the consumer idx in the status block in case of */
4038 /* hw failure */
4039 Idx = 0;
4041 while(Idx < T3_STD_RCV_RCB_ENTRY_COUNT)
4043 if ((pPacket = pDevice->RxStdRing[Idx]))
4045 MM_UnmapRxDma(pDevice, pPacket);
4046 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4047 pDevice->RxStdRing[Idx] = 0;
4050 Idx++;
4051 } /* while */
4053 /* Reinitialize our copy of the indices. */
4054 pDevice->RxStdProdIdx = 0;
4056 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4057 /* Clean up the Jumbo Receive Producer ring. */
4058 Idx = 0;
4060 while(Idx < T3_JUMBO_RCV_RCB_ENTRY_COUNT)
4062 if ((pPacket = pDevice->RxJumboRing[Idx]))
4064 MM_UnmapRxDma(pDevice, pPacket);
4065 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4066 pDevice->RxJumboRing[Idx] = 0;
4068 Idx++;
4069 } /* while */
4071 /* Reinitialize our copy of the indices. */
4072 pDevice->RxJumboProdIdx = 0;
4073 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
4075 /* Initialize the statistis Block */
4076 pDevice->pStatusBlkVirt->Status = 0;
4077 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
4078 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
4079 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
4081 return LM_STATUS_SUCCESS;
4082 } /* LM_Abort */
4086 /******************************************************************************/
4087 /* Description: */
4088 /* Disable the interrupt and put the transmitter and receiver engines in */
4089 /* an idle state. Aborts all pending send requests and receive buffers. */
4090 /* Also free all the receive buffers. */
4091 /* */
4092 /* Return: */
4093 /* LM_STATUS_SUCCESS */
4094 /******************************************************************************/
4095 LM_STATUS
4096 LM_DoHalt(LM_DEVICE_BLOCK *pDevice)
4098 PLM_PACKET pPacket;
4099 LM_UINT32 EntryCnt;
4101 LM_DisableFW(pDevice);
4103 LM_WritePreResetSignatures(pDevice, LM_SHUTDOWN_RESET);
4104 LM_Abort(pDevice);
4106 /* Get the number of entries in the queue. */
4107 EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
4109 /* Make sure all the packets have been accounted for. */
4110 for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
4112 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
4113 if (pPacket == 0)
4114 break;
4116 MM_FreeRxBuffer(pDevice, pPacket);
4118 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
4121 LM_ResetChip(pDevice);
4122 LM_WriteLegacySignatures(pDevice, LM_SHUTDOWN_RESET);
4124 /* Restore PCI configuration registers. */
4125 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
4126 pDevice->SavedCacheLineReg);
4127 LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
4128 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
4130 /* Reprogram the MAC address. */
4131 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
4133 return LM_STATUS_SUCCESS;
4134 } /* LM_DoHalt */
4137 LM_STATUS
4138 LM_Halt(LM_DEVICE_BLOCK *pDevice)
4140 LM_STATUS status;
4142 status = LM_DoHalt(pDevice);
4143 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
4144 return status;
4148 STATIC LM_VOID
4149 LM_WritePreResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4151 MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,T3_MAGIC_NUM_FIRMWARE_INIT_DONE);
4152 #ifdef BCM_ASF
4153 if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
4155 if (Mode == LM_INIT_RESET)
4157 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
4159 else if (Mode == LM_SHUTDOWN_RESET)
4161 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
4163 else if (Mode == LM_SUSPEND_RESET)
4165 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
4168 #endif
4171 STATIC LM_VOID
4172 LM_WritePostResetSignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4174 #ifdef BCM_ASF
4175 if (pDevice->AsfFlags & ASF_NEW_HANDSHAKE)
4177 if (Mode == LM_INIT_RESET)
4179 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
4180 T3_DRV_STATE_START_DONE);
4182 else if (Mode == LM_SHUTDOWN_RESET)
4184 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX,
4185 T3_DRV_STATE_UNLOAD_DONE);
4188 #endif
4191 STATIC LM_VOID
4192 LM_WriteLegacySignatures(LM_DEVICE_BLOCK *pDevice, LM_RESET_TYPE Mode)
4194 #ifdef BCM_ASF
4195 if (pDevice->AsfFlags & ASF_ENABLED)
4197 if (Mode == LM_INIT_RESET)
4199 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_START);
4201 else if (Mode == LM_SHUTDOWN_RESET)
4203 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_UNLOAD);
4205 else if (Mode == LM_SUSPEND_RESET)
4207 MEM_WR_OFFSET(pDevice, T3_DRV_STATE_MAILBOX, T3_DRV_STATE_SUSPEND);
4210 #endif
4213 STATIC LM_STATUS
4214 LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
4216 LM_UINT32 Value32;
4217 LM_UINT32 j, MaxWait;
4219 /* Wait for access to the nvram interface before resetting. This is */
4220 /* a workaround to prevent EEPROM corruption. */
4221 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
4222 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
4224 /* Request access to the flash interface. */
4225 LM_NvramGetLock(pDevice);
4228 Value32 = GRC_MISC_CFG_CORE_CLOCK_RESET;
4229 if (pDevice->Flags & PCI_EXPRESS_FLAG)
4231 if (REG_RD_OFFSET(pDevice, 0x7e2c) == 0x60) /* PCIE 1.0 system */
4233 REG_WR_OFFSET(pDevice, 0x7e2c, 0x20);
4235 if (pDevice->ChipRevId != T3_CHIP_ID_5750_A0)
4237 /* This bit prevents PCIE link training during GRC reset */
4238 REG_WR(pDevice, Grc.MiscCfg, BIT_29); /* Write bit 29 first */
4239 Value32 |= BIT_29; /* and keep bit 29 set during GRC reset */
4242 if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
4244 Value32 |= GRC_MISC_GPHY_KEEP_POWER_DURING_RESET;
4246 /* Global reset. */
4247 RAW_REG_WR(pDevice, Grc.MiscCfg, Value32);
4248 MM_Wait(40); MM_Wait(40); MM_Wait(40);
4250 #ifdef INCLUDE_5750_A0_FIX
4251 if (pDevice->Flags & PCI_EXPRESS_FLAG)
4253 if (pDevice->ChipRevId == T3_CHIP_ID_5750_A0)
4255 /* 500 msec wait for link training to complete */
4256 for (j = 0; j < 5000; j++)
4258 MM_Wait(100);
4260 MM_ReadConfig32(pDevice, 0xc4, &Value32);
4261 MM_WriteConfig32(pDevice, 0xc4, Value32 | BIT_15);
4263 /* Set PCIE max payload size and clear error status */
4264 MM_WriteConfig32(pDevice, 0xd8, 0xf5000);
4266 #endif
4268 /* make sure we re-enable indirect accesses */
4269 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
4270 pDevice->MiscHostCtrl);
4272 /* Set MAX PCI retry to zero. */
4273 Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
4274 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
4276 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
4278 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
4281 MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
4283 /* Restore PCI command register. */
4284 MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
4285 pDevice->PciCommandStatusWords);
4287 /* Disable PCI-X relaxed ordering bit. */
4288 MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
4289 Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
4290 MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
4292 /* Enable memory arbiter. */
4293 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
4295 if (pDevice->ChipRevId == T3_CHIP_ID_5750_A3)
4297 /* Because of chip bug on A3, we need to kill the CPU */
4298 LM_DisableFW(pDevice);
4299 REG_WR_OFFSET(pDevice, 0x5000, 0x400);
4301 #ifdef BIG_ENDIAN_HOST
4302 /* Reconfigure the mode register. */
4303 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
4304 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
4305 GRC_MODE_BYTE_SWAP_DATA |
4306 GRC_MODE_WORD_SWAP_DATA;
4307 #else
4308 /* Reconfigure the mode register. */
4309 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
4310 #endif
4311 REG_WR(pDevice, Grc.Mode, Value32);
4313 #ifdef INCLUDE_5750_A0_FIX
4314 if (pDevice->ChipRevId == T3_CHIP_ID_5750_A0)
4316 Value32 = REG_RD_OFFSET(pDevice, 0xc4);
4317 REG_WR_OFFSET(pDevice, 0xc4, Value32 | BIT_15);
4319 #endif
4320 if ((pDevice->Flags & MINI_PCI_FLAG) &&
4321 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705))
4323 pDevice->ClockCtrl |= T3_PCI_CLKRUN_OUTPUT_EN;
4324 if (pDevice->ChipRevId == T3_CHIP_ID_5705_A0)
4326 pDevice->ClockCtrl |= T3_PCI_FORCE_CLKRUN;
4328 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
4331 if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
4332 pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
4333 REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
4335 else {
4336 REG_WR(pDevice, MacCtrl.Mode, 0);
4339 /* Wait for the firmware to finish initialization. */
4340 if (pDevice->Flags & FLASH_DETECTED_FLAG)
4342 MaxWait = 1000;
4344 else
4346 MaxWait = 10000;
4348 for(j = 0; j < MaxWait; j++)
4350 MM_Wait(100);
4352 if (j < 50)
4353 continue;
4355 Value32 = MEM_RD_OFFSET(pDevice, T3_FIRMWARE_MAILBOX);
4356 if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
4358 break;
4361 if ((j >= MaxWait) && (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704))
4363 /* workaround - need to reset nvram of both devices at the same time */
4364 /* if the boot code is not running */
4365 if (LM_NvramGetLock(pDevice) != LM_STATUS_SUCCESS)
4367 LM_DEVICE_BLOCK *pDevice2;
4369 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RESET);
4370 pDevice2 = MM_FindPeerDev(pDevice);
4371 if (pDevice2 && !pDevice2->InitDone)
4373 REG_WR(pDevice2, Nvram.Cmd, NVRAM_CMD_RESET);
4376 else
4378 LM_NvramReleaseLock(pDevice);
4382 if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
4383 (pDevice->ChipRevId != T3_CHIP_ID_5750_A0))
4385 /* Enable PCIE bug fix */
4386 Value32 = REG_RD_OFFSET(pDevice, 0x7c00);
4387 REG_WR_OFFSET(pDevice, 0x7c00, Value32 | BIT_25);
4389 #ifdef BCM_ASF
4390 pDevice->AsfFlags = 0;
4391 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
4392 if (Value32 == T3_NIC_DATA_SIG)
4394 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
4395 if (Value32 & T3_NIC_CFG_ENABLE_ASF)
4397 pDevice->AsfFlags = ASF_ENABLED;
4398 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750)
4400 pDevice->AsfFlags |= ASF_NEW_HANDSHAKE;
4404 #endif
4406 return LM_STATUS_SUCCESS;
4410 LM_STATUS
4411 LM_ShutdownChip(PLM_DEVICE_BLOCK pDevice, LM_RESET_TYPE Mode)
4413 LM_DisableFW(pDevice);
4414 LM_WritePreResetSignatures(pDevice, Mode);
4415 if (pDevice->InitDone)
4417 LM_Abort(pDevice);
4419 else
4421 LM_DisableChip(pDevice);
4423 LM_ResetChip(pDevice);
4424 LM_WriteLegacySignatures(pDevice, Mode);
4425 LM_WritePostResetSignatures(pDevice, Mode);
4426 return LM_STATUS_SUCCESS;
4429 /******************************************************************************/
4430 /* Description: */
4431 /* */
4432 /* Return: */
4433 /******************************************************************************/
4434 void
4435 LM_ServiceTxInterrupt(
4436 PLM_DEVICE_BLOCK pDevice) {
4437 PLM_PACKET pPacket;
4438 LM_UINT32 HwConIdx;
4439 LM_UINT32 SwConIdx;
4441 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
4443 /* Get our copy of the consumer index. The buffer descriptors */
4444 /* that are in between the consumer indices are freed. */
4445 SwConIdx = pDevice->SendConIdx;
4447 /* Move the packets from the TxPacketActiveQ that are sent out to */
4448 /* the TxPacketXmittedQ. Packets that are sent use the */
4449 /* descriptors that are between SwConIdx and HwConIdx. */
4450 while(SwConIdx != HwConIdx)
4452 pPacket = pDevice->SendRing[SwConIdx];
4453 pDevice->SendRing[SwConIdx] = 0;
4455 /* Set the return status. */
4456 pPacket->PacketStatus = LM_STATUS_SUCCESS;
4458 /* Put the packet in the TxPacketXmittedQ for indication later. */
4459 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
4461 /* Move to the next packet's BD. */
4462 SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
4463 T3_SEND_RCB_ENTRY_COUNT_MASK;
4465 /* Update the number of unused BDs. */
4466 MM_ATOMIC_ADD(&pDevice->SendBdLeft, pPacket->u.Tx.FragCount);
4468 /* Get the new updated HwConIdx. */
4469 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
4470 } /* while */
4472 /* Save the new SwConIdx. */
4473 pDevice->SendConIdx = SwConIdx;
4475 } /* LM_ServiceTxInterrupt */
4478 #ifdef BCM_NAPI_RXPOLL
4479 /******************************************************************************/
4480 /* Description: */
4481 /* */
4482 /* Return: */
4483 /******************************************************************************/
4485 LM_ServiceRxPoll(PLM_DEVICE_BLOCK pDevice, int limit)
4487 PLM_PACKET pPacket;
4488 PT3_RCV_BD pRcvBd;
4489 LM_UINT32 HwRcvRetProdIdx;
4490 LM_UINT32 SwRcvRetConIdx;
4491 int received = 0;
4493 /* Loop thru the receive return rings for received packets. */
4494 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
4496 SwRcvRetConIdx = pDevice->RcvRetConIdx;
4497 MM_RMB();
4498 while (SwRcvRetConIdx != HwRcvRetProdIdx)
4500 pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
4502 /* Get the received packet descriptor. */
4503 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
4504 MM_UINT_PTR(pRcvBd->Opaque));
4506 switch(pPacket->u.Rx.RcvProdRing) {
4507 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4508 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
4509 pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4510 break;
4511 #endif
4512 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
4513 pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4514 break;
4517 /* Check the error flag. */
4518 if(pRcvBd->ErrorFlag &&
4519 pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4521 pPacket->PacketStatus = LM_STATUS_FAILURE;
4523 pDevice->RxCounters.RxPacketErrCnt++;
4525 if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
4527 pDevice->RxCounters.RxErrCrcCnt++;
4530 if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
4532 pDevice->RxCounters.RxErrCollCnt++;
4535 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
4537 pDevice->RxCounters.RxErrLinkLostCnt++;
4540 if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
4542 pDevice->RxCounters.RxErrPhyDecodeCnt++;
4545 if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4547 pDevice->RxCounters.RxErrOddNibbleCnt++;
4550 if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
4552 pDevice->RxCounters.RxErrMacAbortCnt++;
4555 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
4557 pDevice->RxCounters.RxErrShortPacketCnt++;
4560 if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
4562 pDevice->RxCounters.RxErrNoResourceCnt++;
4565 if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
4567 pDevice->RxCounters.RxErrLargePacketCnt++;
4570 else
4572 pPacket->PacketStatus = LM_STATUS_SUCCESS;
4573 pPacket->PacketSize = pRcvBd->Len - 4;
4575 pPacket->Flags = pRcvBd->Flags;
4576 if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
4578 pPacket->VlanTag = pRcvBd->VlanTag;
4581 pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
4584 /* Put the packet descriptor containing the received packet */
4585 /* buffer in the RxPacketReceivedQ for indication later. */
4586 QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
4588 /* Go to the next buffer descriptor. */
4589 SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
4590 pDevice->RcvRetRcbEntryCountMask;
4592 if (++received >= limit)
4594 break;
4596 } /* while */
4598 pDevice->RcvRetConIdx = SwRcvRetConIdx;
4600 /* Update the receive return ring consumer index. */
4601 MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
4602 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4604 MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
4606 return received;
4607 } /* LM_ServiceRxPoll */
4608 #endif /* BCM_NAPI_RXPOLL */
4611 /******************************************************************************/
4612 /* Description: */
4613 /* */
4614 /* Return: */
4615 /******************************************************************************/
4616 void
4617 LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice)
4619 #ifndef BCM_NAPI_RXPOLL
4620 PLM_PACKET pPacket;
4621 PT3_RCV_BD pRcvBd;
4622 #endif
4623 LM_UINT32 HwRcvRetProdIdx;
4624 LM_UINT32 SwRcvRetConIdx;
4626 /* Loop thru the receive return rings for received packets. */
4627 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
4629 SwRcvRetConIdx = pDevice->RcvRetConIdx;
4630 #ifdef BCM_NAPI_RXPOLL
4631 if (!pDevice->RxPoll)
4633 if (SwRcvRetConIdx != HwRcvRetProdIdx)
4635 if (MM_ScheduleRxPoll(pDevice) == LM_STATUS_SUCCESS)
4637 pDevice->RxPoll = TRUE;
4638 REG_WR(pDevice, Grc.Mode,
4639 pDevice->GrcMode | GRC_MODE_NO_INTERRUPT_ON_RECEIVE);
4643 #else
4644 MM_RMB();
4645 while(SwRcvRetConIdx != HwRcvRetProdIdx)
4647 pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
4649 /* Get the received packet descriptor. */
4650 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
4651 MM_UINT_PTR(pRcvBd->Opaque));
4653 switch(pPacket->u.Rx.RcvProdRing) {
4654 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
4655 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
4656 pDevice->RxJumboRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4657 break;
4658 #endif
4659 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
4660 pDevice->RxStdRing[pPacket->u.Rx.RcvRingProdIdx] = 0;
4661 break;
4664 /* Check the error flag. */
4665 if(pRcvBd->ErrorFlag &&
4666 pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4668 pPacket->PacketStatus = LM_STATUS_FAILURE;
4670 pDevice->RxCounters.RxPacketErrCnt++;
4672 if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
4674 pDevice->RxCounters.RxErrCrcCnt++;
4677 if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
4679 pDevice->RxCounters.RxErrCollCnt++;
4682 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
4684 pDevice->RxCounters.RxErrLinkLostCnt++;
4687 if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
4689 pDevice->RxCounters.RxErrPhyDecodeCnt++;
4692 if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
4694 pDevice->RxCounters.RxErrOddNibbleCnt++;
4697 if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
4699 pDevice->RxCounters.RxErrMacAbortCnt++;
4702 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
4704 pDevice->RxCounters.RxErrShortPacketCnt++;
4707 if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
4709 pDevice->RxCounters.RxErrNoResourceCnt++;
4712 if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
4714 pDevice->RxCounters.RxErrLargePacketCnt++;
4717 else
4719 pPacket->PacketStatus = LM_STATUS_SUCCESS;
4720 pPacket->PacketSize = pRcvBd->Len - 4;
4722 pPacket->Flags = pRcvBd->Flags;
4723 if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
4725 pPacket->VlanTag = pRcvBd->VlanTag;
4728 pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
4731 /* Put the packet descriptor containing the received packet */
4732 /* buffer in the RxPacketReceivedQ for indication later. */
4733 QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
4735 /* Go to the next buffer descriptor. */
4736 SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
4737 pDevice->RcvRetRcbEntryCountMask;
4739 } /* while */
4741 pDevice->RcvRetConIdx = SwRcvRetConIdx;
4743 /* Update the receive return ring consumer index. */
4744 MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
4745 if (pDevice->Flags & FLUSH_POSTED_WRITE_FLAG)
4747 MB_REG_RD(pDevice, Mailbox.RcvRetConIdx[0].Low);
4749 #endif
4750 } /* LM_ServiceRxInterrupt */
4754 /******************************************************************************/
4755 /* Description: */
4756 /* This is the interrupt event handler routine. It acknowledges all */
4757 /* pending interrupts and process all pending events. */
4758 /* */
4759 /* Return: */
4760 /* LM_STATUS_SUCCESS */
4761 /******************************************************************************/
4762 LM_STATUS
4763 LM_ServiceInterrupts(
4764 PLM_DEVICE_BLOCK pDevice)
4766 LM_UINT32 Value32;
4767 int ServicePhyInt = FALSE;
4769 /* Setup the phy chip whenever the link status changes. */
4770 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
4772 Value32 = REG_RD(pDevice, MacCtrl.Status);
4773 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
4775 if (Value32 & MAC_STATUS_MI_INTERRUPT)
4777 ServicePhyInt = TRUE;
4780 else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
4782 ServicePhyInt = TRUE;
4785 else
4787 if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
4789 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4790 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4791 ServicePhyInt = TRUE;
4794 #if INCLUDE_TBI_SUPPORT
4795 if (pDevice->IgnoreTbiLinkChange == TRUE)
4797 ServicePhyInt = FALSE;
4799 #endif
4800 if (ServicePhyInt == TRUE)
4802 MM_ACQUIRE_PHY_LOCK_IN_IRQ(pDevice);
4803 LM_SetupPhy(pDevice);
4804 MM_RELEASE_PHY_LOCK_IN_IRQ(pDevice);
4807 /* Service receive and transmit interrupts. */
4808 LM_ServiceRxInterrupt(pDevice);
4809 LM_ServiceTxInterrupt(pDevice);
4811 #ifndef BCM_NAPI_RXPOLL
4812 /* No spinlock for this queue since this routine is serialized. */
4813 if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
4815 /* Indicate receive packets. */
4816 MM_IndicateRxPackets(pDevice);
4817 // LM_QueueRxPackets(pDevice);
4819 #endif
4821 /* No spinlock for this queue since this routine is serialized. */
4822 if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
4824 MM_IndicateTxPackets(pDevice);
4827 return LM_STATUS_SUCCESS;
4828 } /* LM_ServiceInterrupts */
4831 /******************************************************************************/
4832 /* Description: Add a Multicast address. Note that MC addresses, once added, */
4833 /* cannot be individually deleted. All addresses must be */
4834 /* cleared. */
4835 /* */
4836 /* Return: */
4837 /******************************************************************************/
4838 LM_STATUS
4839 LM_MulticastAdd(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
4842 LM_UINT32 RegIndex;
4843 LM_UINT32 Bitpos;
4844 LM_UINT32 Crc32;
4846 Crc32 = ComputeCrc32(pMcAddress, ETHERNET_ADDRESS_SIZE);
4848 /* The most significant 7 bits of the CRC32 (no inversion), */
4849 /* are used to index into one of the possible 128 bit positions. */
4850 Bitpos = ~Crc32 & 0x7f;
4852 /* Hash register index. */
4853 RegIndex = (Bitpos & 0x60) >> 5;
4855 /* Bit to turn on within a hash register. */
4856 Bitpos &= 0x1f;
4858 /* Enable the multicast bit. */
4859 pDevice->MulticastHash[RegIndex] |= (1 << Bitpos);
4861 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
4863 return LM_STATUS_SUCCESS;
4867 /******************************************************************************/
4868 /* Description: */
4869 /* */
4870 /* Return: */
4871 /******************************************************************************/
4872 LM_STATUS
4873 LM_MulticastDel(LM_DEVICE_BLOCK *pDevice, PLM_UINT8 pMcAddress)
4875 return LM_STATUS_FAILURE;
4876 } /* LM_MulticastDel */
4880 /******************************************************************************/
4881 /* Description: */
4882 /* */
4883 /* Return: */
4884 /******************************************************************************/
4885 LM_STATUS
4886 LM_MulticastClear(LM_DEVICE_BLOCK *pDevice)
4888 int i;
4890 for (i = 0; i < 4; i++)
4892 pDevice->MulticastHash[i] = 0;
4894 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4896 return LM_STATUS_SUCCESS;
4897 } /* LM_MulticastClear */
4901 /******************************************************************************/
4902 /* Description: */
4903 /* */
4904 /* Return: */
4905 /******************************************************************************/
4906 LM_STATUS
4907 LM_SetMacAddress(
4908 PLM_DEVICE_BLOCK pDevice,
4909 PLM_UINT8 pMacAddress)
4911 LM_UINT32 j;
4913 for(j = 0; j < 4; j++)
4915 REG_WR(pDevice, MacCtrl.MacAddr[j].High,
4916 (pMacAddress[0] << 8) | pMacAddress[1]);
4917 REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
4918 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4919 (pMacAddress[4] << 8) | pMacAddress[5]);
4922 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
4923 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701) &&
4924 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
4926 for (j = 0; j < 12; j++)
4928 REG_WR(pDevice, MacCtrl.MacAddrExt[j].High,
4929 (pMacAddress[0] << 8) | pMacAddress[1]);
4930 REG_WR(pDevice, MacCtrl.MacAddrExt[j].Low,
4931 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4932 (pMacAddress[4] << 8) | pMacAddress[5]);
4935 return LM_STATUS_SUCCESS;
4938 LM_VOID
4939 LM_PhyTapPowerMgmt(LM_DEVICE_BLOCK *pDevice)
4941 /* Turn off tap power management. */
4942 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4944 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
4945 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4946 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4947 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4948 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4949 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4950 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4951 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4952 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4953 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4954 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4956 MM_Wait(40);
4960 /******************************************************************************/
4961 /* Description: */
4962 /* */
4963 /* Return: */
4964 /* LM_STATUS_LINK_ACTIVE */
4965 /* LM_STATUS_LINK_DOWN */
4966 /******************************************************************************/
4967 static LM_STATUS
4968 LM_InitBcm540xPhy(
4969 PLM_DEVICE_BLOCK pDevice)
4971 LM_LINE_SPEED CurrentLineSpeed;
4972 LM_DUPLEX_MODE CurrentDuplexMode;
4973 LM_STATUS CurrentLinkStatus;
4974 LM_UINT32 Value32;
4975 LM_UINT32 j;
4977 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
4979 if ((pDevice->PhyFlags & PHY_RESET_ON_LINKDOWN) &&
4980 (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE))
4982 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4983 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4984 if(!(Value32 & PHY_STATUS_LINK_PASS))
4986 LM_ResetPhy(pDevice);
4989 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4991 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4992 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4994 if(!pDevice->InitDone)
4996 Value32 = 0;
4999 if(!(Value32 & PHY_STATUS_LINK_PASS))
5001 LM_PhyTapPowerMgmt(pDevice);
5003 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5004 for(j = 0; j < 1000; j++)
5006 MM_Wait(10);
5008 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5009 if(Value32 & PHY_STATUS_LINK_PASS)
5011 MM_Wait(40);
5012 break;
5016 if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
5018 if(!(Value32 & PHY_STATUS_LINK_PASS) &&
5019 (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
5021 LM_ResetPhy(pDevice);
5026 else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5027 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
5029 /* Bug: 5701 A0, B0 TX CRC workaround. */
5030 LM_WritePhy(pDevice, 0x15, 0x0a75);
5031 LM_WritePhy(pDevice, 0x1c, 0x8c68);
5032 LM_WritePhy(pDevice, 0x1c, 0x8d68);
5033 LM_WritePhy(pDevice, 0x1c, 0x8c68);
5036 /* Acknowledge interrupts. */
5037 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
5038 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
5040 /* Configure the interrupt mask. */
5041 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5043 LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
5046 /* Configure PHY led mode. */
5047 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5048 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
5050 if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_1)
5052 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
5053 BCM540X_EXT_CTRL_LINK3_LED_MODE);
5055 else
5057 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
5061 if (pDevice->PhyFlags & PHY_CAPACITIVE_COUPLING)
5063 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4007);
5064 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &Value32);
5065 if (!(Value32 & BIT_10))
5067 /* set the bit and re-link */
5068 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, Value32 | BIT_10);
5069 return LM_STATUS_LINK_SETTING_MISMATCH;
5073 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5075 /* Get current link and duplex mode. */
5076 for(j = 0; j < 100; j++)
5078 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5079 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5081 if(Value32 & PHY_STATUS_LINK_PASS)
5083 break;
5085 MM_Wait(40);
5088 if(Value32 & PHY_STATUS_LINK_PASS)
5091 /* Determine the current line and duplex settings. */
5092 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
5093 for(j = 0; j < 2000; j++)
5095 MM_Wait(10);
5097 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
5098 if(Value32)
5100 break;
5104 switch(Value32 & BCM540X_AUX_SPEED_MASK)
5106 case BCM540X_AUX_10BASET_HD:
5107 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
5108 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5109 break;
5111 case BCM540X_AUX_10BASET_FD:
5112 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
5113 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5114 break;
5116 case BCM540X_AUX_100BASETX_HD:
5117 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
5118 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5119 break;
5121 case BCM540X_AUX_100BASETX_FD:
5122 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
5123 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5124 break;
5126 case BCM540X_AUX_100BASET_HD:
5127 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
5128 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
5129 break;
5131 case BCM540X_AUX_100BASET_FD:
5132 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
5133 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
5134 break;
5136 default:
5138 CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
5139 CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
5140 break;
5143 /* Make sure we are in auto-neg mode. */
5144 for (j = 0; j < 200; j++)
5146 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5147 if(Value32 && Value32 != 0x7fff)
5149 break;
5152 if(Value32 == 0 &&
5153 pDevice->RequestedLineSpeed == LM_LINE_SPEED_10MBPS &&
5154 pDevice->RequestedDuplexMode == LM_DUPLEX_MODE_HALF)
5156 break;
5159 MM_Wait(10);
5162 /* Use the current line settings for "auto" mode. */
5163 if(pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
5165 if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
5167 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5169 /* We may be exiting low power mode and the link is in */
5170 /* 10mb. In this case, we need to restart autoneg. */
5172 if (LM_PhyAdvertiseAll(pDevice) != LM_STATUS_SUCCESS)
5174 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5177 else
5179 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5182 else
5184 /* Force line settings. */
5185 /* Use the current setting if it matches the user's requested */
5186 /* setting. */
5187 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5188 if((pDevice->LineSpeed == CurrentLineSpeed) &&
5189 (pDevice->DuplexMode == CurrentDuplexMode))
5191 if ((pDevice->DisableAutoNeg &&
5192 !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
5193 (!pDevice->DisableAutoNeg &&
5194 (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
5196 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5198 else
5200 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5203 else
5205 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
5209 /* Save line settings. */
5210 pDevice->LineSpeed = CurrentLineSpeed;
5211 pDevice->DuplexMode = CurrentDuplexMode;
5214 return CurrentLinkStatus;
5215 } /* LM_InitBcm540xPhy */
5217 /******************************************************************************/
5218 /* Description: */
5219 /* */
5220 /* Return: */
5221 /******************************************************************************/
5222 LM_STATUS
5223 LM_SetFlowControl(
5224 PLM_DEVICE_BLOCK pDevice,
5225 LM_UINT32 LocalPhyAd,
5226 LM_UINT32 RemotePhyAd)
5228 LM_FLOW_CONTROL FlowCap;
5230 /* Resolve flow control. */
5231 FlowCap = LM_FLOW_CONTROL_NONE;
5233 /* See Table 28B-3 of 802.3ab-1999 spec. */
5234 if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
5236 if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
5238 if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5240 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
5242 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
5243 LM_FLOW_CONTROL_RECEIVE_PAUSE;
5245 else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
5247 FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
5250 else
5252 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
5254 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
5255 LM_FLOW_CONTROL_RECEIVE_PAUSE;
5259 else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5261 if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
5262 (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
5264 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
5268 else
5270 FlowCap = pDevice->FlowControlCap;
5273 pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5275 /* Enable/disable rx PAUSE. */
5276 pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
5277 if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
5278 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
5279 pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
5281 pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
5282 pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
5285 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
5287 /* Enable/disable tx PAUSE. */
5288 pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
5289 if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
5290 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
5291 pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
5293 pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
5294 pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
5297 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
5299 return LM_STATUS_SUCCESS;
5303 #if INCLUDE_TBI_SUPPORT
5304 /******************************************************************************/
5305 /* Description: */
5306 /* */
5307 /* Return: */
5308 /******************************************************************************/
5309 STATIC LM_STATUS
5310 LM_InitBcm800xPhy(
5311 PLM_DEVICE_BLOCK pDevice)
5313 LM_UINT32 Value32;
5314 LM_UINT32 j;
5316 Value32 = REG_RD(pDevice, MacCtrl.Status);
5318 /* Reset the SERDES during init and when we have link. */
5319 if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
5321 /* Set PLL lock range. */
5322 LM_WritePhy(pDevice, 0x16, 0x8007);
5324 /* Software reset. */
5325 LM_WritePhy(pDevice, 0x00, 0x8000);
5327 /* Wait for reset to complete. */
5328 for(j = 0; j < 500; j++)
5330 MM_Wait(10);
5333 /* Config mode; seletct PMA/Ch 1 regs. */
5334 LM_WritePhy(pDevice, 0x10, 0x8411);
5336 /* Enable auto-lock and comdet, select txclk for tx. */
5337 LM_WritePhy(pDevice, 0x11, 0x0a10);
5339 LM_WritePhy(pDevice, 0x18, 0x00a0);
5340 LM_WritePhy(pDevice, 0x16, 0x41ff);
5342 /* Assert and deassert POR. */
5343 LM_WritePhy(pDevice, 0x13, 0x0400);
5344 MM_Wait(40);
5345 LM_WritePhy(pDevice, 0x13, 0x0000);
5347 LM_WritePhy(pDevice, 0x11, 0x0a50);
5348 MM_Wait(40);
5349 LM_WritePhy(pDevice, 0x11, 0x0a10);
5351 /* Delay for signal to stabilize. */
5352 for(j = 0; j < 15000; j++)
5354 MM_Wait(10);
5357 /* Deselect the channel register so we can read the PHY id later. */
5358 LM_WritePhy(pDevice, 0x10, 0x8011);
5361 return LM_STATUS_SUCCESS;
5366 /******************************************************************************/
5367 /* Description: */
5368 /* */
5369 /* Return: */
5370 /******************************************************************************/
5371 STATIC LM_STATUS
5372 LM_SetupFiberPhy(
5373 PLM_DEVICE_BLOCK pDevice)
5375 LM_STATUS CurrentLinkStatus;
5376 AUTONEG_STATUS AnStatus = 0;
5377 LM_UINT32 Value32;
5378 LM_UINT32 Cnt;
5379 LM_UINT32 j, k;
5380 LM_UINT32 MacStatus, RemotePhyAd, LocalPhyAd;
5381 LM_FLOW_CONTROL PreviousFlowControl = pDevice->FlowControl;
5383 if (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE)
5385 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
5386 MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
5387 return LM_STATUS_SUCCESS;
5390 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
5391 (pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) && pDevice->InitDone)
5393 MacStatus = REG_RD(pDevice, MacCtrl.Status);
5394 if ((MacStatus & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED |
5395 MAC_STATUS_CFG_CHANGED | MAC_STATUS_RECEIVING_CFG))
5396 == (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED))
5399 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5400 MAC_STATUS_CFG_CHANGED);
5401 return LM_STATUS_SUCCESS;
5404 pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
5406 /* Initialize the send_config register. */
5407 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
5409 /* Enable TBI and full duplex mode. */
5410 pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
5411 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5413 /* Initialize the BCM8002 SERDES PHY. */
5414 switch(pDevice->PhyId & PHY_ID_MASK)
5416 case PHY_BCM8002_PHY_ID:
5417 LM_InitBcm800xPhy(pDevice);
5418 break;
5420 default:
5421 break;
5424 /* Enable link change interrupt. */
5425 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5427 /* Default to link down. */
5428 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5430 /* Get the link status. */
5431 MacStatus = REG_RD(pDevice, MacCtrl.Status);
5433 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
5435 LM_UINT32 SgDigCtrl, SgDigStatus;
5436 LM_UINT32 SerdesCfg = 0;
5437 LM_UINT32 ExpectedSgDigCtrl = 0;
5438 LM_UINT32 WorkAround = 0;
5439 LM_UINT32 PortA = 1;
5441 if ((pDevice->ChipRevId != T3_CHIP_ID_5704_A0) &&
5442 (pDevice->ChipRevId != T3_CHIP_ID_5704_A1))
5444 WorkAround = 1;
5445 if (REG_RD(pDevice, PciCfg.DualMacCtrl) & T3_DUAL_MAC_ID)
5447 PortA = 0;
5449 /* preserve the voltage regulator bits */
5450 SerdesCfg = REG_RD(pDevice, MacCtrl.SerdesCfg) &
5451 (BIT_23 | BIT_22 | BIT_21 | BIT_20);
5453 SgDigCtrl = REG_RD(pDevice, MacCtrl.SgDigControl);
5454 if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
5455 (pDevice->DisableAutoNeg == FALSE))
5458 ExpectedSgDigCtrl = 0x81388400;
5459 LocalPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5460 if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
5462 ExpectedSgDigCtrl |= BIT_11;
5464 if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
5466 ExpectedSgDigCtrl |= BIT_12;
5468 if (SgDigCtrl != ExpectedSgDigCtrl)
5470 if (WorkAround)
5472 REG_WR(pDevice, MacCtrl.SerdesCfg, 0xc011880 | SerdesCfg);
5474 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl |
5475 BIT_30);
5476 REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
5477 MM_Wait(5);
5478 REG_WR(pDevice, MacCtrl.SgDigControl, ExpectedSgDigCtrl);
5479 pDevice->AutoNegJustInited = TRUE;
5481 /* If autoneg is off, you only get SD when link is up */
5482 else if(MacStatus & (MAC_STATUS_PCS_SYNCED |
5483 MAC_STATUS_SIGNAL_DETECTED))
5485 SgDigStatus = REG_RD(pDevice, MacCtrl.SgDigStatus);
5486 if ((SgDigStatus & BIT_1) &&
5487 (MacStatus & MAC_STATUS_PCS_SYNCED))
5489 /* autoneg. completed */
5490 RemotePhyAd = 0;
5491 if(SgDigStatus & BIT_19)
5493 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
5496 if(SgDigStatus & BIT_20)
5498 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
5501 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5502 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5503 pDevice->AutoNegJustInited = FALSE;
5505 else if (!(SgDigStatus & BIT_1))
5507 if (pDevice->AutoNegJustInited == TRUE)
5509 /* we may be checking too soon, so check again */
5510 /* at the next poll interval */
5511 pDevice->AutoNegJustInited = FALSE;
5513 else
5515 /* autoneg. failed */
5516 if (WorkAround)
5518 if (PortA)
5520 REG_WR(pDevice, MacCtrl.SerdesCfg,
5521 0xc010880 | SerdesCfg);
5523 else
5525 REG_WR(pDevice, MacCtrl.SerdesCfg,
5526 0x4010880 | SerdesCfg);
5529 /* turn off autoneg. to allow traffic to pass */
5530 REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
5531 REG_RD_BACK(pDevice, MacCtrl.SgDigControl);
5532 MM_Wait(40);
5533 MacStatus = REG_RD(pDevice, MacCtrl.Status);
5534 if (MacStatus & MAC_STATUS_PCS_SYNCED)
5536 LM_SetFlowControl(pDevice, 0, 0);
5537 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5543 else
5545 if (SgDigCtrl & BIT_31) {
5546 if (WorkAround)
5548 if (PortA)
5550 REG_WR(pDevice, MacCtrl.SerdesCfg,
5551 0xc010880 | SerdesCfg);
5553 else
5555 REG_WR(pDevice, MacCtrl.SerdesCfg,
5556 0x4010880 | SerdesCfg);
5559 REG_WR(pDevice, MacCtrl.SgDigControl, 0x01388400);
5561 if(MacStatus & MAC_STATUS_PCS_SYNCED)
5563 LM_SetFlowControl(pDevice, 0, 0);
5564 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5568 else if(MacStatus & MAC_STATUS_PCS_SYNCED)
5570 if((pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) ||
5571 (pDevice->DisableAutoNeg == FALSE))
5573 /* auto-negotiation mode. */
5574 /* Initialize the autoneg default capaiblities. */
5575 AutonegInit(&pDevice->AnInfo);
5577 /* Set the context pointer to point to the main device structure. */
5578 pDevice->AnInfo.pContext = pDevice;
5580 /* Setup flow control advertisement register. */
5581 Value32 = GetPhyAdFlowCntrlSettings(pDevice);
5582 if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
5584 pDevice->AnInfo.mr_adv_sym_pause = 1;
5586 else
5588 pDevice->AnInfo.mr_adv_sym_pause = 0;
5591 if(Value32 & PHY_AN_AD_ASYM_PAUSE)
5593 pDevice->AnInfo.mr_adv_asym_pause = 1;
5595 else
5597 pDevice->AnInfo.mr_adv_asym_pause = 0;
5600 /* Try to autoneg up to six times. */
5601 if (pDevice->IgnoreTbiLinkChange)
5603 Cnt = 1;
5605 else
5607 Cnt = 6;
5609 for (j = 0; j < Cnt; j++)
5611 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
5613 Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
5614 REG_WR(pDevice, MacCtrl.Mode, Value32);
5615 REG_RD_BACK(pDevice, MacCtrl.Mode);
5616 MM_Wait(20);
5618 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5619 MAC_MODE_SEND_CONFIGS);
5620 REG_RD_BACK(pDevice, MacCtrl.Mode);
5622 MM_Wait(20);
5624 pDevice->AnInfo.State = AN_STATE_UNKNOWN;
5625 pDevice->AnInfo.CurrentTime_us = 0;
5627 REG_WR(pDevice, Grc.Timer, 0);
5628 for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
5629 (k < 75000); k++)
5631 AnStatus = Autoneg8023z(&pDevice->AnInfo);
5633 if((AnStatus == AUTONEG_STATUS_DONE) ||
5634 (AnStatus == AUTONEG_STATUS_FAILED))
5636 break;
5639 pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
5642 if((AnStatus == AUTONEG_STATUS_DONE) ||
5643 (AnStatus == AUTONEG_STATUS_FAILED))
5645 break;
5647 if (j >= 1)
5649 if (!(REG_RD(pDevice, MacCtrl.Status) &
5650 MAC_STATUS_PCS_SYNCED)) {
5651 break;
5656 /* Stop sending configs. */
5657 MM_AnTxIdle(&pDevice->AnInfo);
5659 /* Resolve flow control settings. */
5660 if((AnStatus == AUTONEG_STATUS_DONE) &&
5661 pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
5662 pDevice->AnInfo.mr_lp_adv_full_duplex)
5664 LM_UINT32 RemotePhyAd;
5665 LM_UINT32 LocalPhyAd;
5667 LocalPhyAd = 0;
5668 if(pDevice->AnInfo.mr_adv_sym_pause)
5670 LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
5673 if(pDevice->AnInfo.mr_adv_asym_pause)
5675 LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
5678 RemotePhyAd = 0;
5679 if(pDevice->AnInfo.mr_lp_adv_sym_pause)
5681 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
5684 if(pDevice->AnInfo.mr_lp_adv_asym_pause)
5686 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
5689 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5691 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5693 else
5695 LM_SetFlowControl(pDevice, 0, 0);
5697 for (j = 0; j < 30; j++)
5699 MM_Wait(20);
5700 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5701 MAC_STATUS_CFG_CHANGED);
5702 REG_RD_BACK(pDevice, MacCtrl.Status);
5703 MM_Wait(20);
5704 if ((REG_RD(pDevice, MacCtrl.Status) &
5705 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
5706 break;
5708 if (pDevice->TbiFlags & TBI_POLLING_FLAGS)
5710 Value32 = REG_RD(pDevice, MacCtrl.Status);
5711 if (Value32 & MAC_STATUS_RECEIVING_CFG)
5713 pDevice->IgnoreTbiLinkChange = TRUE;
5715 else if (pDevice->TbiFlags & TBI_POLLING_INTR_FLAG)
5717 pDevice->IgnoreTbiLinkChange = FALSE;
5720 Value32 = REG_RD(pDevice, MacCtrl.Status);
5721 if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
5722 (Value32 & MAC_STATUS_PCS_SYNCED) &&
5723 ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
5725 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5728 else
5730 /* We are forcing line speed. */
5731 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5732 LM_SetFlowControl(pDevice, 0, 0);
5734 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5735 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5736 MAC_MODE_SEND_CONFIGS);
5739 /* Set the link polarity bit. */
5740 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5741 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5743 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
5744 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
5746 for (j = 0; j < 100; j++)
5748 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5749 MAC_STATUS_CFG_CHANGED);
5750 REG_RD_BACK(pDevice, MacCtrl.Status);
5751 MM_Wait(5);
5752 if ((REG_RD(pDevice, MacCtrl.Status) &
5753 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
5754 break;
5757 Value32 = REG_RD(pDevice, MacCtrl.Status);
5758 if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
5760 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5761 if (pDevice->DisableAutoNeg == FALSE)
5763 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
5764 MAC_MODE_SEND_CONFIGS);
5765 REG_RD_BACK(pDevice, MacCtrl.Mode);
5766 MM_Wait(1);
5767 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5771 /* Initialize the current link status. */
5772 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5774 pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
5775 pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
5776 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
5777 LED_CTRL_OVERRIDE_LINK_LED |
5778 LED_CTRL_1000MBPS_LED_ON);
5780 else
5782 pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
5783 pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
5784 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl |
5785 LED_CTRL_OVERRIDE_LINK_LED |
5786 LED_CTRL_OVERRIDE_TRAFFIC_LED);
5789 /* Indicate link status. */
5790 if ((pDevice->LinkStatus != CurrentLinkStatus) ||
5791 ((CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
5792 (PreviousFlowControl != pDevice->FlowControl)))
5794 pDevice->LinkStatus = CurrentLinkStatus;
5795 MM_IndicateStatus(pDevice, CurrentLinkStatus);
5798 return LM_STATUS_SUCCESS;
5800 #endif /* INCLUDE_TBI_SUPPORT */
5803 /******************************************************************************/
5804 /* Description: */
5805 /* */
5806 /* Return: */
5807 /******************************************************************************/
5808 LM_STATUS
5809 LM_SetupCopperPhy(
5810 PLM_DEVICE_BLOCK pDevice)
5812 LM_STATUS CurrentLinkStatus;
5813 LM_UINT32 Value32;
5815 /* Assume there is not link first. */
5816 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5818 /* Disable phy link change attention. */
5819 REG_WR(pDevice, MacCtrl.MacEvent, 0);
5821 /* Clear link change attention. */
5822 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5823 MAC_STATUS_CFG_CHANGED | MAC_STATUS_MI_COMPLETION |
5824 MAC_STATUS_LINK_STATE_CHANGED);
5826 /* Disable auto-polling for the moment. */
5827 pDevice->MiMode = 0xc0000;
5828 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5829 REG_RD_BACK(pDevice, MacCtrl.MiMode);
5830 MM_Wait(40);
5832 /* Determine the requested line speed and duplex. */
5833 pDevice->OldLineSpeed = pDevice->LineSpeed;
5834 pDevice->LineSpeed = pDevice->RequestedLineSpeed;
5835 pDevice->DuplexMode = pDevice->RequestedDuplexMode;
5837 /* Set the phy to loopback mode. */
5838 if ((pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE) ||
5839 (pDevice->LoopBackMode == LM_MAC_LOOP_BACK_MODE))
5841 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5842 if(!(Value32 & PHY_CTRL_LOOPBACK_MODE) &&
5843 (pDevice->LoopBackMode == LM_PHY_LOOP_BACK_MODE))
5845 /* Disable link change and PHY interrupts. */
5846 REG_WR(pDevice, MacCtrl.MacEvent, 0);
5848 /* Clear link change attention. */
5849 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5850 MAC_STATUS_CFG_CHANGED);
5852 LM_WritePhy(pDevice, PHY_CTRL_REG, 0x4140);
5853 MM_Wait(40);
5855 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5856 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5857 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703 ||
5858 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704 ||
5859 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705 ||
5860 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 &&
5861 (pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID))
5863 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5866 /* Prevent the interrupt handling from being called. */
5867 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
5868 (pDevice->pStatusBlkVirt->Status &
5869 ~STATUS_BLOCK_LINK_CHANGED_STATUS);
5871 /* GMII interface. */
5872 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
5873 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5874 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5875 REG_RD_BACK(pDevice, MacCtrl.Mode);
5876 MM_Wait(40);
5878 /* Configure PHY led mode. */
5879 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
5880 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
5882 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
5883 BCM540X_EXT_CTRL_LINK3_LED_MODE);
5884 MM_Wait(40);
5887 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5889 int j = 0;
5891 while (REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE)
5893 MM_Wait(40);
5894 j++;
5895 if (j > 20)
5896 break;
5899 Value32 = DMA_WRITE_MODE_ENABLE |
5900 DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
5901 DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
5902 DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
5903 DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
5904 DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
5905 DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
5906 DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
5907 DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
5908 REG_WR(pDevice, DmaWrite.Mode, Value32);
5912 pDevice->LinkStatus = LM_STATUS_LINK_ACTIVE;
5913 MM_IndicateStatus(pDevice, LM_STATUS_LINK_ACTIVE);
5915 return LM_STATUS_SUCCESS;
5918 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5919 if(Value32 & PHY_CTRL_LOOPBACK_MODE)
5921 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5923 /* Re-enable link change interrupt. This was disabled when we */
5924 /* enter loopback mode. */
5925 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5927 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
5929 else
5931 REG_WR(pDevice, MacCtrl.MacEvent,
5932 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5935 else
5937 /* Initialize the phy chip. */
5938 CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
5941 if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
5943 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5946 /* Setup flow control. */
5947 pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5948 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5950 LM_FLOW_CONTROL FlowCap; /* Flow control capability. */
5952 FlowCap = LM_FLOW_CONTROL_NONE;
5954 if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
5956 if(pDevice->DisableAutoNeg == FALSE ||
5957 pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
5959 LM_UINT32 ExpectedPhyAd;
5960 LM_UINT32 LocalPhyAd;
5961 LM_UINT32 RemotePhyAd;
5963 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
5964 pDevice->advertising = LocalPhyAd;
5965 LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
5967 ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5969 if(LocalPhyAd != ExpectedPhyAd)
5971 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5973 else
5975 LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
5976 &RemotePhyAd);
5978 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5981 else
5983 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5984 LM_SetFlowControl(pDevice, 0, 0);
5989 if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
5991 LM_ForceAutoNeg(pDevice);
5993 /* If we force line speed, we make get link right away. */
5994 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5995 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5996 if(Value32 & PHY_STATUS_LINK_PASS)
5998 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
6002 /* GMII interface. */
6003 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
6004 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
6006 if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
6007 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
6009 pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
6011 else
6013 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
6016 else {
6017 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
6020 /* Set the MAC to operate in the appropriate duplex mode. */
6021 pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
6022 if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
6024 pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
6027 /* Set the link polarity bit. */
6028 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
6029 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
6031 if((pDevice->LedCtrl == LED_CTRL_PHY_MODE_2) ||
6032 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
6033 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
6035 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
6038 else
6040 if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
6042 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
6046 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6048 /* Enable auto polling. */
6049 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6051 pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
6052 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6054 /* if using MAC led mode and not using auto polling, need to configure */
6055 /* mi status register */
6056 else if ((pDevice->LedCtrl &
6057 (LED_CTRL_PHY_MODE_1 | LED_CTRL_PHY_MODE_2)) == 0)
6059 if (CurrentLinkStatus != LM_STATUS_LINK_ACTIVE)
6061 REG_WR(pDevice, MacCtrl.MiStatus, 0);
6063 else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
6065 REG_WR(pDevice, MacCtrl.MiStatus,
6066 MI_STATUS_ENABLE_LINK_STATUS_ATTN | MI_STATUS_10MBPS);
6068 else
6070 REG_WR(pDevice, MacCtrl.MiStatus,
6071 MI_STATUS_ENABLE_LINK_STATUS_ATTN);
6075 /* Enable phy link change attention. */
6076 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
6078 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
6080 else
6082 REG_WR(pDevice, MacCtrl.MacEvent,
6083 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
6085 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
6086 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
6087 (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
6088 (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
6089 (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
6090 !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
6092 MM_Wait(120);
6093 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
6094 MAC_STATUS_CFG_CHANGED);
6095 MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
6096 T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
6099 /* Indicate link status. */
6100 if (pDevice->LinkStatus != CurrentLinkStatus) {
6101 pDevice->LinkStatus = CurrentLinkStatus;
6102 MM_IndicateStatus(pDevice, CurrentLinkStatus);
6105 return LM_STATUS_SUCCESS;
6106 } /* LM_SetupCopperPhy */
6108 /******************************************************************************/
6109 /* Description: */
6110 /* */
6111 /* Return: */
6112 /******************************************************************************/
6113 LM_STATUS
6114 LM_SetupPhy(
6115 PLM_DEVICE_BLOCK pDevice)
6117 LM_STATUS LmStatus;
6118 LM_UINT32 Value32;
6120 #if INCLUDE_TBI_SUPPORT
6121 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6123 LmStatus = LM_SetupFiberPhy(pDevice);
6125 else
6126 #endif /* INCLUDE_TBI_SUPPORT */
6128 LmStatus = LM_SetupCopperPhy(pDevice);
6130 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
6132 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
6134 Value32 = REG_RD(pDevice, PciCfg.PciState);
6135 REG_WR(pDevice, PciCfg.PciState,
6136 Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
6139 if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
6140 (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
6142 REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
6144 else
6146 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
6148 if(!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6150 if (pDevice->LinkStatus == LM_STATUS_LINK_DOWN)
6152 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks, 0);
6154 else
6156 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
6157 pDevice->StatsCoalescingTicks);
6161 return LmStatus;
6165 /* test data pattern */
6166 static LM_UINT32 pattern[4][6] = {
6167 /* For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
6168 For 5705 , each DFE TAP has 19-bits (low word 15, hi word 4)
6169 For simplicity, we check only 19-bits, so we don't have to
6170 distinguish which chip it is.
6171 the LO word contains 15 bits, make sure pattern data is < 0x7fff
6172 the HI word contains 6 bits, make sure pattern data is < 0x003f */
6173 {0x00005555, 0x00000005, /* ch0, TAP 0, LO/HI pattern */
6174 0x00002aaa, 0x0000000a, /* ch0, TAP 1, LO/HI pattern */
6175 0x00003456, 0x00000003}, /* ch0, TAP 2, LO/HI pattern */
6177 {0x00002aaa, 0x0000000a, /* ch1, TAP 0, LO/HI pattern */
6178 0x00003333, 0x00000003, /* ch1, TAP 1, LO/HI pattern */
6179 0x0000789a, 0x00000005}, /* ch1, TAP 2, LO/HI pattern */
6181 {0x00005a5a, 0x00000005, /* ch2, TAP 0, LO/HI pattern */
6182 0x00002a6a, 0x0000000a, /* ch2, TAP 1, LO/HI pattern */
6183 0x00001bcd, 0x00000003}, /* ch2, TAP 2, LO/HI pattern */
6185 {0x00002a5a, 0x0000000a, /* ch3, TAP 0, LO/HI pattern */
6186 0x000033c3, 0x00000003, /* ch3, TAP 1, LO/HI pattern */
6187 0x00002ef1, 0x00000005}, /* ch3, TAP 2, LO/HI pattern */
6190 /********************************************************/
6191 /* Routine to wait for PHY Macro Command to complete */
6192 /* */
6193 /* If PHY's Macro operation keeps stay busy, nothing we */
6194 /* can do anyway. The timeout is there so we won't */
6195 /* stay in this routine indefinitly. */
6196 /********************************************************/
6197 static LM_UINT32 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice);
6199 static LM_UINT32
6200 LM_wait_macro_done(LM_DEVICE_BLOCK *pDevice)
6202 LM_UINT32 timeout;
6203 LM_UINT32 val32;
6205 timeout = 100;
6206 while (timeout--)
6208 /* make sure the MACRO operation is complete */
6209 LM_ReadPhy(pDevice, 0x16, &val32);
6210 if ((val32 & 0x1000) == 0) break;
6213 return( timeout > 0 );
6216 /********************************************************/
6217 /* This routine resets the PHY on following chips: */
6218 /* 5703, 04, CIOB-E and 5705 */
6219 /* */
6220 /* This routine will issue PHY_RESET and check if */
6221 /* the reset is sucessful. If not, another PHY RESET */
6222 /* will be issued, until max "retry" reaches */
6223 /* */
6224 /* Input: */
6225 /* pDevice - device's context */
6226 /* retry - number of retries */
6227 /* reset - TRUE=will cause a PHY reset initially */
6228 /* FALSE = will not issue a PHY reset */
6229 /* unless TAP lockup detected */
6230 /* */
6231 /* Output: */
6232 /* TRUE - PHY Reset is done sucessfully */
6233 /* FALSE - PHY Reset had failed, after "retry" */
6234 /* has reached */
6235 /* */
6236 /* Dependencies: */
6237 /* void LM_wait_macro_done() */
6238 /* u32 pattern[] */
6239 /* */
6240 /* Usage: */
6241 /* a. Before calling this routine, caller must */
6242 /* determine if the chip is a 5702/03/04 or */
6243 /* CIOB-E, and only call this routine if the */
6244 /* is one of these. */
6245 /* or its derivatives. */
6246 /* b. Instead of using MII register write to reset */
6247 /* the PHY, call this routine instead */
6248 /* c. Upon return from this routine, check return */
6249 /* value (TRUE/FALSE) to determine if PHY reset */
6250 /* is successful of not and "optionally" take */
6251 /* appropriate action (such as: event log) */
6252 /* d. Regardless of the return TRUE or FALSE, */
6253 /* proceed with PHY setup as you normally would */
6254 /* after a PHY_RESET. */
6255 /* e. It is recommended that the caller will give */
6256 /* 10 "retry", however, caller can change to a */
6257 /* different number, depending on you code. */
6258 /* */
6259 /********************************************************/
6260 LM_STATUS LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset);
6262 LM_STATUS
6263 LM_ResetPhy_5703_4_5(LM_DEVICE_BLOCK *pDevice, int retry, int reset)
6265 LM_UINT32 val32, save9;
6266 LM_UINT32 dataLo, dataHi;
6267 int i, channel;
6268 int reset_success = LM_STATUS_FAILURE;
6269 int force_reset;
6271 /* to actually do a PHY_RESET or not is dictated by the caller */
6272 force_reset = reset;
6274 while (retry-- && (reset_success != LM_STATUS_SUCCESS))
6276 if (force_reset)
6278 /* issue a phy reset, and wait for reset to complete */
6279 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
6280 for(i = 0; i < 100; i++)
6282 MM_Wait(10);
6284 LM_ReadPhy(pDevice, PHY_CTRL_REG, &val32);
6285 if(val32 && !(val32 & PHY_CTRL_PHY_RESET))
6287 MM_Wait(20);
6288 break;
6292 /* no more phy reset unless lockup detected */
6293 force_reset = FALSE;
6296 /* assuming reset is successful first */
6297 reset_success = LM_STATUS_SUCCESS;
6299 /* now go check the DFE TAPs to see if locked up, but
6300 first, we need to set up PHY so we can read DFE TAPs */
6302 /* Disable Transmitter and Interrupt, while we play with
6303 the PHY registers, so the link partner won't see any
6304 strange data and the Driver won't see any interrupts. */
6305 LM_ReadPhy(pDevice, 0x10, &val32);
6306 LM_WritePhy(pDevice, 0x10, val32 | 0x3000);
6308 /* Setup Full-Duplex, 1000 mbps */
6309 LM_WritePhy(pDevice, 0x0, 0x0140);
6311 /* Set to Master mode */
6312 LM_ReadPhy(pDevice, 0x9, &save9);
6313 LM_WritePhy(pDevice, 0x9, 0x1800);
6315 /* Enable SM_DSP_CLOCK & 6dB */
6316 LM_WritePhy(pDevice, 0x18, 0x0c00);
6318 /* blocks the PHY control access */
6319 LM_WritePhy(pDevice, 0x17, 0x8005);
6320 LM_WritePhy(pDevice, 0x15, 0x0800);
6322 /* check TAPs for all 4 channels, as soon
6323 as we see a lockup we'll stop checking */
6324 for (channel=0; (channel<4) && (reset_success == LM_STATUS_SUCCESS);
6325 channel++)
6327 /* select channel and set TAP index to 0 */
6328 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6329 /* freeze filter again just to be safe */
6330 LM_WritePhy(pDevice, 0x16, 0x0002);
6332 /* write fixed pattern to the RAM, 3 TAPs for
6333 each channel, each TAP have 2 WORDs (LO/HI) */
6334 for (i=0; i<6; i++)
6335 LM_WritePhy(pDevice, 0x15, pattern[channel][i]);
6337 /* Activate PHY's Macro operation to write DFE TAP from RAM,
6338 and wait for Macro to complete */
6339 LM_WritePhy(pDevice, 0x16, 0x0202);
6340 if (!LM_wait_macro_done(pDevice))
6342 reset_success = LM_STATUS_FAILURE;
6343 force_reset = TRUE;
6344 break;
6347 /* --- done with write phase, now begin read phase --- */
6349 /* select channel and set TAP index to 0 */
6350 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6352 /* Active PHY's Macro operation to load DFE TAP to RAM,
6353 and wait for Macro to complete */
6354 LM_WritePhy(pDevice, 0x16, 0x0082);
6355 if (!LM_wait_macro_done(pDevice))
6357 reset_success = LM_STATUS_FAILURE;
6358 force_reset = TRUE;
6359 break;
6362 /* enable "pre-fetch" */
6363 LM_WritePhy(pDevice, 0x16, 0x0802);
6364 if (!LM_wait_macro_done(pDevice))
6366 reset_success = LM_STATUS_FAILURE;
6367 force_reset = TRUE;
6368 break;
6371 /* read back the TAP values.
6372 3 TAPs for each channel, each TAP have 2 WORDs (LO/HI) */
6373 for (i=0; i<6; i+=2)
6375 /* read Lo/Hi then wait for 'done' is faster */
6376 LM_ReadPhy(pDevice, 0x15, &dataLo);
6377 LM_ReadPhy(pDevice, 0x15, &dataHi);
6378 if (!LM_wait_macro_done(pDevice))
6380 reset_success = LM_STATUS_FAILURE;
6381 force_reset = TRUE;
6382 break;
6385 /* For 5703/04, each DFE TAP has 21-bits (low word 15,
6386 * hi word 6) For 5705, each DFE TAP pas 19-bits (low word 15,
6387 * hi word 4) For simplicity, we check only 19-bits, so we
6388 * don't have to distinguish which chip it is. */
6389 dataLo &= 0x7fff;
6390 dataHi &= 0x000f;
6392 /* check if what we wrote is what we read back */
6393 if ( (dataLo != pattern[channel][i]) || (dataHi != pattern[channel][i+1]) )
6395 /* if failed, then the PHY is locked up,
6396 we need to do PHY reset again */
6397 reset_success = LM_STATUS_FAILURE;
6398 force_reset = TRUE;
6399 /* 04/25/2003. sb. do these writes before issueing a reset. */
6400 /* these steps will reduce the chance of back-to-back
6401 * phy lockup after reset */
6402 LM_WritePhy(pDevice, 0x17, 0x000B);
6403 LM_WritePhy(pDevice, 0x15, 0x4001);
6404 LM_WritePhy(pDevice, 0x15, 0x4005);
6405 break;
6407 } /* for i */
6408 } /* for channel */
6409 } /* while */
6411 /* restore dfe coeff back to zeros */
6412 for (channel=0; channel<4 ; channel++)
6414 LM_WritePhy(pDevice, 0x17, (channel * 0x2000) | 0x0200);
6415 LM_WritePhy(pDevice, 0x16, 0x0002);
6416 for (i=0; i<6; i++)
6417 LM_WritePhy(pDevice, 0x15, 0x0000);
6418 LM_WritePhy(pDevice, 0x16, 0x0202);
6419 if (!LM_wait_macro_done(pDevice))
6421 reset_success = LM_STATUS_FAILURE;
6422 break;
6426 /* remove block phy control */
6427 LM_WritePhy(pDevice, 0x17, 0x8005);
6428 LM_WritePhy(pDevice, 0x15, 0x0000);
6430 /* unfreeze DFE TAP filter for all channels */
6431 LM_WritePhy(pDevice, 0x17, 0x8200);
6432 LM_WritePhy(pDevice, 0x16, 0x0000);
6434 /* Restore PHY back to operating state */
6435 LM_WritePhy(pDevice, 0x18, 0x0400);
6437 /* Restore register 9 */
6438 LM_WritePhy(pDevice, 0x9, save9);
6440 /* enable transmitter and interrupt */
6441 LM_ReadPhy(pDevice, 0x10, &val32);
6442 LM_WritePhy(pDevice, 0x10, (val32 & ~0x3000));
6444 return reset_success;
6447 LM_VOID
6448 LM_ResetPhy(LM_DEVICE_BLOCK *pDevice)
6450 int j;
6451 LM_UINT32 miireg;
6453 if (pDevice->PhyFlags & PHY_CHECK_TAPS_AFTER_RESET)
6455 LM_ResetPhy_5703_4_5(pDevice, 5, 1);
6457 else
6459 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
6461 for(j = 0; j < 100; j++)
6463 MM_Wait(10);
6465 LM_ReadPhy(pDevice, PHY_CTRL_REG, &miireg);
6466 if(miireg && !(miireg & PHY_CTRL_PHY_RESET))
6468 MM_Wait(20);
6469 break;
6472 LM_PhyTapPowerMgmt(pDevice);
6474 if (pDevice->PhyFlags & PHY_ADC_FIX)
6476 LM_WritePhy(pDevice, 0x18, 0x0c00);
6477 LM_WritePhy(pDevice, 0x17, 0x201f);
6478 LM_WritePhy(pDevice, 0x15, 0x2aaa);
6479 LM_WritePhy(pDevice, 0x17, 0x000a);
6480 LM_WritePhy(pDevice, 0x15, 0x0323);
6481 LM_WritePhy(pDevice, 0x18, 0x0400);
6483 if (pDevice->PhyFlags & PHY_5705_5750_FIX)
6485 LM_WritePhy(pDevice, 0x18, 0x0c00);
6486 LM_WritePhy(pDevice, 0x17, 0x000a);
6487 LM_WritePhy(pDevice, 0x15, 0x310b);
6488 LM_WritePhy(pDevice, 0x17, 0x201f);
6489 LM_WritePhy(pDevice, 0x15, 0x9506);
6490 LM_WritePhy(pDevice, 0x17, 0x401f);
6491 LM_WritePhy(pDevice, 0x15, 0x14e2);
6492 LM_WritePhy(pDevice, 0x18, 0x0400);
6494 if (pDevice->PhyFlags & PHY_5704_A0_FIX)
6496 LM_WritePhy(pDevice, 0x1c, 0x8d68);
6497 LM_WritePhy(pDevice, 0x1c, 0x8d68);
6499 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
6501 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
6503 else if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6505 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
6506 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &miireg);
6507 miireg |= 0x4000; /* set extended packet length */
6508 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, miireg);
6511 LM_SetEthWireSpeed(pDevice);
6514 STATIC LM_VOID
6515 LM_SetEthWireSpeed(LM_DEVICE_BLOCK *pDevice)
6517 LM_UINT32 Value32;
6519 /* Enable Ethernet@WireSpeed. */
6520 if (pDevice->PhyFlags & PHY_ETHERNET_WIRESPEED)
6522 LM_WritePhy(pDevice, 0x18, 0x7007);
6523 LM_ReadPhy(pDevice, 0x18, &Value32);
6524 LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
6528 STATIC LM_STATUS
6529 LM_PhyAdvertiseAll(LM_DEVICE_BLOCK *pDevice)
6531 LM_UINT32 miireg;
6533 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &miireg);
6534 pDevice->advertising = miireg;
6535 if ((miireg & PHY_AN_AD_ALL_SPEEDS) != PHY_AN_AD_ALL_SPEEDS)
6537 return LM_STATUS_FAILURE;
6539 if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
6541 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &miireg);
6542 pDevice->advertising1000 = miireg;
6543 if ((miireg & BCM540X_AN_AD_ALL_1G_SPEEDS) !=
6544 BCM540X_AN_AD_ALL_1G_SPEEDS)
6546 return LM_STATUS_FAILURE;
6549 return LM_STATUS_SUCCESS;
6552 /******************************************************************************/
6553 /* Description: */
6554 /* */
6555 /* Return: */
6556 /******************************************************************************/
6557 LM_VOID
6558 LM_ReadPhy(
6559 PLM_DEVICE_BLOCK pDevice,
6560 LM_UINT32 PhyReg,
6561 PLM_UINT32 pData32) {
6562 LM_UINT32 Value32;
6563 LM_UINT32 j;
6565 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6567 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
6568 ~MI_MODE_AUTO_POLLING_ENABLE);
6569 REG_RD_BACK(pDevice, MacCtrl.MiMode);
6570 MM_Wait(40);
6573 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
6574 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
6575 MI_COM_CMD_READ | MI_COM_START;
6577 REG_WR(pDevice, MacCtrl.MiCom, Value32);
6579 for(j = 0; j < 200; j++)
6581 MM_Wait(1);
6583 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6585 if(!(Value32 & MI_COM_BUSY))
6587 MM_Wait(5);
6588 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6589 Value32 &= MI_COM_PHY_DATA_MASK;
6590 break;
6594 if(Value32 & MI_COM_BUSY)
6596 Value32 = 0;
6599 *pData32 = Value32;
6601 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6603 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6604 REG_RD_BACK(pDevice, MacCtrl.MiMode);
6605 MM_Wait(40);
6607 } /* LM_ReadPhy */
6611 /******************************************************************************/
6612 /* Description: */
6613 /* */
6614 /* Return: */
6615 /******************************************************************************/
6616 LM_VOID
6617 LM_WritePhy(
6618 PLM_DEVICE_BLOCK pDevice,
6619 LM_UINT32 PhyReg,
6620 LM_UINT32 Data32) {
6621 LM_UINT32 Value32;
6622 LM_UINT32 j;
6624 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6626 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
6627 ~MI_MODE_AUTO_POLLING_ENABLE);
6628 REG_RD_BACK(pDevice, MacCtrl.MiMode);
6629 MM_Wait(40);
6632 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
6633 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
6634 (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
6636 REG_WR(pDevice, MacCtrl.MiCom, Value32);
6638 for(j = 0; j < 200; j++)
6640 MM_Wait(1);
6642 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
6644 if(!(Value32 & MI_COM_BUSY))
6646 MM_Wait(5);
6647 break;
6651 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
6653 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
6654 REG_RD_BACK(pDevice, MacCtrl.MiMode);
6655 MM_Wait(40);
6657 } /* LM_WritePhy */
6659 STATIC void
6660 LM_GetPhyId(LM_DEVICE_BLOCK *pDevice)
6662 LM_UINT32 Value32;
6664 LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
6665 pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
6667 LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
6668 pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
6669 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
6672 LM_STATUS
6673 LM_EnableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
6675 pDevice->LoopBackMode = LM_MAC_LOOP_BACK_MODE;
6676 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
6677 pDevice->MacMode |= MAC_MODE_PORT_INTERNAL_LOOPBACK |
6678 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
6679 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6680 LM_SetupPhy(pDevice);
6681 return LM_STATUS_SUCCESS;
6684 LM_STATUS
6685 LM_DisableMacLoopBack(PLM_DEVICE_BLOCK pDevice)
6687 pDevice->LoopBackMode = 0;
6688 pDevice->MacMode &= ~(MAC_MODE_PORT_INTERNAL_LOOPBACK |
6689 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_MASK);
6690 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
6691 LM_SetupPhy(pDevice);
6692 return LM_STATUS_SUCCESS;
6695 LM_STATUS
6696 LM_EnablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
6698 pDevice->LoopBackMode = LM_PHY_LOOP_BACK_MODE;
6699 LM_SetupPhy(pDevice);
6700 return LM_STATUS_SUCCESS;
6703 LM_STATUS
6704 LM_DisablePhyLoopBack(PLM_DEVICE_BLOCK pDevice)
6706 pDevice->LoopBackMode = 0;
6707 LM_SetupPhy(pDevice);
6708 return LM_STATUS_SUCCESS;
6711 LM_STATUS
6712 LM_EnableExtLoopBack(PLM_DEVICE_BLOCK pDevice, LM_LINE_SPEED LineSpeed)
6714 pDevice->LoopBackMode = LM_EXT_LOOP_BACK_MODE;
6716 pDevice->SavedDisableAutoNeg = pDevice->DisableAutoNeg;
6717 pDevice->SavedRequestedLineSpeed = pDevice->RequestedLineSpeed;
6718 pDevice->SavedRequestedDuplexMode = pDevice->RequestedDuplexMode;
6720 pDevice->DisableAutoNeg = TRUE;
6721 pDevice->RequestedLineSpeed = LineSpeed;
6722 pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL;
6723 LM_SetupPhy(pDevice);
6724 return LM_STATUS_SUCCESS;
6727 LM_STATUS
6728 LM_DisableExtLoopBack(PLM_DEVICE_BLOCK pDevice)
6730 pDevice->LoopBackMode = 0;
6732 pDevice->DisableAutoNeg = pDevice->SavedDisableAutoNeg;
6733 pDevice->RequestedLineSpeed = pDevice->SavedRequestedLineSpeed;
6734 pDevice->RequestedDuplexMode = pDevice->SavedRequestedDuplexMode;
6736 LM_SetupPhy(pDevice);
6737 return LM_STATUS_SUCCESS;
6740 /******************************************************************************/
6741 /* Description: */
6742 /* */
6743 /* Return: */
6744 /******************************************************************************/
6745 LM_STATUS
6746 LM_SetPowerState(
6747 PLM_DEVICE_BLOCK pDevice,
6748 LM_POWER_STATE PowerLevel)
6750 #ifdef BCM_WOL
6751 LM_UINT32 PmeSupport;
6752 PLM_DEVICE_BLOCK pDevice2 = 0;
6753 int j;
6754 #endif
6755 LM_UINT32 Value32;
6756 LM_UINT32 PmCtrl;
6758 /* make sureindirect accesses are enabled*/
6759 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
6761 /* Clear the PME_ASSERT bit and the power state bits. Also enable */
6762 /* the PME bit. */
6763 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
6765 PmCtrl |= T3_PM_PME_ASSERTED;
6766 PmCtrl &= ~T3_PM_POWER_STATE_MASK;
6768 /* Set the appropriate power state. */
6769 if(PowerLevel == LM_POWER_STATE_D0)
6772 /* Bring the card out of low power mode. */
6773 PmCtrl |= T3_PM_POWER_STATE_D0;
6774 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
6776 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
6777 RAW_REG_WR(pDevice, Grc.LocalCtrl, Value32 &
6778 ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
6779 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
6780 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
6781 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
6782 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
6783 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2));
6785 MM_Wait(40); /* Required delay is about 20us. */
6787 pDevice->PowerLevel = PowerLevel;
6788 return LM_STATUS_SUCCESS;
6790 #ifdef BCM_WOL
6791 else if(PowerLevel == LM_POWER_STATE_D1)
6793 PmCtrl |= T3_PM_POWER_STATE_D1;
6795 else if(PowerLevel == LM_POWER_STATE_D2)
6797 PmCtrl |= T3_PM_POWER_STATE_D2;
6799 else if(PowerLevel == LM_POWER_STATE_D3)
6801 PmCtrl |= T3_PM_POWER_STATE_D3;
6803 else
6805 return LM_STATUS_FAILURE;
6807 PmCtrl |= T3_PM_PME_ENABLE;
6809 /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
6810 /* setting new line speed. */
6811 Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
6812 REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
6814 if(!pDevice->RestoreOnWakeUp)
6816 pDevice->RestoreOnWakeUp = TRUE;
6817 pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
6818 pDevice->WakeUpRequestedLineSpeed = pDevice->RequestedLineSpeed;
6819 pDevice->WakeUpRequestedDuplexMode = pDevice->RequestedDuplexMode;
6822 /* Force auto-negotiation to 10 line speed. */
6823 pDevice->DisableAutoNeg = FALSE;
6825 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
6827 pDevice->RequestedLineSpeed = LM_LINE_SPEED_10MBPS;
6828 LM_SetupPhy(pDevice);
6831 /* Put the driver in the initial state, and go through the power down */
6832 /* sequence. */
6833 LM_DoHalt(pDevice);
6835 if (!(pDevice->AsfFlags & ASF_ENABLED))
6837 for(j = 0; j < 20000; j++)
6839 MM_Wait(10);
6841 Value32 = MEM_RD_OFFSET(pDevice, T3_ASF_FW_STATUS_MAILBOX);
6842 if(Value32 == ~T3_MAGIC_NUM_FIRMWARE_INIT_DONE)
6844 break;
6849 MEM_WR_OFFSET(pDevice, DRV_WOL_MAILBOX, DRV_WOL_SIGNATURE |
6850 DRV_DOWN_STATE_SHUTDOWN | 0x2 | DRV_WOL_SET_MAGIC_PKT);
6852 MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
6854 if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
6857 /* Enable WOL. */
6858 if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG))
6860 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
6861 MM_Wait(40);
6864 if (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5750)
6866 /* Let boot code deal with LED mode on shasta */
6867 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
6870 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6872 Value32 = MAC_MODE_PORT_MODE_TBI;
6874 else
6876 Value32 = MAC_MODE_PORT_MODE_MII;
6877 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
6879 if(pDevice->LedCtrl == LED_CTRL_PHY_MODE_2 ||
6880 pDevice->WolSpeed == WOL_SPEED_10MB)
6882 Value32 |= MAC_MODE_LINK_POLARITY;
6885 else
6887 Value32 |= MAC_MODE_LINK_POLARITY;
6890 REG_WR(pDevice, MacCtrl.Mode, Value32);
6891 REG_RD_BACK(pDevice, MacCtrl.Mode);
6892 MM_Wait(40); MM_Wait(40); MM_Wait(40);
6894 /* Always enable magic packet wake-up if we have vaux. */
6895 if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
6896 (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
6898 Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
6901 #ifdef BCM_ASF
6902 if (pDevice->AsfFlags & ASF_ENABLED)
6904 Value32 &= ~MAC_MODE_ACPI_POWER_ON_ENABLE;
6906 #endif
6907 REG_WR(pDevice, MacCtrl.Mode, Value32);
6909 /* Enable the receiver. */
6910 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
6912 else if (!(pDevice->AsfFlags & ASF_ENABLED))
6914 if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
6916 REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
6917 LED_CTRL_OVERRIDE_TRAFFIC_LED);
6919 else
6921 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
6922 BCM540X_EXT_CTRL_FORCE_LED_OFF);
6923 LM_WritePhy(pDevice, 0x18, 0x01b2);
6924 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
6925 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5704) &&
6926 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
6928 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOWER_POWER_MODE);
6933 /* Disable tx/rx clocks, and select an alternate clock. */
6934 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) ||
6935 ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701) &&
6936 (pDevice->WolSpeed == WOL_SPEED_10MB)))
6938 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6939 T3_PCI_SELECT_ALTERNATE_CLOCK |
6940 T3_PCI_POWER_DOWN_PCI_PLL133;
6942 REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6944 /* ASF on 5750 will not run properly on slow core clock */
6945 else if (!((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5750) &&
6946 (pDevice->AsfFlags & ASF_ENABLED)))
6948 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6950 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6951 T3_PCI_SELECT_ALTERNATE_CLOCK;
6953 else if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6955 Value32 = T3_PCI_625_CORE_CLOCK;
6957 else
6959 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
6961 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6963 MM_Wait(40);
6965 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
6966 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6968 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6969 T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
6971 else if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6973 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_625_CORE_CLOCK;
6975 else
6977 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
6980 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
6982 if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
6984 MM_Wait(40);
6986 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
6987 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
6989 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
6990 T3_PCI_44MHZ_CORE_CLOCK;
6992 else
6994 Value32 = T3_PCI_44MHZ_CORE_CLOCK;
6997 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl | Value32);
7001 MM_Wait(40);
7003 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
7005 pDevice2 = MM_FindPeerDev(pDevice);
7007 if (!(pDevice->Flags & EEPROM_WP_FLAG))
7009 LM_SwitchVaux(pDevice, pDevice2);
7012 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
7014 /* Set the phy to low power mode. */
7015 /* Put the the hardware in low power mode. */
7016 if (!(pDevice->Flags & DISABLE_D3HOT_FLAG))
7018 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
7021 pDevice->PowerLevel = PowerLevel;
7023 #else
7024 LM_WritePostResetSignatures(pDevice, LM_SHUTDOWN_RESET);
7025 #endif /* BCM_WOL */
7027 return LM_STATUS_SUCCESS;
7028 } /* LM_SetPowerState */
7031 LM_VOID
7032 LM_SwitchVaux(PLM_DEVICE_BLOCK pDevice, PLM_DEVICE_BLOCK pDevice2)
7034 pDevice->GrcLocalCtrl &= ~(GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7035 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7036 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7037 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7038 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7039 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7041 /* Switch adapter to auxilliary power if WOL enabled */
7042 if ((pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
7043 (pDevice->AsfFlags & ASF_ENABLED) ||
7044 (pDevice2 && ((pDevice2->WakeUpModeCap != LM_WAKE_UP_MODE_NONE) ||
7045 (pDevice2->AsfFlags & ASF_ENABLED))))
7047 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
7048 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
7050 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
7051 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7052 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7053 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7054 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7055 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7056 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7057 MM_Wait(40);
7059 else
7061 if (pDevice2 && pDevice2->InitDone)
7063 return;
7066 /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
7067 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7068 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7069 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7070 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7071 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7072 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7073 MM_Wait(40);
7075 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
7076 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7077 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7078 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7079 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7080 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7081 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
7082 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
7083 MM_Wait(40);
7085 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
7086 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7087 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
7088 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7089 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
7090 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
7091 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7092 MM_Wait(40);
7095 else /* WOL disabled */
7097 if ((T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700) &&
7098 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701))
7100 if (pDevice2 && pDevice2->InitDone)
7102 return;
7105 /* GPIO1 = 1 */
7106 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7107 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7108 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7109 MM_Wait(40);
7111 /* GPIO1 = 0 */
7112 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7113 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
7114 MM_Wait(40);
7116 /* GPIO1 = 1 */
7117 RAW_REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
7118 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
7119 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
7120 MM_Wait(40);
7126 /******************************************************************************/
7127 /* Description: */
7128 /* */
7129 /* Return: */
7130 /******************************************************************************/
7131 static LM_UINT32
7132 GetPhyAdFlowCntrlSettings(
7133 PLM_DEVICE_BLOCK pDevice)
7135 LM_UINT32 Value32;
7137 Value32 = 0;
7139 /* Auto negotiation flow control only when autonegotiation is enabled. */
7140 if(pDevice->DisableAutoNeg == FALSE ||
7141 pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO)
7143 /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
7144 if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
7145 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
7146 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
7148 Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
7150 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
7152 Value32 |= PHY_AN_AD_ASYM_PAUSE;
7154 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
7156 Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
7160 return Value32;
7165 /******************************************************************************/
7166 /* Description: */
7167 /* */
7168 /* Return: */
7169 /* LM_STATUS_FAILURE */
7170 /* LM_STATUS_SUCCESS */
7171 /* */
7172 /******************************************************************************/
7173 static LM_STATUS
7174 LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice)
7176 LM_LINE_SPEED LineSpeed;
7177 LM_DUPLEX_MODE DuplexMode;
7178 LM_UINT32 NewPhyCtrl;
7179 LM_UINT32 Value32, PhyReg18;
7180 LM_UINT32 Cnt;
7182 /* Get the interface type, line speed, and duplex mode. */
7183 LineSpeed = pDevice->RequestedLineSpeed;
7184 DuplexMode = pDevice->RequestedDuplexMode;
7186 /* Exit ext. loop back, in case it was in ext. loopback mode */
7187 /* Set Extended packet length bit on chips that support jumbo frames */
7188 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
7190 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x4c20);
7192 else
7194 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
7195 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
7196 PhyReg18 &= ~0x8000; /* clear external loop back */
7197 if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7199 PhyReg18 |= 0x4000; /* set extended packet length */
7201 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
7204 #ifdef BCM_WOL
7205 if (pDevice->RestoreOnWakeUp)
7207 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7208 pDevice->advertising1000 = 0;
7209 Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
7210 if (pDevice->WolSpeed == WOL_SPEED_100MB)
7212 Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
7214 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7215 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7216 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7217 pDevice->advertising = Value32;
7219 /* Setup the auto-negotiation advertisement register. */
7220 else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
7221 #else
7222 /* Setup the auto-negotiation advertisement register. */
7223 if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
7224 #endif
7226 /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
7227 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD | PHY_AN_AD_ALL_SPEEDS;
7228 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7230 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7231 pDevice->advertising = Value32;
7233 /* Advertise 1000Mbps */
7234 if (!(pDevice->PhyFlags & PHY_NO_GIGABIT))
7236 Value32 = BCM540X_AN_AD_ALL_1G_SPEEDS;
7238 #if INCLUDE_5701_AX_FIX
7239 /* Bug: workaround for CRC error in gigabit mode when we are in */
7240 /* slave mode. This will force the PHY to operate in */
7241 /* master mode. */
7242 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
7243 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
7245 Value32 |= BCM540X_CONFIG_AS_MASTER |
7246 BCM540X_ENABLE_CONFIG_AS_MASTER;
7248 #endif
7250 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
7251 pDevice->advertising1000 = Value32;
7254 else
7256 if ((pDevice->PhyFlags & PHY_NO_GIGABIT) &&
7257 (LineSpeed == LM_LINE_SPEED_1000MBPS))
7259 LineSpeed = LM_LINE_SPEED_100MBPS;
7261 if(LineSpeed == LM_LINE_SPEED_1000MBPS)
7263 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7264 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7266 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7267 pDevice->advertising = Value32;
7269 if(DuplexMode != LM_DUPLEX_MODE_FULL)
7271 Value32 = BCM540X_AN_AD_1000BASET_HALF;
7273 else
7275 Value32 = BCM540X_AN_AD_1000BASET_FULL;
7278 #if INCLUDE_5701_AX_FIX
7279 if ((pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE) ||
7280 (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
7281 pDevice->ChipRevId == T3_CHIP_ID_5701_B0))
7282 #else
7283 if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
7284 #endif
7286 Value32 |= BCM540X_CONFIG_AS_MASTER |
7287 BCM540X_ENABLE_CONFIG_AS_MASTER;
7289 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
7290 pDevice->advertising1000 = Value32;
7291 if (pDevice->LoopBackMode == LM_EXT_LOOP_BACK_MODE)
7293 if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
7295 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x8c20);
7297 else
7299 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0007);
7300 LM_ReadPhy(pDevice, BCM5401_AUX_CTRL, &PhyReg18);
7301 Value32 |= 0x8000; /* set loop back */
7302 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, PhyReg18);
7306 else if(LineSpeed == LM_LINE_SPEED_100MBPS)
7308 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7309 pDevice->advertising1000 = 0;
7311 if(DuplexMode != LM_DUPLEX_MODE_FULL)
7313 Value32 = PHY_AN_AD_100BASETX_HALF;
7315 else
7317 Value32 = PHY_AN_AD_100BASETX_FULL;
7320 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7321 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7323 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7324 pDevice->advertising = Value32;
7326 else if(LineSpeed == LM_LINE_SPEED_10MBPS)
7328 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
7329 pDevice->advertising1000 = 0;
7331 if(DuplexMode != LM_DUPLEX_MODE_FULL)
7333 Value32 = PHY_AN_AD_10BASET_HALF;
7335 else
7337 Value32 = PHY_AN_AD_10BASET_FULL;
7340 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
7341 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
7343 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
7344 pDevice->advertising = Value32;
7348 /* Force line speed if auto-negotiation is disabled. */
7349 if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
7351 /* This code path is executed only when there is link. */
7352 pDevice->LineSpeed = LineSpeed;
7353 pDevice->DuplexMode = DuplexMode;
7355 /* Force line seepd. */
7356 NewPhyCtrl = 0;
7357 switch(LineSpeed)
7359 case LM_LINE_SPEED_10MBPS:
7360 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
7361 break;
7362 case LM_LINE_SPEED_100MBPS:
7363 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
7364 break;
7365 case LM_LINE_SPEED_1000MBPS:
7366 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
7367 break;
7368 default:
7369 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
7370 break;
7373 if(DuplexMode == LM_DUPLEX_MODE_FULL)
7375 NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
7378 /* Don't do anything if the PHY_CTRL is already what we wanted. */
7379 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
7380 if(Value32 != NewPhyCtrl)
7382 /* Temporary bring the link down before forcing line speed. */
7383 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
7385 /* Wait for link to go down. */
7386 for(Cnt = 0; Cnt < 1500; Cnt++)
7388 MM_Wait(10);
7390 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7391 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
7393 if(!(Value32 & PHY_STATUS_LINK_PASS))
7395 MM_Wait(40);
7396 break;
7400 LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
7401 MM_Wait(40);
7404 else
7406 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
7407 PHY_CTRL_RESTART_AUTO_NEG);
7410 return LM_STATUS_SUCCESS;
7411 } /* LM_ForceAutoNegBcm540xPhy */
7413 /******************************************************************************/
7414 /* Description: */
7415 /* */
7416 /* Return: */
7417 /******************************************************************************/
7418 LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
7419 PT3_FWIMG_INFO pFwImg,
7420 LM_UINT32 LoadCpu,
7421 LM_UINT32 StartCpu)
7423 LM_UINT32 i;
7424 LM_UINT32 address;
7425 LM_VOID (*Wr_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register,LM_UINT32 Value32);
7426 LM_UINT32 (*Rd_fn)(PLM_DEVICE_BLOCK pDevice,LM_UINT32 Register);
7427 LM_UINT32 len;
7428 LM_UINT32 base_addr;
7430 #if INCLUDE_TCP_SEG_SUPPORT
7431 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705)
7433 Wr_fn = LM_MemWrInd;
7434 Rd_fn = LM_MemRdInd;
7435 len = LM_GetStkOffLdFirmwareSize(pDevice);
7436 base_addr = T3_NIC_BCM5705_MBUF_POOL_ADDR;
7438 else
7439 #endif
7441 Wr_fn = LM_RegWrInd;
7442 Rd_fn = LM_RegRdInd;
7443 len = T3_RX_CPU_SPAD_SIZE;
7444 base_addr = T3_RX_CPU_SPAD_ADDR;
7447 if (LoadCpu & T3_RX_CPU_ID)
7449 if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
7451 return LM_STATUS_FAILURE;
7454 /* First of all clear scrach pad memory */
7455 for (i = 0; i < len; i+=4)
7457 Wr_fn(pDevice,base_addr+i,0);
7460 /* Copy code first */
7461 address = base_addr + (pFwImg->Text.Offset & 0xffff);
7462 for (i = 0; i <= pFwImg->Text.Length; i+=4)
7464 Wr_fn(pDevice,address+i,
7465 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
7468 address = base_addr + (pFwImg->ROnlyData.Offset & 0xffff);
7469 for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
7471 Wr_fn(pDevice,address+i,
7472 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
7475 address = base_addr + (pFwImg->Data.Offset & 0xffff);
7476 for (i= 0; i <= pFwImg->Data.Length; i+=4)
7478 Wr_fn(pDevice,address+i,
7479 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
7483 if ((LoadCpu & T3_TX_CPU_ID) &&
7484 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
7486 if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
7488 return LM_STATUS_FAILURE;
7491 /* First of all clear scrach pad memory */
7492 for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
7494 Wr_fn(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
7497 /* Copy code first */
7498 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
7499 for (i= 0; i <= pFwImg->Text.Length; i+=4)
7501 Wr_fn(pDevice,address+i,
7502 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
7505 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
7506 for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
7508 Wr_fn(pDevice,address+i,
7509 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
7512 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
7513 for (i= 0; i <= pFwImg->Data.Length; i+=4)
7515 Wr_fn(pDevice,address+i,
7516 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
7520 if (StartCpu & T3_RX_CPU_ID)
7522 /* Start Rx CPU */
7523 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7524 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
7525 for (i = 0 ; i < 5; i++)
7527 if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
7528 break;
7530 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7531 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7532 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
7533 REG_RD_BACK(pDevice,rxCpu.reg.PC);
7534 MM_Wait(1000);
7537 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7538 REG_WR(pDevice,rxCpu.reg.mode, 0);
7541 if ((StartCpu & T3_TX_CPU_ID) &&
7542 (T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5705))
7544 /* Start Tx CPU */
7545 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7546 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
7547 for (i = 0 ; i < 5; i++)
7549 if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
7550 break;
7552 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7553 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
7554 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
7555 REG_RD_BACK(pDevice,txCpu.reg.PC);
7556 MM_Wait(1000);
7559 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7560 REG_WR(pDevice,txCpu.reg.mode, 0);
7563 return LM_STATUS_SUCCESS;
7566 LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
7568 LM_UINT32 i;
7570 if((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5705) &&
7571 (cpu_number != T3_RX_CPU_ID))
7573 return LM_STATUS_SUCCESS;
7576 if (cpu_number == T3_RX_CPU_ID)
7578 for (i = 0 ; i < 10000; i++)
7580 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7581 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7583 if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
7584 break;
7587 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
7588 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
7589 REG_RD_BACK(pDevice,rxCpu.reg.mode);
7590 MM_Wait(10);
7592 else
7594 for (i = 0 ; i < 10000; i++)
7596 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
7597 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
7599 if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
7600 break;
7604 return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
7608 LM_STATUS
7609 LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
7611 int j;
7612 int ret = LM_STATUS_SUCCESS;
7614 if(BlinkDurationSec == 0)
7616 BlinkDurationSec = 1;
7618 if(BlinkDurationSec > 120)
7620 BlinkDurationSec = 120;
7623 for(j = 0; j < BlinkDurationSec * 2; j++)
7625 if(j % 2)
7627 // Turn on the LEDs.
7628 REG_WR(pDevice, MacCtrl.LedCtrl,
7629 LED_CTRL_OVERRIDE_LINK_LED |
7630 LED_CTRL_1000MBPS_LED_ON |
7631 LED_CTRL_100MBPS_LED_ON |
7632 LED_CTRL_10MBPS_LED_ON |
7633 LED_CTRL_OVERRIDE_TRAFFIC_LED |
7634 LED_CTRL_BLINK_TRAFFIC_LED |
7635 LED_CTRL_TRAFFIC_LED);
7637 else
7639 // Turn off the LEDs.
7640 REG_WR(pDevice, MacCtrl.LedCtrl,
7641 LED_CTRL_OVERRIDE_LINK_LED |
7642 LED_CTRL_OVERRIDE_TRAFFIC_LED);
7644 if (MM_Sleep(pDevice, 500) != LM_STATUS_SUCCESS)/* 0.5 second */
7646 ret = LM_STATUS_FAILURE;
7647 break;
7650 REG_WR(pDevice, MacCtrl.LedCtrl, pDevice->LedCtrl);
7651 return ret;
7654 LM_STATUS
7655 LM_SwitchClocks(PLM_DEVICE_BLOCK pDevice)
7657 LM_UINT32 ClockCtrl;
7659 ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl);
7660 pDevice->ClockCtrl = ClockCtrl & (T3_PCI_FORCE_CLKRUN |
7661 T3_PCI_CLKRUN_OUTPUT_EN | 0x1f);
7662 if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7664 if (ClockCtrl & T3_PCI_625_CORE_CLOCK)
7666 /* clear ALT clock first */
7667 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7668 T3_PCI_625_CORE_CLOCK);
7669 MM_Wait(40); /* required delay is 27usec */
7672 else
7674 if (ClockCtrl & T3_PCI_44MHZ_CORE_CLOCK)
7676 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7677 T3_PCI_44MHZ_CORE_CLOCK | T3_PCI_SELECT_ALTERNATE_CLOCK);
7678 MM_Wait(40); /* required delay is 27usec */
7679 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl |
7680 T3_PCI_SELECT_ALTERNATE_CLOCK);
7681 MM_Wait(40); /* required delay is 27usec */
7685 RAW_REG_WR(pDevice, PciCfg.ClockCtrl, pDevice->ClockCtrl);
7686 MM_Wait(40); /* required delay is 27usec */
7687 return LM_STATUS_SUCCESS;
7690 int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
7691 LM_PHYSICAL_ADDRESS host_addr_phy, int length,
7692 int dma_read)
7694 T3_DMA_DESC dma_desc;
7695 int i;
7696 LM_UINT32 dma_desc_addr;
7697 LM_UINT32 value32;
7699 REG_WR(pDevice, BufMgr.Mode, 0);
7700 REG_WR(pDevice, Ftq.Reset, 0);
7702 dma_desc.host_addr.High = host_addr_phy.High;
7703 dma_desc.host_addr.Low = host_addr_phy.Low;
7704 dma_desc.nic_mbuf = 0x2100;
7705 dma_desc.len = length;
7706 dma_desc.flags = 0x00000005; /* Generate Rx-CPU event */
7708 if (dma_read)
7710 dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
7711 T3_QID_DMA_HIGH_PRI_READ;
7712 REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
7714 else
7716 dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
7717 T3_QID_DMA_HIGH_PRI_WRITE;
7718 REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
7721 dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
7723 /* Writing this DMA descriptor to DMA memory */
7724 for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
7726 value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
7727 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
7728 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG,
7729 MM_SWAP_LE32(value32));
7731 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
7733 if (dma_read)
7734 REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
7735 else
7736 REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
7738 for (i = 0; i < 40; i++)
7740 if (dma_read)
7741 value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
7742 else
7743 value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
7745 if ((value32 & 0xffff) == dma_desc_addr)
7746 break;
7748 MM_Wait(10);
7751 return LM_STATUS_SUCCESS;
7754 STATIC LM_STATUS
7755 LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
7756 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
7758 int j;
7759 LM_UINT32 *ptr;
7760 int dma_success = 0;
7761 LM_STATUS ret = LM_STATUS_FAILURE;
7763 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
7764 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
7766 return LM_STATUS_SUCCESS;
7768 while (!dma_success)
7770 /* Fill data with incremental patterns */
7771 ptr = (LM_UINT32 *)pBufferVirt;
7772 for (j = 0; j < BufferSize/4; j++)
7773 *ptr++ = j;
7775 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
7777 goto LM_DmaTestDone;
7780 MM_Wait(40);
7781 ptr = (LM_UINT32 *)pBufferVirt;
7782 /* Fill data with zero */
7783 for (j = 0; j < BufferSize/4; j++)
7784 *ptr++ = 0;
7786 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
7788 goto LM_DmaTestDone;
7791 MM_Wait(40);
7792 /* Check for data */
7793 ptr = (LM_UINT32 *)pBufferVirt;
7794 for (j = 0; j < BufferSize/4; j++)
7796 if (*ptr++ != j)
7798 if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
7799 != DMA_CTRL_WRITE_BOUNDARY_16)
7801 pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
7802 ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
7803 DMA_CTRL_WRITE_BOUNDARY_16;
7804 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
7805 pDevice->DmaReadWriteCtrl);
7806 break;
7808 else
7810 goto LM_DmaTestDone;
7814 if (j == (BufferSize/4))
7815 dma_success = 1;
7817 ret = LM_STATUS_SUCCESS;
7818 LM_DmaTestDone:
7819 memset(pBufferVirt, 0, BufferSize);
7820 return ret;
7823 void
7824 LM_Add32To64Counter(LM_UINT32 Counter32, T3_64BIT_REGISTER *Counter64)
7826 Counter64->Low += Counter32;
7827 if (Counter64->Low < Counter32)
7829 Counter64->High++;
7833 LM_STATUS
7834 LM_GetStats(PLM_DEVICE_BLOCK pDevice)
7836 PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
7838 if (!T3_ASIC_5705_OR_5750(pDevice->ChipRevId))
7840 return LM_STATUS_FAILURE;
7843 if (pStats == 0)
7845 return LM_STATUS_FAILURE;
7847 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutOctets),
7848 &pStats->ifHCOutOctets);
7849 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsCollisions),
7850 &pStats->etherStatsCollisions);
7851 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXonSent),
7852 &pStats->outXonSent);
7853 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.outXoffSent),
7854 &pStats->outXoffSent);
7855 LM_Add32To64Counter(REG_RD(pDevice,
7856 MacCtrl.dot3StatsInternalMacTransmitErrors),
7857 &pStats->dot3StatsInternalMacTransmitErrors);
7858 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsSingleCollisionFrames),
7859 &pStats->dot3StatsSingleCollisionFrames);
7860 LM_Add32To64Counter(REG_RD(pDevice,
7861 MacCtrl.dot3StatsMultipleCollisionFrames),
7862 &pStats->dot3StatsMultipleCollisionFrames);
7863 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsDeferredTransmissions),
7864 &pStats->dot3StatsDeferredTransmissions);
7865 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsExcessiveCollisions),
7866 &pStats->dot3StatsExcessiveCollisions);
7867 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsLateCollisions),
7868 &pStats->dot3StatsLateCollisions);
7869 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutUcastPkts),
7870 &pStats->ifHCOutUcastPkts);
7871 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutMulticastPkts),
7872 &pStats->ifHCOutMulticastPkts);
7873 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCOutBroadcastPkts),
7874 &pStats->ifHCOutBroadcastPkts);
7875 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInOctets),
7876 &pStats->ifHCInOctets);
7877 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsFragments),
7878 &pStats->etherStatsFragments);
7879 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInUcastPkts),
7880 &pStats->ifHCInUcastPkts);
7881 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInMulticastPkts),
7882 &pStats->ifHCInMulticastPkts);
7883 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.ifHCInBroadcastPkts),
7884 &pStats->ifHCInBroadcastPkts);
7885 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFCSErrors),
7886 &pStats->dot3StatsFCSErrors);
7887 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsAlignmentErrors),
7888 &pStats->dot3StatsAlignmentErrors);
7889 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xonPauseFramesReceived),
7890 &pStats->xonPauseFramesReceived);
7891 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffPauseFramesReceived),
7892 &pStats->xoffPauseFramesReceived);
7893 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.macControlFramesReceived),
7894 &pStats->macControlFramesReceived);
7895 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.xoffStateEntered),
7896 &pStats->xoffStateEntered);
7897 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.dot3StatsFramesTooLong),
7898 &pStats->dot3StatsFramesTooLong);
7899 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsJabbers),
7900 &pStats->etherStatsJabbers);
7901 LM_Add32To64Counter(REG_RD(pDevice, MacCtrl.etherStatsUndersizePkts),
7902 &pStats->etherStatsUndersizePkts);
7904 return LM_STATUS_SUCCESS;