1 /******************************************************************************/
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
5 /* All rights reserved. */
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. */
12 /******************************************************************************/
14 #include <asm/types.h>
15 #if (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \
16 defined(CONFIG_TIGON3)
21 #include <linux/byteorder/big_endian.h>
22 #include "bcm570x_mm.h"
25 /******************************************************************************/
26 /* Local functions. */
27 /******************************************************************************/
29 LM_STATUS LM_Abort(PLM_DEVICE_BLOCK pDevice);
30 LM_STATUS LM_QueueRxPackets(PLM_DEVICE_BLOCK pDevice);
32 static LM_STATUS LM_TranslateRequestedMediaType(
33 LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
34 PLM_MEDIA_TYPE pMediaType, PLM_LINE_SPEED pLineSpeed,
35 PLM_DUPLEX_MODE pDuplexMode);
37 static LM_STATUS LM_InitBcm540xPhy(PLM_DEVICE_BLOCK pDevice);
39 __inline static LM_VOID LM_ServiceRxInterrupt(PLM_DEVICE_BLOCK pDevice);
40 __inline static LM_VOID LM_ServiceTxInterrupt(PLM_DEVICE_BLOCK pDevice);
42 static LM_STATUS LM_ForceAutoNegBcm540xPhy(PLM_DEVICE_BLOCK pDevice,
43 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
44 static LM_STATUS LM_ForceAutoNeg(PLM_DEVICE_BLOCK pDevice,
45 LM_REQUESTED_MEDIA_TYPE RequestedMediaType);
46 static LM_UINT32 GetPhyAdFlowCntrlSettings(PLM_DEVICE_BLOCK pDevice);
47 STATIC LM_STATUS LM_SetFlowControl(PLM_DEVICE_BLOCK pDevice,
48 LM_UINT32 LocalPhyAd, LM_UINT32 RemotePhyAd);
49 #if INCLUDE_TBI_SUPPORT
50 STATIC LM_STATUS LM_SetupFiberPhy(PLM_DEVICE_BLOCK pDevice);
51 STATIC LM_STATUS LM_InitBcm800xPhy(PLM_DEVICE_BLOCK pDevice);
53 STATIC LM_STATUS LM_SetupCopperPhy(PLM_DEVICE_BLOCK pDevice);
54 STATIC PLM_ADAPTER_INFO LM_GetAdapterInfoBySsid(LM_UINT16 Svid, LM_UINT16 Ssid);
55 STATIC LM_STATUS LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
56 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize);
57 STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number);
58 STATIC LM_STATUS LM_ResetChip(PLM_DEVICE_BLOCK pDevice);
59 STATIC LM_STATUS LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
62 /******************************************************************************/
63 /* External functions. */
64 /******************************************************************************/
66 LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice);
69 /******************************************************************************/
73 /******************************************************************************/
76 PLM_DEVICE_BLOCK pDevice,
80 #if PCIX_TARGET_WORKAROUND
81 MM_ACQUIRE_UNDI_LOCK(pDevice);
83 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
84 MM_ReadConfig32(pDevice, T3_PCI_REG_DATA_REG, &Value32);
85 #if PCIX_TARGET_WORKAROUND
86 MM_RELEASE_UNDI_LOCK(pDevice);
94 /******************************************************************************/
98 /******************************************************************************/
101 PLM_DEVICE_BLOCK pDevice,
105 #if PCIX_TARGET_WORKAROUND
106 MM_ACQUIRE_UNDI_LOCK(pDevice);
108 MM_WriteConfig32(pDevice, T3_PCI_REG_ADDR_REG, Register);
109 MM_WriteConfig32(pDevice, T3_PCI_REG_DATA_REG, Value32);
110 #if PCIX_TARGET_WORKAROUND
111 MM_RELEASE_UNDI_LOCK(pDevice);
117 /******************************************************************************/
121 /******************************************************************************/
124 PLM_DEVICE_BLOCK pDevice,
128 MM_ACQUIRE_UNDI_LOCK(pDevice);
129 #ifdef BIG_ENDIAN_HOST
130 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
131 Value32 = REG_RD(pDevice, PciCfg.MemWindowData);
132 /* Value32 = REG_RD(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4]); */
134 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
135 MM_ReadConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, &Value32);
137 MM_RELEASE_UNDI_LOCK(pDevice);
144 /******************************************************************************/
148 /******************************************************************************/
151 PLM_DEVICE_BLOCK pDevice,
154 MM_ACQUIRE_UNDI_LOCK(pDevice);
155 #ifdef BIG_ENDIAN_HOST
156 REG_WR(pDevice,PciCfg.MemWindowBaseAddr,MemAddr);
157 REG_WR(pDevice,uIntMem.Mbuf[(MemAddr & 0x7fff)/4],Value32);
159 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, MemAddr);
160 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, Value32);
162 MM_RELEASE_UNDI_LOCK(pDevice);
167 /******************************************************************************/
171 /******************************************************************************/
174 PLM_DEVICE_BLOCK pDevice) {
178 LM_UINT32 StdBdAdded = 0;
179 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
180 LM_UINT32 JumboBdAdded = 0;
181 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
183 Lmstatus = LM_STATUS_SUCCESS;
185 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
187 switch(pPacket->u.Rx.RcvProdRing) {
188 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
189 case T3_JUMBO_RCV_PROD_RING: /* Jumbo Receive Ring. */
190 /* Initialize the buffer descriptor. */
192 &pDevice->pRxJumboBdVirt[pDevice->RxJumboProdIdx];
193 pRcvBd->Flags = RCV_BD_FLAG_END | RCV_BD_FLAG_JUMBO_RING;
194 pRcvBd->Len = (LM_UINT16) pDevice->RxJumboBufferSize;
196 /* Initialize the receive buffer pointer */
197 #if 0 /* Jimmy, deleted in new */
198 pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
199 pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
201 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
203 /* The opaque field may point to an offset from a fix addr. */
204 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
205 MM_UINT_PTR(pDevice->pPacketDescBase));
207 /* Update the producer index. */
208 pDevice->RxJumboProdIdx = (pDevice->RxJumboProdIdx + 1) &
209 T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
213 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
215 case T3_STD_RCV_PROD_RING: /* Standard Receive Ring. */
216 /* Initialize the buffer descriptor. */
217 pRcvBd = &pDevice->pRxStdBdVirt[pDevice->RxStdProdIdx];
218 pRcvBd->Flags = RCV_BD_FLAG_END;
219 pRcvBd->Len = MAX_STD_RCV_BUFFER_SIZE;
221 /* Initialize the receive buffer pointer */
222 #if 0 /* Jimmy, deleted in new replaced with MM_MapRxDma */
223 pRcvBd->HostAddr.Low = pPacket->u.Rx.RxBufferPhy.Low;
224 pRcvBd->HostAddr.High = pPacket->u.Rx.RxBufferPhy.High;
226 MM_MapRxDma(pDevice, pPacket, &pRcvBd->HostAddr);
228 /* The opaque field may point to an offset from a fix addr. */
229 pRcvBd->Opaque = (LM_UINT32) (MM_UINT_PTR(pPacket) -
230 MM_UINT_PTR(pDevice->pPacketDescBase));
232 /* Update the producer index. */
233 pDevice->RxStdProdIdx = (pDevice->RxStdProdIdx + 1) &
234 T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
239 case T3_UNKNOWN_RCV_PROD_RING:
241 Lmstatus = LM_STATUS_FAILURE;
245 /* Bail out if there is any error. */
246 if(Lmstatus != LM_STATUS_SUCCESS)
251 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
255 /* Update the procedure index. */
258 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, pDevice->RxStdProdIdx);
260 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
263 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low,
264 pDevice->RxJumboProdIdx);
266 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
269 } /* LM_QueueRxPackets */
272 /******************************************************************************/
276 /******************************************************************************/
279 PLM_DEVICE_BLOCK pDevice)
284 /* Intialize clock period and state machine. */
285 Value32 = SEEPROM_ADDR_CLK_PERD(SEEPROM_CLOCK_PERIOD) |
286 SEEPROM_ADDR_FSM_RESET;
287 REG_WR(pDevice, Grc.EepromAddr, Value32);
289 for(j = 0; j < 100; j++)
294 /* Serial eeprom access using the Grc.EepromAddr/EepromData registers. */
295 Value32 = REG_RD(pDevice, Grc.LocalCtrl);
296 REG_WR(pDevice, Grc.LocalCtrl, Value32 | GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM);
298 /* Set the 5701 compatibility mode if we are using EEPROM. */
299 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
300 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
302 Value32 = REG_RD(pDevice, Nvram.Config1);
303 if((Value32 & FLASH_INTERFACE_ENABLE) == 0)
305 /* Use the new interface to read EEPROM. */
306 Value32 &= ~FLASH_COMPAT_BYPASS;
308 REG_WR(pDevice, Nvram.Config1, Value32);
314 /******************************************************************************/
318 /******************************************************************************/
321 PLM_DEVICE_BLOCK pDevice,
330 if(Offset > SEEPROM_CHIP_SIZE)
332 return LM_STATUS_FAILURE;
335 Dev = Offset / SEEPROM_CHIP_SIZE;
336 Addr = Offset % SEEPROM_CHIP_SIZE;
338 Value32 = REG_RD(pDevice, Grc.EepromAddr);
339 Value32 &= ~(SEEPROM_ADDR_ADDRESS_MASK | SEEPROM_ADDR_DEV_ID_MASK |
340 SEEPROM_ADDR_RW_MASK);
341 REG_WR(pDevice, Grc.EepromAddr, Value32 | SEEPROM_ADDR_DEV_ID(Dev) |
342 SEEPROM_ADDR_ADDRESS(Addr) | SEEPROM_ADDR_START | SEEPROM_ADDR_READ);
344 for(j = 0; j < 1000; j++)
346 Value32 = REG_RD(pDevice, Grc.EepromAddr);
347 if(Value32 & SEEPROM_ADDR_COMPLETE)
354 if(Value32 & SEEPROM_ADDR_COMPLETE)
356 Value32 = REG_RD(pDevice, Grc.EepromData);
359 return LM_STATUS_SUCCESS;
362 return LM_STATUS_FAILURE;
363 } /* LM_EepromRead */
367 /******************************************************************************/
371 /******************************************************************************/
374 PLM_DEVICE_BLOCK pDevice,
382 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
383 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
385 Status = LM_EepromRead(pDevice, Offset, pData);
389 /* Determine if we have flash or EEPROM. */
390 Value32 = REG_RD(pDevice, Nvram.Config1);
391 if(Value32 & FLASH_INTERFACE_ENABLE)
393 if(Value32 & FLASH_SSRAM_BUFFERRED_MODE)
395 Offset = ((Offset/BUFFERED_FLASH_PAGE_SIZE) <<
396 BUFFERED_FLASH_PAGE_POS) +
397 (Offset % BUFFERED_FLASH_PAGE_SIZE);
401 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
402 for (j = 0; j < 1000; j++)
404 if (REG_RD(pDevice, Nvram.SwArb) & SW_ARB_GNT1)
412 return LM_STATUS_FAILURE;
415 /* Read from flash or EEPROM with the new 5703/02 interface. */
416 REG_WR(pDevice, Nvram.Addr, Offset & NVRAM_ADDRESS_MASK);
418 REG_WR(pDevice, Nvram.Cmd, NVRAM_CMD_RD | NVRAM_CMD_DO_IT |
419 NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
421 /* Wait for the done bit to clear. */
422 for(j = 0; j < 500; j++)
426 Value32 = REG_RD(pDevice, Nvram.Cmd);
427 if(!(Value32 & NVRAM_CMD_DONE))
433 /* Wait for the done bit. */
434 if(!(Value32 & NVRAM_CMD_DONE))
436 for(j = 0; j < 500; j++)
440 Value32 = REG_RD(pDevice, Nvram.Cmd);
441 if(Value32 & NVRAM_CMD_DONE)
445 *pData = REG_RD(pDevice, Nvram.ReadData);
447 /* Change the endianess. */
448 *pData = ((*pData & 0xff) << 24)| ((*pData & 0xff00) << 8)|
449 ((*pData & 0xff0000) >> 8) | ((*pData >> 24) & 0xff);
456 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_CLR1);
457 if(Value32 & NVRAM_CMD_DONE)
459 Status = LM_STATUS_SUCCESS;
463 Status = LM_STATUS_FAILURE;
472 LM_ReadVPD(PLM_DEVICE_BLOCK pDevice)
474 LM_UINT32 Vpd_arr[256/4];
475 LM_UINT8 *Vpd = (LM_UINT8 *) &Vpd_arr[0];
476 LM_UINT32 *Vpd_dptr = &Vpd_arr[0];
480 /* Read PN from VPD */
481 for (j = 0; j < 256; j += 4, Vpd_dptr++ )
483 if (LM_NvramRead(pDevice, 0x100 + j, &Value32) != LM_STATUS_SUCCESS) {
484 printf("BCM570x: LM_ReadVPD: VPD read failed"
485 " (no EEPROM onboard)\n");
488 *Vpd_dptr = cpu_to_le32(Value32);
490 for (j = 0; j < 256; )
492 unsigned int Vpd_r_len;
493 unsigned int Vpd_r_end;
495 if ((Vpd[j] == 0x82) || (Vpd[j] == 0x91))
497 j = j + 3 + Vpd[j + 1] + (Vpd[j + 2] << 8);
499 else if (Vpd[j] == 0x90)
501 Vpd_r_len = Vpd[j + 1] + (Vpd[j + 2] << 8);
503 Vpd_r_end = Vpd_r_len + j;
504 while (j < Vpd_r_end)
506 if ((Vpd[j] == 'P') && (Vpd[j + 1] == 'N'))
508 unsigned int len = Vpd[j + 2];
512 memcpy(pDevice->PartNo, &Vpd[j + 3], len);
534 LM_ReadBootCodeVersion(PLM_DEVICE_BLOCK pDevice)
536 LM_UINT32 Value32, offset, ver_offset;
539 if (LM_NvramRead(pDevice, 0x0, &Value32) != LM_STATUS_SUCCESS)
541 if (Value32 != 0xaa559966)
543 if (LM_NvramRead(pDevice, 0xc, &offset) != LM_STATUS_SUCCESS)
546 offset = ((offset & 0xff) << 24)| ((offset & 0xff00) << 8)|
547 ((offset & 0xff0000) >> 8) | ((offset >> 24) & 0xff);
548 if (LM_NvramRead(pDevice, offset, &Value32) != LM_STATUS_SUCCESS)
550 if ((Value32 == 0x0300000e) &&
551 (LM_NvramRead(pDevice, offset + 4, &Value32) == LM_STATUS_SUCCESS) &&
554 if (LM_NvramRead(pDevice, offset + 8, &ver_offset) != LM_STATUS_SUCCESS)
556 ver_offset = ((ver_offset & 0xff0000) >> 8) |
557 ((ver_offset >> 24) & 0xff);
558 for (i = 0; i < 16; i += 4) {
559 if (LM_NvramRead(pDevice, offset + ver_offset + i, &Value32) !=
564 *((LM_UINT32 *) &pDevice->BootCodeVer[i]) = cpu_to_le32(Value32);
570 if (LM_NvramRead(pDevice, 0x94, &Value32) != LM_STATUS_SUCCESS)
574 c = ((Value32 & 0xff0000) >> 16);
577 pDevice->BootCodeVer[i++] = c + '0';
580 pDevice->BootCodeVer[i++] = (c / 10) + '0';
581 pDevice->BootCodeVer[i++] = (c % 10) + '0';
583 pDevice->BootCodeVer[i++] = '.';
584 c = (Value32 & 0xff000000) >> 24;
586 pDevice->BootCodeVer[i++] = c + '0';
589 pDevice->BootCodeVer[i++] = (c / 10) + '0';
590 pDevice->BootCodeVer[i++] = (c % 10) + '0';
592 pDevice->BootCodeVer[i] = 0;
597 LM_GetBusSpeed(PLM_DEVICE_BLOCK pDevice)
599 LM_UINT32 PciState = pDevice->PciState;
603 if (PciState & T3_PCI_STATE_32BIT_PCI_BUS)
605 strcpy(pDevice->BusSpeedStr, "32-bit ");
609 strcpy(pDevice->BusSpeedStr, "64-bit ");
611 if (PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)
613 strcat(pDevice->BusSpeedStr, "PCI ");
614 if (PciState & T3_PCI_STATE_HIGH_BUS_SPEED)
625 strcat(pDevice->BusSpeedStr, "PCIX ");
626 if (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE)
632 ClockCtrl = REG_RD(pDevice, PciCfg.ClockCtrl) & 0x1f;
657 strcat(pDevice->BusSpeedStr, SpeedStr);
660 /******************************************************************************/
662 /* This routine initializes default parameters and reads the PCI */
663 /* configurations. */
666 /* LM_STATUS_SUCCESS */
667 /******************************************************************************/
670 PLM_DEVICE_BLOCK pDevice)
672 PLM_ADAPTER_INFO pAdapterInfo;
676 LM_UINT32 EeSigFound;
677 LM_UINT32 EePhyTypeSerdes = 0;
678 LM_UINT32 EePhyLedMode = 0;
679 LM_UINT32 EePhyId = 0;
681 /* Get Device Id and Vendor Id */
682 Status = MM_ReadConfig32(pDevice, PCI_VENDOR_ID_REG, &Value32);
683 if(Status != LM_STATUS_SUCCESS)
687 pDevice->PciVendorId = (LM_UINT16) Value32;
688 pDevice->PciDeviceId = (LM_UINT16) (Value32 >> 16);
690 /* If we are not getting the write adapter, exit. */
691 if((Value32 != T3_PCI_ID_BCM5700) &&
692 (Value32 != T3_PCI_ID_BCM5701) &&
693 (Value32 != T3_PCI_ID_BCM5702) &&
694 (Value32 != T3_PCI_ID_BCM5702x) &&
695 (Value32 != T3_PCI_ID_BCM5702FE) &&
696 (Value32 != T3_PCI_ID_BCM5703) &&
697 (Value32 != T3_PCI_ID_BCM5703x) &&
698 (Value32 != T3_PCI_ID_BCM5704))
700 return LM_STATUS_FAILURE;
703 Status = MM_ReadConfig32(pDevice, PCI_REV_ID_REG, &Value32);
704 if(Status != LM_STATUS_SUCCESS)
708 pDevice->PciRevId = (LM_UINT8) Value32;
711 Status = MM_ReadConfig32(pDevice, PCI_INT_LINE_REG, &Value32);
712 if(Status != LM_STATUS_SUCCESS)
716 pDevice->Irq = (LM_UINT8) Value32;
718 /* Get interrupt pin. */
719 pDevice->IntPin = (LM_UINT8) (Value32 >> 8);
721 /* Get chip revision id. */
722 Status = MM_ReadConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, &Value32);
723 pDevice->ChipRevId = Value32 >> 16;
725 /* Get subsystem vendor. */
726 Status = MM_ReadConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG, &Value32);
727 if(Status != LM_STATUS_SUCCESS)
731 pDevice->SubsystemVendorId = (LM_UINT16) Value32;
733 /* Get PCI subsystem id. */
734 pDevice->SubsystemId = (LM_UINT16) (Value32 >> 16);
736 /* Get the cache line size. */
737 MM_ReadConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG, &Value32);
738 pDevice->CacheLineSize = (LM_UINT8) Value32;
739 pDevice->SavedCacheLineReg = Value32;
741 if(pDevice->ChipRevId != T3_CHIP_ID_5703_A1 &&
742 pDevice->ChipRevId != T3_CHIP_ID_5703_A2 &&
743 pDevice->ChipRevId != T3_CHIP_ID_5704_A0)
745 pDevice->UndiFix = FALSE;
747 #if !PCIX_TARGET_WORKAROUND
748 pDevice->UndiFix = FALSE;
750 /* Map the memory base to system address space. */
751 if (!pDevice->UndiFix)
753 Status = MM_MapMemBase(pDevice);
754 if(Status != LM_STATUS_SUCCESS)
758 /* Initialize the memory view pointer. */
759 pDevice->pMemView = (PT3_STD_MEM_MAP) pDevice->pMappedMemBase;
762 #if PCIX_TARGET_WORKAROUND
763 /* store whether we are in PCI are PCI-X mode */
764 pDevice->EnablePciXFix = FALSE;
766 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
767 if((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0)
769 /* Enable PCI-X workaround only if we are running on 5700 BX. */
770 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
772 pDevice->EnablePciXFix = TRUE;
775 if (pDevice->UndiFix)
777 pDevice->EnablePciXFix = TRUE;
780 /* Bx bug: due to the "byte_enable bug" in PCI-X mode, the power */
781 /* management register may be clobbered which may cause the */
782 /* BCM5700 to go into D3 state. While in this state, we will */
783 /* not have memory mapped register access. As a workaround, we */
784 /* need to restore the device to D0 state. */
785 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &Value32);
786 Value32 |= T3_PM_PME_ASSERTED;
787 Value32 &= ~T3_PM_POWER_STATE_MASK;
788 Value32 |= T3_PM_POWER_STATE_D0;
789 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, Value32);
791 /* read the current PCI command word */
792 MM_ReadConfig32(pDevice, PCI_COMMAND_REG, &Value32);
794 /* Make sure bus-mastering is enabled. */
795 Value32 |= PCI_BUSMASTER_ENABLE;
797 #if PCIX_TARGET_WORKAROUND
798 /* if we are in PCI-X mode, also make sure mem-mapping and SERR#/PERR#
800 if (pDevice->EnablePciXFix == TRUE) {
801 Value32 |= (PCI_MEM_SPACE_ENABLE | PCI_SYSTEM_ERROR_ENABLE |
802 PCI_PARITY_ERROR_ENABLE);
804 if (pDevice->UndiFix)
806 Value32 &= ~PCI_MEM_SPACE_ENABLE;
811 if(pDevice->EnableMWI)
813 Value32 |= PCI_MEMORY_WRITE_INVALIDATE;
816 Value32 &= (~PCI_MEMORY_WRITE_INVALIDATE);
819 /* Error out if mem-mapping is NOT enabled for PCI systems */
820 if (!(Value32 | PCI_MEM_SPACE_ENABLE))
822 return LM_STATUS_FAILURE;
825 /* save the value we are going to write into the PCI command word */
826 pDevice->PciCommandStatusWords = Value32;
828 Status = MM_WriteConfig32(pDevice, PCI_COMMAND_REG, Value32);
829 if(Status != LM_STATUS_SUCCESS)
834 /* Set power state to D0. */
835 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
837 #ifdef BIG_ENDIAN_PCI
838 pDevice->MiscHostCtrl =
839 MISC_HOST_CTRL_MASK_PCI_INT |
840 MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
841 MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
842 MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
843 #else /* No CPU Swap modes for PCI IO */
845 /* Setup the mode registers. */
846 pDevice->MiscHostCtrl =
847 MISC_HOST_CTRL_MASK_PCI_INT |
848 MISC_HOST_CTRL_ENABLE_ENDIAN_WORD_SWAP |
849 #ifdef BIG_ENDIAN_HOST
850 MISC_HOST_CTRL_ENABLE_ENDIAN_BYTE_SWAP |
851 #endif /* BIG_ENDIAN_HOST */
852 MISC_HOST_CTRL_ENABLE_INDIRECT_ACCESS |
853 MISC_HOST_CTRL_ENABLE_PCI_STATE_REG_RW;
854 #endif /* !BIG_ENDIAN_PCI */
856 /* write to PCI misc host ctr first in order to enable indirect accesses */
857 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
859 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl);
861 #ifdef BIG_ENDIAN_PCI
862 Value32 = GRC_MODE_WORD_SWAP_DATA|
863 GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
865 /* No CPU Swap modes for PCI IO */
866 #ifdef BIG_ENDIAN_HOST
867 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
868 GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
870 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
872 #endif /* !BIG_ENDIAN_PCI */
874 REG_WR(pDevice, Grc.Mode, Value32);
876 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
878 REG_WR(pDevice, Grc.LocalCtrl, GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
879 GRC_MISC_LOCAL_CTRL_GPIO_OE1);
883 /* Enable indirect memory access */
884 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
886 if (REG_RD(pDevice, PciCfg.ClockCtrl) & T3_PCI_44MHZ_CORE_CLOCK)
888 REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_44MHZ_CORE_CLOCK |
889 T3_PCI_SELECT_ALTERNATE_CLOCK);
890 REG_WR(pDevice, PciCfg.ClockCtrl, T3_PCI_SELECT_ALTERNATE_CLOCK);
891 MM_Wait(40); /* required delay is 27usec */
893 REG_WR(pDevice, PciCfg.ClockCtrl, 0);
894 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
896 #if PCIX_TARGET_WORKAROUND
897 MM_ReadConfig32(pDevice, T3_PCI_STATE_REG, &Value32);
898 if ((pDevice->EnablePciXFix == FALSE) &&
899 ((Value32 & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) == 0))
901 if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
902 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
903 pDevice->ChipRevId == T3_CHIP_ID_5701_B2 ||
904 pDevice->ChipRevId == T3_CHIP_ID_5701_B5)
906 __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x300]));
907 __raw_writel(0, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
908 __raw_writel(0xffffffff, &(pDevice->pMemView->uIntMem.MemBlock32K[0x301]));
909 if (__raw_readl(&(pDevice->pMemView->uIntMem.MemBlock32K[0x300])))
911 pDevice->EnablePciXFix = TRUE;
918 * This code was at the beginning of else block below, but that's
919 * a bug if node address in shared memory.
922 LM_NvramInit(pDevice);
924 /* Get the node address. First try to get in from the shared memory. */
925 /* If the signature is not present, then get it from the NVRAM. */
926 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_HIGH_MAILBOX);
927 if((Value32 >> 16) == 0x484b)
930 pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 8);
931 pDevice->NodeAddress[1] = (LM_UINT8) Value32;
933 Value32 = MEM_RD_OFFSET(pDevice, T3_MAC_ADDR_LOW_MAILBOX);
935 pDevice->NodeAddress[2] = (LM_UINT8) (Value32 >> 24);
936 pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 16);
937 pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 8);
938 pDevice->NodeAddress[5] = (LM_UINT8) Value32;
940 Status = LM_STATUS_SUCCESS;
944 Status = LM_NvramRead(pDevice, 0x7c, &Value32);
945 if(Status == LM_STATUS_SUCCESS)
947 pDevice->NodeAddress[0] = (LM_UINT8) (Value32 >> 16);
948 pDevice->NodeAddress[1] = (LM_UINT8) (Value32 >> 24);
950 Status = LM_NvramRead(pDevice, 0x80, &Value32);
952 pDevice->NodeAddress[2] = (LM_UINT8) Value32;
953 pDevice->NodeAddress[3] = (LM_UINT8) (Value32 >> 8);
954 pDevice->NodeAddress[4] = (LM_UINT8) (Value32 >> 16);
955 pDevice->NodeAddress[5] = (LM_UINT8) (Value32 >> 24);
959 /* Assign a default address. */
960 if(Status != LM_STATUS_SUCCESS)
963 printk(KERN_ERR "Cannot get MAC addr from NVRAM. Using default.\n");
965 pDevice->NodeAddress[0] = 0x00; pDevice->NodeAddress[1] = 0x10;
966 pDevice->NodeAddress[2] = 0x18; pDevice->NodeAddress[3] = 0x68;
967 pDevice->NodeAddress[4] = 0x61; pDevice->NodeAddress[5] = 0x76;
970 pDevice->PermanentNodeAddress[0] = pDevice->NodeAddress[0];
971 pDevice->PermanentNodeAddress[1] = pDevice->NodeAddress[1];
972 pDevice->PermanentNodeAddress[2] = pDevice->NodeAddress[2];
973 pDevice->PermanentNodeAddress[3] = pDevice->NodeAddress[3];
974 pDevice->PermanentNodeAddress[4] = pDevice->NodeAddress[4];
975 pDevice->PermanentNodeAddress[5] = pDevice->NodeAddress[5];
977 /* Initialize the default values. */
978 pDevice->NoTxPseudoHdrChksum = FALSE;
979 pDevice->NoRxPseudoHdrChksum = FALSE;
980 pDevice->NicSendBd = FALSE;
981 pDevice->TxPacketDescCnt = DEFAULT_TX_PACKET_DESC_COUNT;
982 pDevice->RxStdDescCnt = DEFAULT_STD_RCV_DESC_COUNT;
983 pDevice->RxCoalescingTicks = DEFAULT_RX_COALESCING_TICKS;
984 pDevice->TxCoalescingTicks = DEFAULT_TX_COALESCING_TICKS;
985 pDevice->RxMaxCoalescedFrames = DEFAULT_RX_MAX_COALESCED_FRAMES;
986 pDevice->TxMaxCoalescedFrames = DEFAULT_TX_MAX_COALESCED_FRAMES;
987 pDevice->RxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
988 pDevice->TxCoalescingTicksDuringInt = BAD_DEFAULT_VALUE;
989 pDevice->RxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
990 pDevice->TxMaxCoalescedFramesDuringInt = BAD_DEFAULT_VALUE;
991 pDevice->StatsCoalescingTicks = DEFAULT_STATS_COALESCING_TICKS;
992 pDevice->EnableMWI = FALSE;
993 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
994 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
995 pDevice->DisableAutoNeg = FALSE;
996 pDevice->PhyIntMode = T3_PHY_INT_MODE_AUTO;
997 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_AUTO;
998 pDevice->LedMode = LED_MODE_AUTO;
999 pDevice->ResetPhyOnInit = TRUE;
1000 pDevice->DelayPciGrant = TRUE;
1001 pDevice->UseTaggedStatus = FALSE;
1002 pDevice->OneDmaAtOnce = BAD_DEFAULT_VALUE;
1004 pDevice->DmaMbufLowMark = T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO;
1005 pDevice->RxMacMbufLowMark = T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO;
1006 pDevice->MbufHighMark = T3_DEF_MBUF_HIGH_WMARK_JUMBO;
1008 pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_AUTO;
1009 pDevice->TaskOffloadCap = LM_TASK_OFFLOAD_NONE;
1010 pDevice->FlowControlCap = LM_FLOW_CONTROL_AUTO_PAUSE;
1011 pDevice->EnableTbi = FALSE;
1012 #if INCLUDE_TBI_SUPPORT
1013 pDevice->PollTbiLink = BAD_DEFAULT_VALUE;
1016 switch (T3_ASIC_REV(pDevice->ChipRevId))
1018 case T3_ASIC_REV_5704:
1019 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1020 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE64;
1023 pDevice->MbufBase = T3_NIC_MBUF_POOL_ADDR;
1024 pDevice->MbufSize = T3_NIC_MBUF_POOL_SIZE96;
1028 pDevice->LinkStatus = LM_STATUS_LINK_DOWN;
1029 pDevice->QueueRxPackets = TRUE;
1031 pDevice->EnableWireSpeed = TRUE;
1033 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1034 pDevice->RxJumboDescCnt = DEFAULT_JUMBO_RCV_DESC_COUNT;
1035 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1037 /* Make this is a known adapter. */
1038 pAdapterInfo = LM_GetAdapterInfoBySsid(pDevice->SubsystemVendorId,
1039 pDevice->SubsystemId);
1041 pDevice->BondId = REG_RD(pDevice, Grc.MiscCfg) & GRC_MISC_BD_ID_MASK;
1042 if (pDevice->BondId != GRC_MISC_BD_ID_5700 &&
1043 pDevice->BondId != GRC_MISC_BD_ID_5701 &&
1044 pDevice->BondId != GRC_MISC_BD_ID_5702FE &&
1045 pDevice->BondId != GRC_MISC_BD_ID_5703 &&
1046 pDevice->BondId != GRC_MISC_BD_ID_5703S &&
1047 pDevice->BondId != GRC_MISC_BD_ID_5704 &&
1048 pDevice->BondId != GRC_MISC_BD_ID_5704CIOBE)
1050 return LM_STATUS_UNKNOWN_ADAPTER;
1053 pDevice->SplitModeEnable = SPLIT_MODE_DISABLE;
1054 if ((pDevice->ChipRevId == T3_CHIP_ID_5704_A0) &&
1055 (pDevice->BondId == GRC_MISC_BD_ID_5704CIOBE))
1057 pDevice->SplitModeEnable = SPLIT_MODE_ENABLE;
1058 pDevice->SplitModeMaxReq = SPLIT_MODE_5704_MAX_REQ;
1061 /* Get Eeprom info. */
1062 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_SIG_ADDR);
1063 if (Value32 == T3_NIC_DATA_SIG)
1066 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_NIC_CFG_ADDR);
1068 /* Determine PHY type. */
1069 switch (Value32 & T3_NIC_CFG_PHY_TYPE_MASK)
1071 case T3_NIC_CFG_PHY_TYPE_COPPER:
1072 EePhyTypeSerdes = FALSE;
1075 case T3_NIC_CFG_PHY_TYPE_FIBER:
1076 EePhyTypeSerdes = TRUE;
1080 EePhyTypeSerdes = FALSE;
1084 /* Determine PHY led mode. */
1085 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1086 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1088 switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
1090 case T3_NIC_CFG_LED_MODE_TRIPLE_SPEED:
1091 EePhyLedMode = LED_MODE_THREE_LINK;
1094 case T3_NIC_CFG_LED_MODE_LINK_SPEED:
1095 EePhyLedMode = LED_MODE_LINK10;
1099 EePhyLedMode = LED_MODE_AUTO;
1105 switch(Value32 & T3_NIC_CFG_LED_MODE_MASK)
1107 case T3_NIC_CFG_LED_MODE_OPEN_DRAIN:
1108 EePhyLedMode = LED_MODE_OPEN_DRAIN;
1111 case T3_NIC_CFG_LED_MODE_OUTPUT:
1112 EePhyLedMode = LED_MODE_OUTPUT;
1116 EePhyLedMode = LED_MODE_AUTO;
1120 if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1121 pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
1123 /* Enable EEPROM write protection. */
1124 if(Value32 & T3_NIC_EEPROM_WP)
1126 pDevice->EepromWp = TRUE;
1130 /* Get the PHY Id. */
1131 Value32 = MEM_RD_OFFSET(pDevice, T3_NIC_DATA_PHY_ID_ADDR);
1134 EePhyId = (((Value32 & T3_NIC_PHY_ID1_MASK) >> 16) &
1135 PHY_ID1_OUI_MASK) << 10;
1137 Value32 = Value32 & T3_NIC_PHY_ID2_MASK;
1139 EePhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1140 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1152 /* Set the PHY address. */
1153 pDevice->PhyAddr = PHY_DEVICE_ID;
1155 /* Disable auto polling. */
1156 pDevice->MiMode = 0xc0000;
1157 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
1160 /* Get the PHY id. */
1161 LM_ReadPhy(pDevice, PHY_ID1_REG, &Value32);
1162 pDevice->PhyId = (Value32 & PHY_ID1_OUI_MASK) << 10;
1164 LM_ReadPhy(pDevice, PHY_ID2_REG, &Value32);
1165 pDevice->PhyId |= ((Value32 & PHY_ID2_OUI_MASK) << 16) |
1166 (Value32 & PHY_ID2_MODEL_MASK) | (Value32 & PHY_ID2_REV_MASK);
1168 /* Set the EnableTbi flag to false if we have a copper PHY. */
1169 switch(pDevice->PhyId & PHY_ID_MASK)
1171 case PHY_BCM5400_PHY_ID:
1172 pDevice->EnableTbi = FALSE;
1175 case PHY_BCM5401_PHY_ID:
1176 pDevice->EnableTbi = FALSE;
1179 case PHY_BCM5411_PHY_ID:
1180 pDevice->EnableTbi = FALSE;
1183 case PHY_BCM5701_PHY_ID:
1184 pDevice->EnableTbi = FALSE;
1187 case PHY_BCM5703_PHY_ID:
1188 pDevice->EnableTbi = FALSE;
1191 case PHY_BCM5704_PHY_ID:
1192 pDevice->EnableTbi = FALSE;
1195 case PHY_BCM8002_PHY_ID:
1196 pDevice->EnableTbi = TRUE;
1203 pDevice->PhyId = pAdapterInfo->PhyId;
1204 pDevice->EnableTbi = pAdapterInfo->Serdes;
1206 else if (EeSigFound)
1208 pDevice->PhyId = EePhyId;
1209 pDevice->EnableTbi = EePhyTypeSerdes;
1214 /* Bail out if we don't know the copper PHY id. */
1215 if(UNKNOWN_PHY_ID(pDevice->PhyId) && !pDevice->EnableTbi)
1217 return LM_STATUS_FAILURE;
1220 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1222 if((pDevice->SavedCacheLineReg & 0xff00) < 0x4000)
1224 pDevice->SavedCacheLineReg &= 0xffff00ff;
1225 pDevice->SavedCacheLineReg |= 0x4000;
1228 /* Change driver parameters. */
1229 Status = MM_GetConfig(pDevice);
1230 if(Status != LM_STATUS_SUCCESS)
1235 #if INCLUDE_5701_AX_FIX
1236 if (pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1237 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1239 pDevice->ResetPhyOnInit = TRUE;
1243 /* Save the current phy link status. */
1244 if(!pDevice->EnableTbi)
1246 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1247 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
1249 /* If we don't have link reset the PHY. */
1250 if(!(Value32 & PHY_STATUS_LINK_PASS) || pDevice->ResetPhyOnInit)
1253 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
1255 for(j = 0; j < 100; j++)
1259 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
1260 if(Value32 && !(Value32 & PHY_CTRL_PHY_RESET))
1268 #if INCLUDE_5701_AX_FIX
1269 /* 5701_AX_BX bug: only advertises 10mb speed. */
1270 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1271 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
1274 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
1275 PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
1276 PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
1277 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
1278 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
1279 pDevice->advertising = Value32;
1281 Value32 = BCM540X_AN_AD_1000BASET_HALF |
1282 BCM540X_AN_AD_1000BASET_FULL | BCM540X_CONFIG_AS_MASTER |
1283 BCM540X_ENABLE_CONFIG_AS_MASTER;
1284 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
1285 pDevice->advertising1000 = Value32;
1287 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
1288 PHY_CTRL_RESTART_AUTO_NEG);
1291 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1293 LM_WritePhy(pDevice, 0x18, 0x0c00);
1294 LM_WritePhy(pDevice, 0x17, 0x201f);
1295 LM_WritePhy(pDevice, 0x15, 0x2aaa);
1297 if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
1299 LM_WritePhy(pDevice, 0x1c, 0x8d68);
1300 LM_WritePhy(pDevice, 0x1c, 0x8d68);
1302 /* Enable Ethernet@WireSpeed. */
1303 if(pDevice->EnableWireSpeed)
1305 LM_WritePhy(pDevice, 0x18, 0x7007);
1306 LM_ReadPhy(pDevice, 0x18, &Value32);
1307 LM_WritePhy(pDevice, 0x18, Value32 | BIT_15 | BIT_4);
1312 /* Turn off tap power management. */
1313 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
1315 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
1316 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
1317 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
1318 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
1319 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
1320 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1321 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
1322 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
1323 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
1324 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
1325 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
1330 #if INCLUDE_TBI_SUPPORT
1331 pDevice->IgnoreTbiLinkChange = FALSE;
1333 if(pDevice->EnableTbi)
1335 pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_NONE;
1336 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1337 if ((pDevice->PollTbiLink == BAD_DEFAULT_VALUE) ||
1338 pDevice->DisableAutoNeg)
1340 pDevice->PollTbiLink = FALSE;
1345 pDevice->PollTbiLink = FALSE;
1347 #endif /* INCLUDE_TBI_SUPPORT */
1349 /* UseTaggedStatus is only valid for 5701 and later. */
1350 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1352 pDevice->UseTaggedStatus = FALSE;
1354 pDevice->CoalesceMode = 0;
1358 pDevice->CoalesceMode = HOST_COALESCE_CLEAR_TICKS_ON_RX_BD_EVENT |
1359 HOST_COALESCE_CLEAR_TICKS_ON_TX_BD_EVENT;
1362 /* Set the status block size. */
1363 if(T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_AX &&
1364 T3_CHIP_REV(pDevice->ChipRevId) != T3_CHIP_REV_5700_BX)
1366 pDevice->CoalesceMode |= HOST_COALESCE_32_BYTE_STATUS_MODE;
1369 /* Check the DURING_INT coalescing ticks parameters. */
1370 if(pDevice->UseTaggedStatus)
1372 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1374 pDevice->RxCoalescingTicksDuringInt =
1375 DEFAULT_RX_COALESCING_TICKS_DURING_INT;
1378 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1380 pDevice->TxCoalescingTicksDuringInt =
1381 DEFAULT_TX_COALESCING_TICKS_DURING_INT;
1384 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1386 pDevice->RxMaxCoalescedFramesDuringInt =
1387 DEFAULT_RX_MAX_COALESCED_FRAMES_DURING_INT;
1390 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1392 pDevice->TxMaxCoalescedFramesDuringInt =
1393 DEFAULT_TX_MAX_COALESCED_FRAMES_DURING_INT;
1398 if(pDevice->RxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1400 pDevice->RxCoalescingTicksDuringInt = 0;
1403 if(pDevice->TxCoalescingTicksDuringInt == BAD_DEFAULT_VALUE)
1405 pDevice->TxCoalescingTicksDuringInt = 0;
1408 if(pDevice->RxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1410 pDevice->RxMaxCoalescedFramesDuringInt = 0;
1413 if(pDevice->TxMaxCoalescedFramesDuringInt == BAD_DEFAULT_VALUE)
1415 pDevice->TxMaxCoalescedFramesDuringInt = 0;
1419 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1420 if(pDevice->RxMtu <= (MAX_STD_RCV_BUFFER_SIZE - 8 /* CRC */))
1422 pDevice->RxJumboDescCnt = 0;
1423 if(pDevice->RxMtu <= MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1425 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1430 pDevice->RxJumboBufferSize = (pDevice->RxMtu + 8 /* CRC + VLAN */ +
1431 COMMON_CACHE_LINE_SIZE-1) & ~COMMON_CACHE_LINE_MASK;
1433 if(pDevice->RxJumboBufferSize > MAX_JUMBO_RCV_BUFFER_SIZE)
1435 pDevice->RxJumboBufferSize = DEFAULT_JUMBO_RCV_BUFFER_SIZE;
1436 pDevice->RxMtu = pDevice->RxJumboBufferSize - 8 /* CRC + VLAN */;
1438 pDevice->TxMtu = pDevice->RxMtu;
1442 pDevice->RxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1443 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1445 pDevice->RxPacketDescCnt =
1446 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1447 pDevice->RxJumboDescCnt +
1448 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1449 pDevice->RxStdDescCnt;
1451 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_SIZE_NO_CRC)
1453 pDevice->TxMtu = MAX_ETHERNET_PACKET_SIZE_NO_CRC;
1456 if(pDevice->TxMtu > MAX_JUMBO_TX_BUFFER_SIZE)
1458 pDevice->TxMtu = MAX_JUMBO_TX_BUFFER_SIZE;
1461 /* Configure the proper ways to get link change interrupt. */
1462 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO)
1464 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1466 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1470 pDevice->PhyIntMode = T3_PHY_INT_MODE_LINK_READY;
1473 else if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
1475 /* Auto-polling does not work on 5700_AX and 5700_BX. */
1476 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1478 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1482 /* Determine the method to get link change status. */
1483 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_AUTO)
1485 /* The link status bit in the status block does not work on 5700_AX */
1486 /* and 5700_BX chips. */
1487 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1489 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1493 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_BLOCK;
1497 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT ||
1498 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
1500 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1503 /* Configure PHY led mode. */
1504 if(pDevice->LedMode == LED_MODE_AUTO)
1506 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1507 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
1509 if(pDevice->SubsystemVendorId == T3_SVID_DELL)
1511 pDevice->LedMode = LED_MODE_LINK10;
1515 pDevice->LedMode = LED_MODE_THREE_LINK;
1517 if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
1519 pDevice->LedMode = EePhyLedMode;
1523 /* bug? 5701 in LINK10 mode does not seem to work when */
1524 /* PhyIntMode is LINK_READY. */
1525 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
1526 #if INCLUDE_TBI_SUPPORT
1527 pDevice->EnableTbi == FALSE &&
1529 pDevice->LedMode == LED_MODE_LINK10)
1531 pDevice->PhyIntMode = T3_PHY_INT_MODE_MI_INTERRUPT;
1532 pDevice->LinkChngMode = T3_LINK_CHNG_MODE_USE_STATUS_REG;
1535 if(pDevice->EnableTbi)
1537 pDevice->LedMode = LED_MODE_THREE_LINK;
1542 if(EeSigFound && EePhyLedMode != LED_MODE_AUTO)
1544 pDevice->LedMode = EePhyLedMode;
1548 pDevice->LedMode = LED_MODE_OPEN_DRAIN;
1553 /* Enable OneDmaAtOnce. */
1554 if(pDevice->OneDmaAtOnce == BAD_DEFAULT_VALUE)
1556 pDevice->OneDmaAtOnce = FALSE;
1559 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
1560 pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
1561 pDevice->ChipRevId == T3_CHIP_ID_5701_B0 ||
1562 pDevice->ChipRevId == T3_CHIP_ID_5701_B2)
1564 pDevice->WolSpeed = WOL_SPEED_10MB;
1568 pDevice->WolSpeed = WOL_SPEED_100MB;
1572 pDevice->TaskToOffload = LM_TASK_OFFLOAD_NONE;
1574 /* Turn off task offloading on Ax. */
1575 if(pDevice->ChipRevId == T3_CHIP_ID_5700_B0)
1577 pDevice->TaskOffloadCap &= ~(LM_TASK_OFFLOAD_TX_TCP_CHECKSUM |
1578 LM_TASK_OFFLOAD_TX_UDP_CHECKSUM);
1580 pDevice->PciState = REG_RD(pDevice, PciCfg.PciState);
1581 LM_ReadVPD(pDevice);
1582 LM_ReadBootCodeVersion(pDevice);
1583 LM_GetBusSpeed(pDevice);
1585 return LM_STATUS_SUCCESS;
1586 } /* LM_GetAdapterInfo */
1588 STATIC PLM_ADAPTER_INFO
1589 LM_GetAdapterInfoBySsid(
1593 static LM_ADAPTER_INFO AdapterArr[] =
1595 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A6, PHY_BCM5401_PHY_ID, 0},
1596 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A5, PHY_BCM5701_PHY_ID, 0},
1597 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700T6, PHY_BCM8002_PHY_ID, 1},
1598 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95700A9, 0, 1 },
1599 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T1, PHY_BCM5701_PHY_ID, 0},
1600 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701T8, PHY_BCM5701_PHY_ID, 0},
1601 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A7, 0, 1},
1602 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A10, PHY_BCM5701_PHY_ID, 0},
1603 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95701A12, PHY_BCM5701_PHY_ID, 0},
1604 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax1, PHY_BCM5701_PHY_ID, 0},
1605 { T3_SVID_BROADCOM, T3_SSID_BROADCOM_BCM95703Ax2, PHY_BCM5701_PHY_ID, 0},
1607 { T3_SVID_3COM, T3_SSID_3COM_3C996T, PHY_BCM5401_PHY_ID, 0 },
1608 { T3_SVID_3COM, T3_SSID_3COM_3C996BT, PHY_BCM5701_PHY_ID, 0 },
1609 { T3_SVID_3COM, T3_SSID_3COM_3C996SX, 0, 1 },
1610 { T3_SVID_3COM, T3_SSID_3COM_3C1000T, PHY_BCM5701_PHY_ID, 0 },
1611 { T3_SVID_3COM, T3_SSID_3COM_3C940BR01, PHY_BCM5701_PHY_ID, 0 },
1613 { T3_SVID_DELL, T3_SSID_DELL_VIPER, PHY_BCM5401_PHY_ID, 0 },
1614 { T3_SVID_DELL, T3_SSID_DELL_JAGUAR, PHY_BCM5401_PHY_ID, 0 },
1615 { T3_SVID_DELL, T3_SSID_DELL_MERLOT, PHY_BCM5411_PHY_ID, 0 },
1616 { T3_SVID_DELL, T3_SSID_DELL_SLIM_MERLOT, PHY_BCM5411_PHY_ID, 0 },
1618 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE, PHY_BCM5701_PHY_ID, 0 },
1619 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_BANSHEE_2, PHY_BCM5701_PHY_ID, 0 },
1620 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_CHANGELING, 0, 1 },
1621 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780, PHY_BCM5701_PHY_ID, 0 },
1622 { T3_SVID_COMPAQ, T3_SSID_COMPAQ_NC7780_2, PHY_BCM5701_PHY_ID, 0 },
1627 for(j = 0; j < sizeof(AdapterArr)/sizeof(LM_ADAPTER_INFO); j++)
1629 if(AdapterArr[j].Svid == Svid && AdapterArr[j].Ssid == Ssid)
1631 return &AdapterArr[j];
1639 /******************************************************************************/
1641 /* This routine sets up receive/transmit buffer descriptions queues. */
1644 /* LM_STATUS_SUCCESS */
1645 /******************************************************************************/
1647 LM_InitializeAdapter(
1648 PLM_DEVICE_BLOCK pDevice)
1650 LM_PHYSICAL_ADDRESS MemPhy;
1657 /* Set power state to D0. */
1658 LM_SetPowerState(pDevice, LM_POWER_STATE_D0);
1660 /* Intialize the queues. */
1661 QQ_InitQueue(&pDevice->RxPacketReceivedQ.Container,
1662 MAX_RX_PACKET_DESC_COUNT);
1663 QQ_InitQueue(&pDevice->RxPacketFreeQ.Container,
1664 MAX_RX_PACKET_DESC_COUNT);
1666 QQ_InitQueue(&pDevice->TxPacketFreeQ.Container,MAX_TX_PACKET_DESC_COUNT);
1667 QQ_InitQueue(&pDevice->TxPacketActiveQ.Container,MAX_TX_PACKET_DESC_COUNT);
1668 QQ_InitQueue(&pDevice->TxPacketXmittedQ.Container,MAX_TX_PACKET_DESC_COUNT);
1670 /* Allocate shared memory for: status block, the buffers for receive */
1671 /* rings -- standard, mini, jumbo, and return rings. */
1672 Size = T3_STATUS_BLOCK_SIZE + sizeof(T3_STATS_BLOCK) +
1673 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
1674 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1675 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD) +
1676 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1677 T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1679 /* Memory for host based Send BD. */
1680 if(pDevice->NicSendBd == FALSE)
1682 Size += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1685 /* Allocate the memory block. */
1686 Status = MM_AllocateSharedMemory(pDevice, Size, (PLM_VOID) &pMemVirt, &MemPhy, FALSE);
1687 if(Status != LM_STATUS_SUCCESS)
1692 /* Program DMA Read/Write */
1693 if (pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS)
1695 pDevice->DmaReadWriteCtrl = 0x763f000f;
1699 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704)
1701 pDevice->DmaReadWriteCtrl = 0x761f0000;
1705 pDevice->DmaReadWriteCtrl = 0x761b000f;
1707 if(pDevice->ChipRevId == T3_CHIP_ID_5703_A1 ||
1708 pDevice->ChipRevId == T3_CHIP_ID_5703_A2)
1710 pDevice->OneDmaAtOnce = TRUE;
1713 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703)
1715 pDevice->DmaReadWriteCtrl &= 0xfffffff0;
1718 if(pDevice->OneDmaAtOnce)
1720 pDevice->DmaReadWriteCtrl |= DMA_CTRL_WRITE_ONE_DMA_AT_ONCE;
1722 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
1724 if (LM_DmaTest(pDevice, pMemVirt, MemPhy, 0x400) != LM_STATUS_SUCCESS)
1726 return LM_STATUS_FAILURE;
1730 pDevice->pStatusBlkVirt = (PT3_STATUS_BLOCK) pMemVirt;
1731 pDevice->StatusBlkPhy = MemPhy;
1732 pMemVirt += T3_STATUS_BLOCK_SIZE;
1733 LM_INC_PHYSICAL_ADDRESS(&MemPhy, T3_STATUS_BLOCK_SIZE);
1735 /* Statistics block. */
1736 pDevice->pStatsBlkVirt = (PT3_STATS_BLOCK) pMemVirt;
1737 pDevice->StatsBlkPhy = MemPhy;
1738 pMemVirt += sizeof(T3_STATS_BLOCK);
1739 LM_INC_PHYSICAL_ADDRESS(&MemPhy, sizeof(T3_STATS_BLOCK));
1741 /* Receive standard BD buffer. */
1742 pDevice->pRxStdBdVirt = (PT3_RCV_BD) pMemVirt;
1743 pDevice->RxStdBdPhy = MemPhy;
1745 pMemVirt += T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1746 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1747 T3_STD_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1749 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1750 /* Receive jumbo BD buffer. */
1751 pDevice->pRxJumboBdVirt = (PT3_RCV_BD) pMemVirt;
1752 pDevice->RxJumboBdPhy = MemPhy;
1754 pMemVirt += T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1755 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1756 T3_JUMBO_RCV_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1757 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1759 /* Receive return BD buffer. */
1760 pDevice->pRcvRetBdVirt = (PT3_RCV_BD) pMemVirt;
1761 pDevice->RcvRetBdPhy = MemPhy;
1763 pMemVirt += T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD);
1764 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1765 T3_RCV_RETURN_RCB_ENTRY_COUNT * sizeof(T3_RCV_BD));
1767 /* Set up Send BD. */
1768 if(pDevice->NicSendBd == FALSE)
1770 pDevice->pSendBdVirt = (PT3_SND_BD) pMemVirt;
1771 pDevice->SendBdPhy = MemPhy;
1773 pMemVirt += sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT;
1774 LM_INC_PHYSICAL_ADDRESS(&MemPhy,
1775 sizeof(T3_SND_BD) * T3_SEND_RCB_ENTRY_COUNT);
1779 pDevice->pSendBdVirt = (PT3_SND_BD)
1780 pDevice->pMemView->uIntMem.First32k.BufferDesc;
1781 pDevice->SendBdPhy.High = 0;
1782 pDevice->SendBdPhy.Low = T3_NIC_SND_BUFFER_DESC_ADDR;
1785 /* Allocate memory for packet descriptors. */
1786 Size = (pDevice->RxPacketDescCnt +
1787 pDevice->TxPacketDescCnt) * MM_PACKET_DESC_SIZE;
1788 Status = MM_AllocateMemory(pDevice, Size, (PLM_VOID *) &pPacket);
1789 if(Status != LM_STATUS_SUCCESS)
1793 pDevice->pPacketDescBase = (PLM_VOID) pPacket;
1795 /* Create transmit packet descriptors from the memory block and add them */
1796 /* to the TxPacketFreeQ for each send ring. */
1797 for(j = 0; j < pDevice->TxPacketDescCnt; j++)
1802 /* Queue the descriptor in the TxPacketFreeQ of the 'k' ring. */
1803 QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket);
1805 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
1806 /* is the total size of the packet descriptor including the */
1807 /* os-specific extensions in the UM_PACKET structure. */
1808 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1811 /* Create receive packet descriptors from the memory block and add them */
1812 /* to the RxPacketFreeQ. Create the Standard packet descriptors. */
1813 for(j = 0; j < pDevice->RxStdDescCnt; j++)
1815 /* Receive producer ring. */
1816 pPacket->u.Rx.RcvProdRing = T3_STD_RCV_PROD_RING;
1818 /* Receive buffer size. */
1819 pPacket->u.Rx.RxBufferSize = MAX_STD_RCV_BUFFER_SIZE;
1821 /* Add the descriptor to RxPacketFreeQ. */
1822 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
1824 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
1825 /* is the total size of the packet descriptor including the */
1826 /* os-specific extensions in the UM_PACKET structure. */
1827 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1830 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
1831 /* Create the Jumbo packet descriptors. */
1832 for(j = 0; j < pDevice->RxJumboDescCnt; j++)
1834 /* Receive producer ring. */
1835 pPacket->u.Rx.RcvProdRing = T3_JUMBO_RCV_PROD_RING;
1837 /* Receive buffer size. */
1838 pPacket->u.Rx.RxBufferSize = pDevice->RxJumboBufferSize;
1840 /* Add the descriptor to RxPacketFreeQ. */
1841 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
1843 /* Get the pointer to the next descriptor. MM_PACKET_DESC_SIZE */
1844 /* is the total size of the packet descriptor including the */
1845 /* os-specific extensions in the UM_PACKET structure. */
1846 pPacket = (PLM_PACKET) ((PLM_UINT8) pPacket + MM_PACKET_DESC_SIZE);
1848 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
1850 /* Initialize the rest of the packet descriptors. */
1851 Status = MM_InitializeUmPackets(pDevice);
1852 if(Status != LM_STATUS_SUCCESS)
1857 /* Default receive mask. */
1858 pDevice->ReceiveMask = LM_ACCEPT_MULTICAST | LM_ACCEPT_BROADCAST |
1861 /* Make sure we are in the first 32k memory window or NicSendBd. */
1862 REG_WR(pDevice, PciCfg.MemWindowBaseAddr, 0);
1864 /* Initialize the hardware. */
1865 Status = LM_ResetAdapter(pDevice);
1866 if(Status != LM_STATUS_SUCCESS)
1871 /* We are done with initialization. */
1872 pDevice->InitDone = TRUE;
1874 return LM_STATUS_SUCCESS;
1875 } /* LM_InitializeAdapter */
1879 /******************************************************************************/
1881 /* This function Enables/Disables a given block. */
1884 /* LM_STATUS_SUCCESS */
1885 /******************************************************************************/
1888 PLM_DEVICE_BLOCK pDevice,
1889 LM_UINT32 mask,LM_UINT32 cntrl)
1892 LM_UINT32 MaxWaitCnt;
1897 for(i = 0 ; i < 32; i++)
1899 if(!(mask & (1 << i)))
1904 case T3_BLOCK_DMA_RD:
1905 data = REG_RD(pDevice, DmaRead.Mode);
1906 if (cntrl == LM_DISABLE)
1908 data &= ~DMA_READ_MODE_ENABLE;
1909 REG_WR(pDevice, DmaRead.Mode, data);
1910 for(j = 0; j < MaxWaitCnt; j++)
1912 if(!(REG_RD(pDevice, DmaRead.Mode) & DMA_READ_MODE_ENABLE))
1918 REG_WR(pDevice, DmaRead.Mode, data | DMA_READ_MODE_ENABLE);
1921 case T3_BLOCK_DMA_COMP:
1922 data = REG_RD(pDevice,DmaComp.Mode);
1923 if (cntrl == LM_DISABLE)
1925 data &= ~DMA_COMP_MODE_ENABLE;
1926 REG_WR(pDevice, DmaComp.Mode, data);
1927 for(j = 0; j < MaxWaitCnt; j++)
1929 if(!(REG_RD(pDevice, DmaComp.Mode) & DMA_COMP_MODE_ENABLE))
1935 REG_WR(pDevice, DmaComp.Mode, data | DMA_COMP_MODE_ENABLE);
1938 case T3_BLOCK_RX_BD_INITIATOR:
1939 data = REG_RD(pDevice, RcvBdIn.Mode);
1940 if (cntrl == LM_DISABLE)
1942 data &= ~RCV_BD_IN_MODE_ENABLE;
1943 REG_WR(pDevice, RcvBdIn.Mode,data);
1944 for(j = 0; j < MaxWaitCnt; j++)
1946 if(!(REG_RD(pDevice, RcvBdIn.Mode) & RCV_BD_IN_MODE_ENABLE))
1952 REG_WR(pDevice, RcvBdIn.Mode,data | RCV_BD_IN_MODE_ENABLE);
1955 case T3_BLOCK_RX_BD_COMP:
1956 data = REG_RD(pDevice, RcvBdComp.Mode);
1957 if (cntrl == LM_DISABLE)
1959 data &= ~RCV_BD_COMP_MODE_ENABLE;
1960 REG_WR(pDevice, RcvBdComp.Mode,data);
1961 for(j = 0; j < MaxWaitCnt; j++)
1963 if(!(REG_RD(pDevice, RcvBdComp.Mode) & RCV_BD_COMP_MODE_ENABLE))
1969 REG_WR(pDevice, RcvBdComp.Mode,data | RCV_BD_COMP_MODE_ENABLE);
1972 case T3_BLOCK_DMA_WR:
1973 data = REG_RD(pDevice, DmaWrite.Mode);
1974 if (cntrl == LM_DISABLE)
1976 data &= ~DMA_WRITE_MODE_ENABLE;
1977 REG_WR(pDevice, DmaWrite.Mode,data);
1979 for(j = 0; j < MaxWaitCnt; j++)
1981 if(!(REG_RD(pDevice, DmaWrite.Mode) & DMA_WRITE_MODE_ENABLE))
1987 REG_WR(pDevice, DmaWrite.Mode,data | DMA_WRITE_MODE_ENABLE);
1990 case T3_BLOCK_MSI_HANDLER:
1991 data = REG_RD(pDevice, Msi.Mode);
1992 if (cntrl == LM_DISABLE)
1994 data &= ~MSI_MODE_ENABLE;
1995 REG_WR(pDevice, Msi.Mode, data);
1996 for(j = 0; j < MaxWaitCnt; j++)
1998 if(!(REG_RD(pDevice, Msi.Mode) & MSI_MODE_ENABLE))
2004 REG_WR(pDevice, Msi.Mode, data |MSI_MODE_ENABLE);
2007 case T3_BLOCK_RX_LIST_PLMT:
2008 data = REG_RD(pDevice, RcvListPlmt.Mode);
2009 if (cntrl == LM_DISABLE)
2011 data &= ~RCV_LIST_PLMT_MODE_ENABLE;
2012 REG_WR(pDevice, RcvListPlmt.Mode,data);
2013 for(j = 0; j < MaxWaitCnt; j++)
2015 if(!(REG_RD(pDevice, RcvListPlmt.Mode) & RCV_LIST_PLMT_MODE_ENABLE))
2021 REG_WR(pDevice, RcvListPlmt.Mode,data | RCV_LIST_PLMT_MODE_ENABLE);
2024 case T3_BLOCK_RX_LIST_SELECTOR:
2025 data = REG_RD(pDevice, RcvListSel.Mode);
2026 if (cntrl == LM_DISABLE)
2028 data &= ~RCV_LIST_SEL_MODE_ENABLE;
2029 REG_WR(pDevice, RcvListSel.Mode,data);
2030 for(j = 0; j < MaxWaitCnt; j++)
2032 if(!(REG_RD(pDevice, RcvListSel.Mode) & RCV_LIST_SEL_MODE_ENABLE))
2038 REG_WR(pDevice, RcvListSel.Mode,data |RCV_LIST_SEL_MODE_ENABLE);
2041 case T3_BLOCK_RX_DATA_INITIATOR:
2042 data = REG_RD(pDevice, RcvDataBdIn.Mode);
2043 if (cntrl == LM_DISABLE)
2045 data &= ~RCV_DATA_BD_IN_MODE_ENABLE;
2046 REG_WR(pDevice, RcvDataBdIn.Mode,data);
2047 for(j = 0; j < MaxWaitCnt; j++)
2049 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_BD_IN_MODE_ENABLE))
2055 REG_WR(pDevice, RcvDataBdIn.Mode, data | RCV_DATA_BD_IN_MODE_ENABLE);
2058 case T3_BLOCK_RX_DATA_COMP:
2059 data = REG_RD(pDevice, RcvDataComp.Mode);
2060 if (cntrl == LM_DISABLE)
2062 data &= ~RCV_DATA_COMP_MODE_ENABLE;
2063 REG_WR(pDevice, RcvDataComp.Mode,data);
2064 for(j = 0; j < MaxWaitCnt; j++)
2066 if(!(REG_RD(pDevice, RcvDataBdIn.Mode) & RCV_DATA_COMP_MODE_ENABLE))
2072 REG_WR(pDevice, RcvDataComp.Mode,data | RCV_DATA_COMP_MODE_ENABLE);
2075 case T3_BLOCK_HOST_COALESING:
2076 data = REG_RD(pDevice, HostCoalesce.Mode);
2077 if (cntrl == LM_DISABLE)
2079 data &= ~HOST_COALESCE_ENABLE;
2080 REG_WR(pDevice, HostCoalesce.Mode, data);
2081 for(j = 0; j < MaxWaitCnt; j++)
2083 if(!(REG_RD(pDevice, SndBdIn.Mode) & HOST_COALESCE_ENABLE))
2089 REG_WR(pDevice, HostCoalesce.Mode, data | HOST_COALESCE_ENABLE);
2092 case T3_BLOCK_MAC_RX_ENGINE:
2093 if(cntrl == LM_DISABLE)
2095 pDevice->RxMode &= ~RX_MODE_ENABLE;
2096 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2097 for(j = 0; j < MaxWaitCnt; j++)
2099 if(!(REG_RD(pDevice, MacCtrl.RxMode) & RX_MODE_ENABLE))
2108 pDevice->RxMode |= RX_MODE_ENABLE;
2109 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2113 case T3_BLOCK_MBUF_CLUSTER_FREE:
2114 data = REG_RD(pDevice, MbufClusterFree.Mode);
2115 if (cntrl == LM_DISABLE)
2117 data &= ~MBUF_CLUSTER_FREE_MODE_ENABLE;
2118 REG_WR(pDevice, MbufClusterFree.Mode,data);
2119 for(j = 0; j < MaxWaitCnt; j++)
2121 if(!(REG_RD(pDevice, MbufClusterFree.Mode) & MBUF_CLUSTER_FREE_MODE_ENABLE))
2127 REG_WR(pDevice, MbufClusterFree.Mode, data | MBUF_CLUSTER_FREE_MODE_ENABLE);
2130 case T3_BLOCK_SEND_BD_INITIATOR:
2131 data = REG_RD(pDevice, SndBdIn.Mode);
2132 if (cntrl == LM_DISABLE)
2134 data &= ~SND_BD_IN_MODE_ENABLE;
2135 REG_WR(pDevice, SndBdIn.Mode, data);
2136 for(j = 0; j < MaxWaitCnt; j++)
2138 if(!(REG_RD(pDevice, SndBdIn.Mode) & SND_BD_IN_MODE_ENABLE))
2144 REG_WR(pDevice, SndBdIn.Mode, data | SND_BD_IN_MODE_ENABLE);
2147 case T3_BLOCK_SEND_BD_COMP:
2148 data = REG_RD(pDevice, SndBdComp.Mode);
2149 if (cntrl == LM_DISABLE)
2151 data &= ~SND_BD_COMP_MODE_ENABLE;
2152 REG_WR(pDevice, SndBdComp.Mode, data);
2153 for(j = 0; j < MaxWaitCnt; j++)
2155 if(!(REG_RD(pDevice, SndBdComp.Mode) & SND_BD_COMP_MODE_ENABLE))
2161 REG_WR(pDevice, SndBdComp.Mode, data | SND_BD_COMP_MODE_ENABLE);
2164 case T3_BLOCK_SEND_BD_SELECTOR:
2165 data = REG_RD(pDevice, SndBdSel.Mode);
2166 if (cntrl == LM_DISABLE)
2168 data &= ~SND_BD_SEL_MODE_ENABLE;
2169 REG_WR(pDevice, SndBdSel.Mode, data);
2170 for(j = 0; j < MaxWaitCnt; j++)
2172 if(!(REG_RD(pDevice, SndBdSel.Mode) & SND_BD_SEL_MODE_ENABLE))
2178 REG_WR(pDevice, SndBdSel.Mode, data | SND_BD_SEL_MODE_ENABLE);
2181 case T3_BLOCK_SEND_DATA_INITIATOR:
2182 data = REG_RD(pDevice, SndDataIn.Mode);
2183 if (cntrl == LM_DISABLE)
2185 data &= ~T3_SND_DATA_IN_MODE_ENABLE;
2186 REG_WR(pDevice, SndDataIn.Mode,data);
2187 for(j = 0; j < MaxWaitCnt; j++)
2189 if(!(REG_RD(pDevice, SndDataIn.Mode) & T3_SND_DATA_IN_MODE_ENABLE))
2195 REG_WR(pDevice, SndDataIn.Mode,data | T3_SND_DATA_IN_MODE_ENABLE);
2198 case T3_BLOCK_SEND_DATA_COMP:
2199 data = REG_RD(pDevice, SndDataComp.Mode);
2200 if (cntrl == LM_DISABLE)
2202 data &= ~SND_DATA_COMP_MODE_ENABLE;
2203 REG_WR(pDevice, SndDataComp.Mode, data);
2204 for(j = 0; j < MaxWaitCnt; j++)
2206 if(!(REG_RD(pDevice, SndDataComp.Mode) & SND_DATA_COMP_MODE_ENABLE))
2212 REG_WR(pDevice, SndDataComp.Mode,data | SND_DATA_COMP_MODE_ENABLE);
2215 case T3_BLOCK_MAC_TX_ENGINE:
2216 if(cntrl == LM_DISABLE)
2218 pDevice->TxMode &= ~TX_MODE_ENABLE;
2219 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2220 for(j = 0; j < MaxWaitCnt; j++)
2222 if(!(REG_RD(pDevice, MacCtrl.TxMode) & TX_MODE_ENABLE))
2229 pDevice->TxMode |= TX_MODE_ENABLE;
2230 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2234 case T3_BLOCK_MEM_ARBITOR:
2235 data = REG_RD(pDevice, MemArbiter.Mode);
2236 if (cntrl == LM_DISABLE)
2238 data &= ~T3_MEM_ARBITER_MODE_ENABLE;
2239 REG_WR(pDevice, MemArbiter.Mode, data);
2240 for(j = 0; j < MaxWaitCnt; j++)
2242 if(!(REG_RD(pDevice, MemArbiter.Mode) & T3_MEM_ARBITER_MODE_ENABLE))
2248 REG_WR(pDevice, MemArbiter.Mode,data|T3_MEM_ARBITER_MODE_ENABLE);
2251 case T3_BLOCK_MBUF_MANAGER:
2252 data = REG_RD(pDevice, BufMgr.Mode);
2253 if (cntrl == LM_DISABLE)
2255 data &= ~BUFMGR_MODE_ENABLE;
2256 REG_WR(pDevice, BufMgr.Mode,data);
2257 for(j = 0; j < MaxWaitCnt; j++)
2259 if(!(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE))
2265 REG_WR(pDevice, BufMgr.Mode,data | BUFMGR_MODE_ENABLE);
2268 case T3_BLOCK_MAC_GLOBAL:
2269 if(cntrl == LM_DISABLE)
2271 pDevice->MacMode &= ~(MAC_MODE_ENABLE_TDE |
2272 MAC_MODE_ENABLE_RDE |
2273 MAC_MODE_ENABLE_FHDE);
2277 pDevice->MacMode |= (MAC_MODE_ENABLE_TDE |
2278 MAC_MODE_ENABLE_RDE |
2279 MAC_MODE_ENABLE_FHDE);
2281 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
2285 return LM_STATUS_FAILURE;
2290 return LM_STATUS_FAILURE;
2294 return LM_STATUS_SUCCESS;
2297 /******************************************************************************/
2299 /* This function reinitializes the adapter. */
2302 /* LM_STATUS_SUCCESS */
2303 /******************************************************************************/
2306 PLM_DEVICE_BLOCK pDevice)
2312 /* Disable interrupt. */
2313 LM_DisableInterrupt(pDevice);
2315 /* May get a spurious interrupt */
2316 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED;
2318 /* Disable transmit and receive DMA engines. Abort all pending requests. */
2319 if(pDevice->InitDone)
2324 pDevice->ShuttingDown = FALSE;
2326 LM_ResetChip(pDevice);
2328 /* Bug: Athlon fix for B3 silicon only. This bit does not do anything */
2329 /* in other chip revisions. */
2330 if(pDevice->DelayPciGrant)
2332 Value32 = REG_RD(pDevice, PciCfg.ClockCtrl);
2333 REG_WR(pDevice, PciCfg.ClockCtrl, Value32 | BIT_31);
2336 if(pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2338 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2340 Value32 = REG_RD(pDevice, PciCfg.PciState);
2341 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
2342 REG_WR(pDevice, PciCfg.PciState, Value32);
2346 /* Enable TaggedStatus mode. */
2347 if(pDevice->UseTaggedStatus)
2349 pDevice->MiscHostCtrl |= MISC_HOST_CTRL_ENABLE_TAGGED_STATUS_MODE;
2352 /* Restore PCI configuration registers. */
2353 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
2354 pDevice->SavedCacheLineReg);
2355 MM_WriteConfig32(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
2356 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
2358 /* Clear the statistics block. */
2359 for(j = 0x0300; j < 0x0b00; j++)
2361 MEM_WR_OFFSET(pDevice, j, 0);
2364 /* Initialize the statistis Block */
2365 pDevice->pStatusBlkVirt->Status = 0;
2366 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
2367 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
2368 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
2370 for(j = 0; j < 16; j++)
2372 pDevice->pStatusBlkVirt->Idx[j].RcvProdIdx = 0;
2373 pDevice->pStatusBlkVirt->Idx[j].SendConIdx = 0;
2376 for(k = 0; k < T3_STD_RCV_RCB_ENTRY_COUNT ;k++)
2378 pDevice->pRxStdBdVirt[k].HostAddr.High = 0;
2379 pDevice->pRxStdBdVirt[k].HostAddr.Low = 0;
2382 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2383 /* Receive jumbo BD buffer. */
2384 for(k = 0; k < T3_JUMBO_RCV_RCB_ENTRY_COUNT; k++)
2386 pDevice->pRxJumboBdVirt[k].HostAddr.High = 0;
2387 pDevice->pRxJumboBdVirt[k].HostAddr.Low = 0;
2391 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl, pDevice->DmaReadWriteCtrl);
2393 /* GRC mode control register. */
2394 #ifdef BIG_ENDIAN_PCI /* Jimmy, this ifdef block deleted in new code! */
2396 GRC_MODE_WORD_SWAP_DATA |
2397 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2398 GRC_MODE_INT_ON_MAC_ATTN |
2399 GRC_MODE_HOST_STACK_UP;
2401 /* No CPU Swap modes for PCI IO */
2403 #ifdef BIG_ENDIAN_HOST
2404 GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
2405 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2406 GRC_MODE_BYTE_SWAP_DATA |
2407 GRC_MODE_WORD_SWAP_DATA |
2409 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
2410 GRC_MODE_BYTE_SWAP_DATA |
2411 GRC_MODE_WORD_SWAP_DATA |
2413 GRC_MODE_INT_ON_MAC_ATTN |
2414 GRC_MODE_HOST_STACK_UP;
2415 #endif /* !BIG_ENDIAN_PCI */
2417 /* Configure send BD mode. */
2418 if(pDevice->NicSendBd == FALSE)
2420 Value32 |= GRC_MODE_HOST_SEND_BDS;
2424 Value32 |= GRC_MODE_4X_NIC_BASED_SEND_RINGS;
2427 /* Configure pseudo checksum mode. */
2428 if(pDevice->NoTxPseudoHdrChksum)
2430 Value32 |= GRC_MODE_TX_NO_PSEUDO_HEADER_CHKSUM;
2433 if(pDevice->NoRxPseudoHdrChksum)
2435 Value32 |= GRC_MODE_RX_NO_PSEUDO_HEADER_CHKSUM;
2438 REG_WR(pDevice, Grc.Mode, Value32);
2440 /* Setup the timer prescalar register. */
2441 REG_WR(pDevice, Grc.MiscCfg, 65 << 1); /* Clock is alwasy 66Mhz. */
2443 /* Set up the MBUF pool base address and size. */
2444 REG_WR(pDevice, BufMgr.MbufPoolAddr, pDevice->MbufBase);
2445 REG_WR(pDevice, BufMgr.MbufPoolSize, pDevice->MbufSize);
2447 /* Set up the DMA descriptor pool base address and size. */
2448 REG_WR(pDevice, BufMgr.DmaDescPoolAddr, T3_NIC_DMA_DESC_POOL_ADDR);
2449 REG_WR(pDevice, BufMgr.DmaDescPoolSize, T3_NIC_DMA_DESC_POOL_SIZE);
2451 /* Configure MBUF and Threshold watermarks */
2452 /* Configure the DMA read MBUF low water mark. */
2453 if(pDevice->DmaMbufLowMark)
2455 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2456 pDevice->DmaMbufLowMark);
2460 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2462 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2463 T3_DEF_DMA_MBUF_LOW_WMARK);
2467 REG_WR(pDevice, BufMgr.MbufReadDmaLowWaterMark,
2468 T3_DEF_DMA_MBUF_LOW_WMARK_JUMBO);
2472 /* Configure the MAC Rx MBUF low water mark. */
2473 if(pDevice->RxMacMbufLowMark)
2475 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2476 pDevice->RxMacMbufLowMark);
2480 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2482 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2483 T3_DEF_RX_MAC_MBUF_LOW_WMARK);
2487 REG_WR(pDevice, BufMgr.MbufMacRxLowWaterMark,
2488 T3_DEF_RX_MAC_MBUF_LOW_WMARK_JUMBO);
2492 /* Configure the MBUF high water mark. */
2493 if(pDevice->MbufHighMark)
2495 REG_WR(pDevice, BufMgr.MbufHighWaterMark, pDevice->MbufHighMark);
2499 if(pDevice->TxMtu < MAX_ETHERNET_PACKET_BUFFER_SIZE)
2501 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2502 T3_DEF_MBUF_HIGH_WMARK);
2506 REG_WR(pDevice, BufMgr.MbufHighWaterMark,
2507 T3_DEF_MBUF_HIGH_WMARK_JUMBO);
2511 REG_WR(pDevice, BufMgr.DmaLowWaterMark, T3_DEF_DMA_DESC_LOW_WMARK);
2512 REG_WR(pDevice, BufMgr.DmaHighWaterMark, T3_DEF_DMA_DESC_HIGH_WMARK);
2514 /* Enable buffer manager. */
2515 REG_WR(pDevice, BufMgr.Mode, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
2517 for(j = 0 ;j < 2000; j++)
2519 if(REG_RD(pDevice, BufMgr.Mode) & BUFMGR_MODE_ENABLE)
2526 return LM_STATUS_FAILURE;
2529 /* Enable the FTQs. */
2530 REG_WR(pDevice, Ftq.Reset, 0xffffffff);
2531 REG_WR(pDevice, Ftq.Reset, 0);
2533 /* Wait until FTQ is ready */
2534 for(j = 0; j < 2000; j++)
2536 if(REG_RD(pDevice, Ftq.Reset) == 0)
2543 return LM_STATUS_FAILURE;
2546 /* Initialize the Standard Receive RCB. */
2547 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.High,
2548 pDevice->RxStdBdPhy.High);
2549 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.HostRingAddr.Low,
2550 pDevice->RxStdBdPhy.Low);
2551 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.u.MaxLen_Flags,
2552 MAX_STD_RCV_BUFFER_SIZE << 16);
2554 /* Initialize the Jumbo Receive RCB. */
2555 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags,
2556 T3_RCB_FLAG_RING_DISABLED);
2557 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2558 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.High,
2559 pDevice->RxJumboBdPhy.High);
2560 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.HostRingAddr.Low,
2561 pDevice->RxJumboBdPhy.Low);
2563 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.u.MaxLen_Flags, 0);
2565 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2567 /* Initialize the Mini Receive RCB. */
2568 REG_WR(pDevice, RcvDataBdIn.MiniRcvRcb.u.MaxLen_Flags,
2569 T3_RCB_FLAG_RING_DISABLED);
2572 REG_WR(pDevice, RcvDataBdIn.StdRcvRcb.NicRingAddr,
2573 (LM_UINT32) T3_NIC_STD_RCV_BUFFER_DESC_ADDR);
2574 REG_WR(pDevice, RcvDataBdIn.JumboRcvRcb.NicRingAddr,
2575 (LM_UINT32) T3_NIC_JUMBO_RCV_BUFFER_DESC_ADDR);
2578 /* Receive BD Ring replenish threshold. */
2579 REG_WR(pDevice, RcvBdIn.StdRcvThreshold, pDevice->RxStdDescCnt/8);
2580 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2581 REG_WR(pDevice, RcvBdIn.JumboRcvThreshold, pDevice->RxJumboDescCnt/8);
2582 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
2584 /* Disable all the unused rings. */
2585 for(j = 0; j < T3_MAX_SEND_RCB_COUNT; j++) {
2586 MEM_WR(pDevice, SendRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
2589 /* Initialize the indices. */
2590 pDevice->SendProdIdx = 0;
2591 pDevice->SendConIdx = 0;
2593 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, 0);
2594 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, 0);
2596 /* Set up host or NIC based send RCB. */
2597 if(pDevice->NicSendBd == FALSE)
2599 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High,
2600 pDevice->SendBdPhy.High);
2601 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low,
2602 pDevice->SendBdPhy.Low);
2604 /* Set up the NIC ring address in the RCB. */
2605 MEM_WR(pDevice, SendRcb[0].NicRingAddr,T3_NIC_SND_BUFFER_DESC_ADDR);
2607 /* Setup the RCB. */
2608 MEM_WR(pDevice, SendRcb[0].u.MaxLen_Flags,
2609 T3_SEND_RCB_ENTRY_COUNT << 16);
2611 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
2613 pDevice->pSendBdVirt[k].HostAddr.High = 0;
2614 pDevice->pSendBdVirt[k].HostAddr.Low = 0;
2619 MEM_WR(pDevice, SendRcb[0].HostRingAddr.High, 0);
2620 MEM_WR(pDevice, SendRcb[0].HostRingAddr.Low, 0);
2621 MEM_WR(pDevice, SendRcb[0].NicRingAddr,
2622 pDevice->SendBdPhy.Low);
2624 for(k = 0; k < T3_SEND_RCB_ENTRY_COUNT; k++)
2626 __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.High));
2627 __raw_writel(0, &(pDevice->pSendBdVirt[k].HostAddr.Low));
2628 __raw_writel(0, &(pDevice->pSendBdVirt[k].u1.Len_Flags));
2629 pDevice->ShadowSendBd[k].HostAddr.High = 0;
2630 pDevice->ShadowSendBd[k].u1.Len_Flags = 0;
2633 atomic_set(&pDevice->SendBdLeft, T3_SEND_RCB_ENTRY_COUNT-1);
2635 /* Configure the receive return rings. */
2636 for(j = 0; j < T3_MAX_RCV_RETURN_RCB_COUNT; j++)
2638 MEM_WR(pDevice, RcvRetRcb[j].u.MaxLen_Flags, T3_RCB_FLAG_RING_DISABLED);
2641 pDevice->RcvRetConIdx = 0;
2643 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.High,
2644 pDevice->RcvRetBdPhy.High);
2645 MEM_WR(pDevice, RcvRetRcb[0].HostRingAddr.Low,
2646 pDevice->RcvRetBdPhy.Low);
2648 /* Set up the NIC ring address in the RCB. */
2649 /* Not very clear from the spec. I am guessing that for Receive */
2650 /* Return Ring, NicRingAddr is not used. */
2651 MEM_WR(pDevice, RcvRetRcb[0].NicRingAddr, 0);
2653 /* Setup the RCB. */
2654 MEM_WR(pDevice, RcvRetRcb[0].u.MaxLen_Flags,
2655 T3_RCV_RETURN_RCB_ENTRY_COUNT << 16);
2657 /* Reinitialize RX ring producer index */
2658 MB_REG_WR(pDevice, Mailbox.RcvStdProdIdx.Low, 0);
2659 MB_REG_WR(pDevice, Mailbox.RcvJumboProdIdx.Low, 0);
2660 MB_REG_WR(pDevice, Mailbox.RcvMiniProdIdx.Low, 0);
2662 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
2663 pDevice->RxJumboProdIdx = 0;
2664 pDevice->RxJumboQueuedCnt = 0;
2667 /* Reinitialize our copy of the indices. */
2668 pDevice->RxStdProdIdx = 0;
2669 pDevice->RxStdQueuedCnt = 0;
2671 #if T3_JUMBO_RCV_ENTRY_COUNT
2672 pDevice->RxJumboProdIdx = 0;
2673 #endif /* T3_JUMBO_RCV_ENTRY_COUNT */
2675 /* Configure the MAC address. */
2676 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
2678 /* Initialize the transmit random backoff seed. */
2679 Value32 = (pDevice->NodeAddress[0] + pDevice->NodeAddress[1] +
2680 pDevice->NodeAddress[2] + pDevice->NodeAddress[3] +
2681 pDevice->NodeAddress[4] + pDevice->NodeAddress[5]) &
2682 MAC_TX_BACKOFF_SEED_MASK;
2683 REG_WR(pDevice, MacCtrl.TxBackoffSeed, Value32);
2685 /* Receive MTU. Frames larger than the MTU is marked as oversized. */
2686 REG_WR(pDevice, MacCtrl.MtuSize, pDevice->RxMtu + 8); /* CRC + VLAN. */
2688 /* Configure Time slot/IPG per 802.3 */
2689 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
2692 * Configure Receive Rules so that packets don't match
2693 * Programmble rule will be queued to Return Ring 1
2695 REG_WR(pDevice, MacCtrl.RcvRuleCfg, RX_RULE_DEFAULT_CLASS);
2698 * Configure to have 16 Classes of Services (COS) and one
2699 * queue per class. Bad frames are queued to RRR#1.
2700 * And frames don't match rules are also queued to COS#1.
2702 REG_WR(pDevice, RcvListPlmt.Config, 0x181);
2704 /* Enable Receive Placement Statistics */
2705 REG_WR(pDevice, RcvListPlmt.StatsEnableMask,0xffffff);
2706 REG_WR(pDevice, RcvListPlmt.StatsCtrl, RCV_LIST_STATS_ENABLE);
2708 /* Enable Send Data Initator Statistics */
2709 REG_WR(pDevice, SndDataIn.StatsEnableMask,0xffffff);
2710 REG_WR(pDevice, SndDataIn.StatsCtrl,
2711 T3_SND_DATA_IN_STATS_CTRL_ENABLE | \
2712 T3_SND_DATA_IN_STATS_CTRL_FASTER_UPDATE);
2714 /* Disable the host coalescing state machine before configuring it's */
2716 REG_WR(pDevice, HostCoalesce.Mode, 0);
2717 for(j = 0; j < 2000; j++)
2719 Value32 = REG_RD(pDevice, HostCoalesce.Mode);
2720 if(!(Value32 & HOST_COALESCE_ENABLE))
2727 /* Host coalescing configurations. */
2728 REG_WR(pDevice, HostCoalesce.RxCoalescingTicks, pDevice->RxCoalescingTicks);
2729 REG_WR(pDevice, HostCoalesce.TxCoalescingTicks, pDevice->TxCoalescingTicks);
2730 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFrames,
2731 pDevice->RxMaxCoalescedFrames);
2732 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFrames,
2733 pDevice->TxMaxCoalescedFrames);
2734 REG_WR(pDevice, HostCoalesce.RxCoalescedTickDuringInt,
2735 pDevice->RxCoalescingTicksDuringInt);
2736 REG_WR(pDevice, HostCoalesce.TxCoalescedTickDuringInt,
2737 pDevice->TxCoalescingTicksDuringInt);
2738 REG_WR(pDevice, HostCoalesce.RxMaxCoalescedFramesDuringInt,
2739 pDevice->RxMaxCoalescedFramesDuringInt);
2740 REG_WR(pDevice, HostCoalesce.TxMaxCoalescedFramesDuringInt,
2741 pDevice->TxMaxCoalescedFramesDuringInt);
2743 /* Initialize the address of the status block. The NIC will DMA */
2744 /* the status block to this memory which resides on the host. */
2745 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.High,
2746 pDevice->StatusBlkPhy.High);
2747 REG_WR(pDevice, HostCoalesce.StatusBlkHostAddr.Low,
2748 pDevice->StatusBlkPhy.Low);
2750 /* Initialize the address of the statistics block. The NIC will DMA */
2751 /* the statistics to this block of memory. */
2752 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.High,
2753 pDevice->StatsBlkPhy.High);
2754 REG_WR(pDevice, HostCoalesce.StatsBlkHostAddr.Low,
2755 pDevice->StatsBlkPhy.Low);
2757 REG_WR(pDevice, HostCoalesce.StatsCoalescingTicks,
2758 pDevice->StatsCoalescingTicks);
2760 REG_WR(pDevice, HostCoalesce.StatsBlkNicAddr, 0x300);
2761 REG_WR(pDevice, HostCoalesce.StatusBlkNicAddr,0xb00);
2763 /* Enable Host Coalesing state machine */
2764 REG_WR(pDevice, HostCoalesce.Mode, HOST_COALESCE_ENABLE |
2765 pDevice->CoalesceMode);
2767 /* Enable the Receive BD Completion state machine. */
2768 REG_WR(pDevice, RcvBdComp.Mode, RCV_BD_COMP_MODE_ENABLE |
2769 RCV_BD_COMP_MODE_ATTN_ENABLE);
2771 /* Enable the Receive List Placement state machine. */
2772 REG_WR(pDevice, RcvListPlmt.Mode, RCV_LIST_PLMT_MODE_ENABLE);
2774 /* Enable the Receive List Selector state machine. */
2775 REG_WR(pDevice, RcvListSel.Mode, RCV_LIST_SEL_MODE_ENABLE |
2776 RCV_LIST_SEL_MODE_ATTN_ENABLE);
2778 /* Enable transmit DMA, clear statistics. */
2779 pDevice->MacMode = MAC_MODE_ENABLE_TX_STATISTICS |
2780 MAC_MODE_ENABLE_RX_STATISTICS | MAC_MODE_ENABLE_TDE |
2781 MAC_MODE_ENABLE_RDE | MAC_MODE_ENABLE_FHDE;
2782 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
2783 MAC_MODE_CLEAR_RX_STATISTICS | MAC_MODE_CLEAR_TX_STATISTICS);
2785 /* GRC miscellaneous local control register. */
2786 pDevice->GrcLocalCtrl = GRC_MISC_LOCAL_CTRL_INT_ON_ATTN |
2787 GRC_MISC_LOCAL_CTRL_AUTO_SEEPROM;
2789 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
2791 pDevice->GrcLocalCtrl |= GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
2792 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1;
2795 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
2798 /* Reset RX counters. */
2799 for(j = 0; j < sizeof(LM_RX_COUNTERS); j++)
2801 ((PLM_UINT8) &pDevice->RxCounters)[j] = 0;
2804 /* Reset TX counters. */
2805 for(j = 0; j < sizeof(LM_TX_COUNTERS); j++)
2807 ((PLM_UINT8) &pDevice->TxCounters)[j] = 0;
2810 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
2812 /* Enable the DMA Completion state machine. */
2813 REG_WR(pDevice, DmaComp.Mode, DMA_COMP_MODE_ENABLE);
2815 /* Enable the DMA Write state machine. */
2816 Value32 = DMA_WRITE_MODE_ENABLE |
2817 DMA_WRITE_MODE_TARGET_ABORT_ATTN_ENABLE |
2818 DMA_WRITE_MODE_MASTER_ABORT_ATTN_ENABLE |
2819 DMA_WRITE_MODE_PARITY_ERROR_ATTN_ENABLE |
2820 DMA_WRITE_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2821 DMA_WRITE_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2822 DMA_WRITE_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2823 DMA_WRITE_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2824 DMA_WRITE_MODE_LONG_READ_ATTN_ENABLE;
2825 REG_WR(pDevice, DmaWrite.Mode, Value32);
2827 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
2829 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
2831 Value16 = REG_RD(pDevice, PciCfg.PciXCommand);
2832 Value16 &= ~(PCIX_CMD_MAX_SPLIT_MASK | PCIX_CMD_MAX_BURST_MASK);
2833 Value16 |= ((PCIX_CMD_MAX_BURST_CPIOB << PCIX_CMD_MAX_BURST_SHL) &
2834 PCIX_CMD_MAX_BURST_MASK);
2835 if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
2837 Value16 |= (pDevice->SplitModeMaxReq << PCIX_CMD_MAX_SPLIT_SHL)
2838 & PCIX_CMD_MAX_SPLIT_MASK;
2840 REG_WR(pDevice, PciCfg.PciXCommand, Value16);
2844 /* Enable the Read DMA state machine. */
2845 Value32 = DMA_READ_MODE_ENABLE |
2846 DMA_READ_MODE_TARGET_ABORT_ATTN_ENABLE |
2847 DMA_READ_MODE_MASTER_ABORT_ATTN_ENABLE |
2848 DMA_READ_MODE_PARITY_ERROR_ATTN_ENABLE |
2849 DMA_READ_MODE_ADDR_OVERFLOW_ATTN_ENABLE |
2850 DMA_READ_MODE_FIFO_OVERRUN_ATTN_ENABLE |
2851 DMA_READ_MODE_FIFO_UNDERRUN_ATTN_ENABLE |
2852 DMA_READ_MODE_FIFO_OVERREAD_ATTN_ENABLE |
2853 DMA_READ_MODE_LONG_READ_ATTN_ENABLE;
2855 if (pDevice->SplitModeEnable == SPLIT_MODE_ENABLE)
2857 Value32 |= DMA_READ_MODE_SPLIT_ENABLE;
2859 REG_WR(pDevice, DmaRead.Mode, Value32);
2861 /* Enable the Receive Data Completion state machine. */
2862 REG_WR(pDevice, RcvDataComp.Mode, RCV_DATA_COMP_MODE_ENABLE |
2863 RCV_DATA_COMP_MODE_ATTN_ENABLE);
2865 /* Enable the Mbuf Cluster Free state machine. */
2866 REG_WR(pDevice, MbufClusterFree.Mode, MBUF_CLUSTER_FREE_MODE_ENABLE);
2868 /* Enable the Send Data Completion state machine. */
2869 REG_WR(pDevice, SndDataComp.Mode, SND_DATA_COMP_MODE_ENABLE);
2871 /* Enable the Send BD Completion state machine. */
2872 REG_WR(pDevice, SndBdComp.Mode, SND_BD_COMP_MODE_ENABLE |
2873 SND_BD_COMP_MODE_ATTN_ENABLE);
2875 /* Enable the Receive BD Initiator state machine. */
2876 REG_WR(pDevice, RcvBdIn.Mode, RCV_BD_IN_MODE_ENABLE |
2877 RCV_BD_IN_MODE_BD_IN_DIABLED_RCB_ATTN_ENABLE);
2879 /* Enable the Receive Data and Receive BD Initiator state machine. */
2880 REG_WR(pDevice, RcvDataBdIn.Mode, RCV_DATA_BD_IN_MODE_ENABLE |
2881 RCV_DATA_BD_IN_MODE_INVALID_RING_SIZE);
2883 /* Enable the Send Data Initiator state machine. */
2884 REG_WR(pDevice, SndDataIn.Mode, T3_SND_DATA_IN_MODE_ENABLE);
2886 /* Enable the Send BD Initiator state machine. */
2887 REG_WR(pDevice, SndBdIn.Mode, SND_BD_IN_MODE_ENABLE |
2888 SND_BD_IN_MODE_ATTN_ENABLE);
2890 /* Enable the Send BD Selector state machine. */
2891 REG_WR(pDevice, SndBdSel.Mode, SND_BD_SEL_MODE_ENABLE |
2892 SND_BD_SEL_MODE_ATTN_ENABLE);
2894 #if INCLUDE_5701_AX_FIX
2895 /* Load the firmware for the 5701_A0 workaround. */
2896 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0)
2898 LM_LoadRlsFirmware(pDevice);
2902 /* Enable the transmitter. */
2903 pDevice->TxMode = TX_MODE_ENABLE;
2904 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
2906 /* Enable the receiver. */
2907 pDevice->RxMode = RX_MODE_ENABLE;
2908 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2910 if (pDevice->RestoreOnWakeUp)
2912 pDevice->RestoreOnWakeUp = FALSE;
2913 pDevice->DisableAutoNeg = pDevice->WakeUpDisableAutoNeg;
2914 pDevice->RequestedMediaType = pDevice->WakeUpRequestedMediaType;
2917 /* Disable auto polling. */
2918 pDevice->MiMode = 0xc0000;
2919 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
2921 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
2922 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
2924 Value32 = LED_CTRL_PHY_MODE_1;
2928 if(pDevice->LedMode == LED_MODE_OUTPUT)
2930 Value32 = LED_CTRL_PHY_MODE_2;
2934 Value32 = LED_CTRL_PHY_MODE_1;
2937 REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
2939 /* Activate Link to enable MAC state machine */
2940 REG_WR(pDevice, MacCtrl.MiStatus, MI_STATUS_ENABLE_LINK_STATUS_ATTN);
2942 if (pDevice->EnableTbi)
2944 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_RESET);
2946 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
2947 if (pDevice->ChipRevId == T3_CHIP_ID_5703_A1)
2949 REG_WR(pDevice, MacCtrl.SerdesCfg, 0x616000);
2952 /* Setup the phy chip. */
2953 LM_SetupPhy(pDevice);
2955 if (!pDevice->EnableTbi) {
2956 /* Clear CRC stats */
2957 LM_ReadPhy(pDevice, 0x1e, &Value32);
2958 LM_WritePhy(pDevice, 0x1e, Value32 | 0x8000);
2959 LM_ReadPhy(pDevice, 0x14, &Value32);
2962 /* Set up the receive mask. */
2963 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask);
2965 /* Queue Rx packet buffers. */
2966 if(pDevice->QueueRxPackets)
2968 LM_QueueRxPackets(pDevice);
2971 /* Enable interrupt to the host. */
2972 if(pDevice->InitDone)
2974 LM_EnableInterrupt(pDevice);
2977 return LM_STATUS_SUCCESS;
2978 } /* LM_ResetAdapter */
2981 /******************************************************************************/
2983 /* This routine disables the adapter from generating interrupts. */
2986 /* LM_STATUS_SUCCESS */
2987 /******************************************************************************/
2989 LM_DisableInterrupt(
2990 PLM_DEVICE_BLOCK pDevice)
2992 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl |
2993 MISC_HOST_CTRL_MASK_PCI_INT);
2994 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 1);
2996 return LM_STATUS_SUCCESS;
3001 /******************************************************************************/
3003 /* This routine enables the adapter to generate interrupts. */
3006 /* LM_STATUS_SUCCESS */
3007 /******************************************************************************/
3010 PLM_DEVICE_BLOCK pDevice)
3012 REG_WR(pDevice, PciCfg.MiscHostCtrl, pDevice->MiscHostCtrl &
3013 ~MISC_HOST_CTRL_MASK_PCI_INT);
3014 MB_REG_WR(pDevice, Mailbox.Interrupt[0].Low, 0);
3016 if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED)
3018 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
3019 GRC_MISC_LOCAL_CTRL_SET_INT);
3022 return LM_STATUS_SUCCESS;
3027 /******************************************************************************/
3029 /* This routine puts a packet on the wire if there is a transmit DMA */
3030 /* descriptor available; otherwise the packet is queued for later */
3031 /* transmission. If the second argue is NULL, this routine will put */
3032 /* the queued packet on the wire if possible. */
3035 /* LM_STATUS_SUCCESS */
3036 /******************************************************************************/
3039 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3041 LM_UINT32 FragCount;
3043 PT3_SND_BD pShadowSendBd;
3044 LM_UINT32 Value32, Len;
3047 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) {
3048 return LM_5700SendPacket(pDevice, pPacket);
3051 /* Update the SendBdLeft count. */
3052 atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3054 /* Initalize the send buffer descriptors. */
3055 Idx = pDevice->SendProdIdx;
3057 pSendBd = &pDevice->pSendBdVirt[Idx];
3059 /* Next producer index. */
3060 if (pDevice->NicSendBd == TRUE)
3062 T3_64BIT_HOST_ADDR paddr;
3064 pShadowSendBd = &pDevice->ShadowSendBd[Idx];
3065 for(FragCount = 0; ; )
3067 MM_MapTxDma(pDevice, pPacket, &paddr, &Len, FragCount);
3068 /* Initialize the pointer to the send buffer fragment. */
3069 if (paddr.High != pShadowSendBd->HostAddr.High)
3071 __raw_writel(paddr.High, &(pSendBd->HostAddr.High));
3072 pShadowSendBd->HostAddr.High = paddr.High;
3074 __raw_writel(paddr.Low, &(pSendBd->HostAddr.Low));
3076 /* Setup the control flags and send buffer size. */
3077 Value32 = (Len << 16) | pPacket->Flags;
3079 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3082 if (FragCount >= pPacket->u.Tx.FragCount)
3084 Value32 |= SND_BD_FLAG_END;
3085 if (Value32 != pShadowSendBd->u1.Len_Flags)
3087 __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3088 pShadowSendBd->u1.Len_Flags = Value32;
3090 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3091 __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
3097 if (Value32 != pShadowSendBd->u1.Len_Flags)
3099 __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3100 pShadowSendBd->u1.Len_Flags = Value32;
3102 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG) {
3103 __raw_writel(pPacket->VlanTag, &(pSendBd->u2.VlanTag));
3111 pSendBd = &pDevice->pSendBdVirt[0];
3112 pShadowSendBd = &pDevice->ShadowSendBd[0];
3116 /* Put the packet descriptor in the ActiveQ. */
3117 QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3120 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3125 for(FragCount = 0; ; )
3127 /* Initialize the pointer to the send buffer fragment. */
3128 MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3130 pSendBd->u2.VlanTag = pPacket->VlanTag;
3132 /* Setup the control flags and send buffer size. */
3133 Value32 = (Len << 16) | pPacket->Flags;
3135 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3138 if (FragCount >= pPacket->u.Tx.FragCount)
3140 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3145 pSendBd->u1.Len_Flags = Value32;
3150 pSendBd = &pDevice->pSendBdVirt[0];
3154 /* Put the packet descriptor in the ActiveQ. */
3155 QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3158 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3162 /* Update the producer index. */
3163 pDevice->SendProdIdx = Idx;
3165 return LM_STATUS_SUCCESS;
3170 LM_SendPacket(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket)
3172 LM_UINT32 FragCount;
3173 PT3_SND_BD pSendBd, pTmpSendBd, pShadowSendBd;
3174 T3_SND_BD NicSendBdArr[MAX_FRAGMENT_COUNT];
3175 LM_UINT32 StartIdx, Idx;
3179 /* Initalize the send buffer descriptors. */
3180 StartIdx = Idx = pDevice->SendProdIdx;
3182 if (pDevice->NicSendBd)
3184 pTmpSendBd = pSendBd = &NicSendBdArr[0];
3188 pTmpSendBd = pSendBd = &pDevice->pSendBdVirt[Idx];
3191 /* Next producer index. */
3192 for(FragCount = 0; ; )
3194 LM_UINT32 Value32, Len;
3196 /* Initialize the pointer to the send buffer fragment. */
3197 MM_MapTxDma(pDevice, pPacket, &pSendBd->HostAddr, &Len, FragCount);
3199 pSendBd->u2.VlanTag = pPacket->VlanTag;
3201 /* Setup the control flags and send buffer size. */
3202 Value32 = (Len << 16) | pPacket->Flags;
3204 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3207 if (FragCount >= pPacket->u.Tx.FragCount)
3209 pSendBd->u1.Len_Flags = Value32 | SND_BD_FLAG_END;
3214 pSendBd->u1.Len_Flags = Value32;
3217 if ((Idx == 0) && !pDevice->NicSendBd)
3219 pSendBd = &pDevice->pSendBdVirt[0];
3222 if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
3224 if (LM_Test4GBoundary(pDevice, pPacket, pTmpSendBd) ==
3227 if (MM_CoalesceTxBuffer(pDevice, pPacket) != LM_STATUS_SUCCESS)
3229 QQ_PushHead(&pDevice->TxPacketFreeQ.Container, pPacket);
3230 return LM_STATUS_FAILURE;
3237 /* Put the packet descriptor in the ActiveQ. */
3238 QQ_PushTail(&pDevice->TxPacketActiveQ.Container, pPacket);
3240 if (pDevice->NicSendBd)
3242 pSendBd = &pDevice->pSendBdVirt[StartIdx];
3243 pShadowSendBd = &pDevice->ShadowSendBd[StartIdx];
3245 while (StartIdx != Idx)
3249 if ((Value32 = pTmpSendBd->HostAddr.High) !=
3250 pShadowSendBd->HostAddr.High)
3252 __raw_writel(Value32, &(pSendBd->HostAddr.High));
3253 pShadowSendBd->HostAddr.High = Value32;
3256 __raw_writel(pTmpSendBd->HostAddr.Low, &(pSendBd->HostAddr.Low));
3258 if ((Value32 = pTmpSendBd->u1.Len_Flags) !=
3259 pShadowSendBd->u1.Len_Flags)
3261 __raw_writel(Value32, &(pSendBd->u1.Len_Flags));
3262 pShadowSendBd->u1.Len_Flags = Value32;
3265 if (pPacket->Flags & SND_BD_FLAG_VLAN_TAG)
3267 __raw_writel(pTmpSendBd->u2.VlanTag, &(pSendBd->u2.VlanTag));
3270 StartIdx = (StartIdx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3272 pSendBd = &pDevice->pSendBdVirt[0];
3278 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3280 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3282 MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, Idx);
3288 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3290 if(T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX)
3292 MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, Idx);
3296 /* Update the SendBdLeft count. */
3297 atomic_sub(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3299 /* Update the producer index. */
3300 pDevice->SendProdIdx = Idx;
3302 return LM_STATUS_SUCCESS;
3306 LM_Test4GBoundary(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket,
3310 LM_UINT32 Idx, Base, Len;
3312 Idx = pDevice->SendProdIdx;
3313 for(FragCount = 0; ; )
3315 Len = pSendBd->u1.Len_Flags >> 16;
3316 if (((Base = pSendBd->HostAddr.Low) > 0xffffdcc0) &&
3317 (pSendBd->HostAddr.High == 0) &&
3318 ((Base + 8 + Len) < Base))
3320 return LM_STATUS_SUCCESS;
3323 if (FragCount >= pPacket->u.Tx.FragCount)
3328 if (!pDevice->NicSendBd)
3330 Idx = (Idx + 1) & T3_SEND_RCB_ENTRY_COUNT_MASK;
3333 pSendBd = &pDevice->pSendBdVirt[0];
3337 return LM_STATUS_FAILURE;
3340 /******************************************************************************/
3344 /******************************************************************************/
3345 __inline static unsigned long
3347 unsigned char *pBuffer,
3348 unsigned long BufferSize) {
3355 for(j = 0; j < BufferSize; j++)
3359 for(k = 0; k < 8; k++)
3373 } /* ComputeCrc32 */
3377 /******************************************************************************/
3379 /* This routine sets the receive control register according to ReceiveMask */
3382 /* LM_STATUS_SUCCESS */
3383 /******************************************************************************/
3386 PLM_DEVICE_BLOCK pDevice,
3388 LM_UINT32 ReceiveMask;
3394 RxMode = pDevice->RxMode;
3396 if(Mask & LM_ACCEPT_UNICAST)
3398 Mask &= ~LM_ACCEPT_UNICAST;
3401 if(Mask & LM_ACCEPT_MULTICAST)
3403 Mask &= ~LM_ACCEPT_MULTICAST;
3406 if(Mask & LM_ACCEPT_ALL_MULTICAST)
3408 Mask &= ~LM_ACCEPT_ALL_MULTICAST;
3411 if(Mask & LM_ACCEPT_BROADCAST)
3413 Mask &= ~LM_ACCEPT_BROADCAST;
3416 RxMode &= ~RX_MODE_PROMISCUOUS_MODE;
3417 if(Mask & LM_PROMISCUOUS_MODE)
3419 RxMode |= RX_MODE_PROMISCUOUS_MODE;
3420 Mask &= ~LM_PROMISCUOUS_MODE;
3423 RxMode &= ~(RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED);
3424 if(Mask & LM_ACCEPT_ERROR_PACKET)
3426 RxMode |= RX_MODE_ACCEPT_RUNTS | RX_MODE_ACCEPT_OVERSIZED;
3427 Mask &= ~LM_ACCEPT_ERROR_PACKET;
3430 /* Make sure all the bits are valid before committing changes. */
3433 return LM_STATUS_FAILURE;
3436 /* Commit the new filter. */
3437 pDevice->RxMode = RxMode;
3438 REG_WR(pDevice, MacCtrl.RxMode, RxMode);
3440 pDevice->ReceiveMask = ReceiveMask;
3442 /* Set up the MC hash table. */
3443 if(ReceiveMask & LM_ACCEPT_ALL_MULTICAST)
3445 for(k = 0; k < 4; k++)
3447 REG_WR(pDevice, MacCtrl.HashReg[k], 0xffffffff);
3450 else if(ReceiveMask & LM_ACCEPT_MULTICAST)
3452 LM_UINT32 HashReg[4];
3454 HashReg[0] = 0; HashReg[1] = 0; HashReg[2] = 0; HashReg[3] = 0;
3455 for(j = 0; j < pDevice->McEntryCount; j++)
3461 Crc32 = ComputeCrc32(pDevice->McTable[j], ETHERNET_ADDRESS_SIZE);
3463 /* The most significant 7 bits of the CRC32 (no inversion), */
3464 /* are used to index into one of the possible 128 bit positions. */
3465 Bitpos = ~Crc32 & 0x7f;
3467 /* Hash register index. */
3468 RegIndex = (Bitpos & 0x60) >> 5;
3470 /* Bit to turn on within a hash register. */
3473 /* Enable the multicast bit. */
3474 HashReg[RegIndex] |= (1 << Bitpos);
3477 /* REV_AX has problem with multicast filtering where it uses both */
3478 /* DA and SA to perform hashing. */
3479 for(k = 0; k < 4; k++)
3481 REG_WR(pDevice, MacCtrl.HashReg[k], HashReg[k]);
3486 /* Reject all multicast frames. */
3487 for(j = 0; j < 4; j++)
3489 REG_WR(pDevice, MacCtrl.HashReg[j], 0);
3493 /* By default, Tigon3 will accept broadcast frames. We need to setup */
3494 if(ReceiveMask & LM_ACCEPT_BROADCAST)
3496 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3497 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3498 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3499 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3500 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3501 REJECT_BROADCAST_RULE1_RULE & RCV_DISABLE_RULE_MASK);
3502 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3503 REJECT_BROADCAST_RULE1_VALUE & RCV_DISABLE_RULE_MASK);
3507 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Rule,
3508 REJECT_BROADCAST_RULE1_RULE);
3509 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE1_REJECT_BROADCAST_IDX].Value,
3510 REJECT_BROADCAST_RULE1_VALUE);
3511 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Rule,
3512 REJECT_BROADCAST_RULE2_RULE);
3513 REG_WR(pDevice, MacCtrl.RcvRules[RCV_RULE2_REJECT_BROADCAST_IDX].Value,
3514 REJECT_BROADCAST_RULE2_VALUE);
3517 /* disable the rest of the rules. */
3518 for(j = RCV_LAST_RULE_IDX; j < 16; j++)
3520 REG_WR(pDevice, MacCtrl.RcvRules[j].Rule, 0);
3521 REG_WR(pDevice, MacCtrl.RcvRules[j].Value, 0);
3524 return LM_STATUS_SUCCESS;
3525 } /* LM_SetReceiveMask */
3529 /******************************************************************************/
3531 /* Disable the interrupt and put the transmitter and receiver engines in */
3532 /* an idle state. Also aborts all pending send requests and receive */
3536 /* LM_STATUS_SUCCESS */
3537 /******************************************************************************/
3540 PLM_DEVICE_BLOCK pDevice)
3545 LM_DisableInterrupt(pDevice);
3547 /* Disable all the state machines. */
3548 LM_CntrlBlock(pDevice,T3_BLOCK_MAC_RX_ENGINE,LM_DISABLE);
3549 LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_INITIATOR,LM_DISABLE);
3550 LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_PLMT,LM_DISABLE);
3551 LM_CntrlBlock(pDevice,T3_BLOCK_RX_LIST_SELECTOR,LM_DISABLE);
3552 LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_INITIATOR,LM_DISABLE);
3553 LM_CntrlBlock(pDevice,T3_BLOCK_RX_DATA_COMP,LM_DISABLE);
3554 LM_CntrlBlock(pDevice,T3_BLOCK_RX_BD_COMP,LM_DISABLE);
3556 LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_SELECTOR,LM_DISABLE);
3557 LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_INITIATOR,LM_DISABLE);
3558 LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_INITIATOR,LM_DISABLE);
3559 LM_CntrlBlock(pDevice,T3_BLOCK_DMA_RD,LM_DISABLE);
3560 LM_CntrlBlock(pDevice,T3_BLOCK_SEND_DATA_COMP,LM_DISABLE);
3561 LM_CntrlBlock(pDevice,T3_BLOCK_DMA_COMP,LM_DISABLE);
3562 LM_CntrlBlock(pDevice,T3_BLOCK_SEND_BD_COMP,LM_DISABLE);
3565 pDevice->MacMode &= ~MAC_MODE_ENABLE_TDE;
3566 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
3568 LM_CntrlBlock(pDevice,T3_BLOCK_MAC_TX_ENGINE,LM_DISABLE);
3569 LM_CntrlBlock(pDevice,T3_BLOCK_HOST_COALESING,LM_DISABLE);
3570 LM_CntrlBlock(pDevice,T3_BLOCK_DMA_WR,LM_DISABLE);
3571 LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_CLUSTER_FREE,LM_DISABLE);
3573 /* Reset all FTQs */
3574 REG_WR(pDevice, Ftq.Reset, 0xffffffff);
3575 REG_WR(pDevice, Ftq.Reset, 0x0);
3577 LM_CntrlBlock(pDevice,T3_BLOCK_MBUF_MANAGER,LM_DISABLE);
3578 LM_CntrlBlock(pDevice,T3_BLOCK_MEM_ARBITOR,LM_DISABLE);
3580 MM_ACQUIRE_INT_LOCK(pDevice);
3582 /* Abort packets that have already queued to go out. */
3583 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
3587 pPacket->PacketStatus = LM_STATUS_TRANSMIT_ABORTED;
3588 pDevice->TxCounters.TxPacketAbortedCnt++;
3590 atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3592 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
3594 pPacket = (PLM_PACKET)
3595 QQ_PopHead(&pDevice->TxPacketActiveQ.Container);
3598 /* Cleanup the receive return rings. */
3599 LM_ServiceRxInterrupt(pDevice);
3601 /* Don't want to indicate rx packets in Ndis miniport shutdown context. */
3602 /* Doing so may cause system crash. */
3603 if(!pDevice->ShuttingDown)
3605 /* Indicate packets to the protocol. */
3606 MM_IndicateTxPackets(pDevice);
3608 /* Indicate received packets to the protocols. */
3609 MM_IndicateRxPackets(pDevice);
3613 /* Move the receive packet descriptors in the ReceivedQ to the */
3617 pPacket = (PLM_PACKET) QQ_PopHead(
3618 &pDevice->RxPacketReceivedQ.Container);
3623 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3627 /* Clean up the Std Receive Producer ring. */
3628 Idx = pDevice->pStatusBlkVirt->RcvStdConIdx;
3630 while(Idx != pDevice->RxStdProdIdx) {
3631 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3632 MM_UINT_PTR(pDevice->pRxStdBdVirt[Idx].Opaque));
3634 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3636 Idx = (Idx + 1) & T3_STD_RCV_RCB_ENTRY_COUNT_MASK;
3639 /* Reinitialize our copy of the indices. */
3640 pDevice->RxStdProdIdx = 0;
3642 #if T3_JUMBO_RCV_RCB_ENTRY_COUNT
3643 /* Clean up the Jumbo Receive Producer ring. */
3644 Idx = pDevice->pStatusBlkVirt->RcvJumboConIdx;
3646 while(Idx != pDevice->RxJumboProdIdx) {
3647 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3648 MM_UINT_PTR(pDevice->pRxJumboBdVirt[Idx].Opaque));
3650 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3652 Idx = (Idx + 1) & T3_JUMBO_RCV_RCB_ENTRY_COUNT_MASK;
3655 /* Reinitialize our copy of the indices. */
3656 pDevice->RxJumboProdIdx = 0;
3657 #endif /* T3_JUMBO_RCV_RCB_ENTRY_COUNT */
3659 MM_RELEASE_INT_LOCK(pDevice);
3661 /* Initialize the statistis Block */
3662 pDevice->pStatusBlkVirt->Status = 0;
3663 pDevice->pStatusBlkVirt->RcvStdConIdx = 0;
3664 pDevice->pStatusBlkVirt->RcvJumboConIdx = 0;
3665 pDevice->pStatusBlkVirt->RcvMiniConIdx = 0;
3667 return LM_STATUS_SUCCESS;
3672 /******************************************************************************/
3674 /* Disable the interrupt and put the transmitter and receiver engines in */
3675 /* an idle state. Aborts all pending send requests and receive buffers. */
3676 /* Also free all the receive buffers. */
3679 /* LM_STATUS_SUCCESS */
3680 /******************************************************************************/
3683 PLM_DEVICE_BLOCK pDevice) {
3689 /* Get the number of entries in the queue. */
3690 EntryCnt = QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container);
3692 /* Make sure all the packets have been accounted for. */
3693 for(EntryCnt = 0; EntryCnt < pDevice->RxPacketDescCnt; EntryCnt++)
3695 pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->RxPacketFreeQ.Container);
3699 MM_FreeRxBuffer(pDevice, pPacket);
3701 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket);
3704 LM_ResetChip(pDevice);
3706 /* Restore PCI configuration registers. */
3707 MM_WriteConfig32(pDevice, PCI_CACHE_LINE_SIZE_REG,
3708 pDevice->SavedCacheLineReg);
3709 LM_RegWrInd(pDevice, PCI_SUBSYSTEM_VENDOR_ID_REG,
3710 (pDevice->SubsystemId << 16) | pDevice->SubsystemVendorId);
3712 /* Reprogram the MAC address. */
3713 LM_SetMacAddress(pDevice, pDevice->NodeAddress);
3715 return LM_STATUS_SUCCESS;
3720 LM_ResetChip(PLM_DEVICE_BLOCK pDevice)
3725 /* Wait for access to the nvram interface before resetting. This is */
3726 /* a workaround to prevent EEPROM corruption. */
3727 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
3728 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
3730 /* Request access to the flash interface. */
3731 REG_WR(pDevice, Nvram.SwArb, SW_ARB_REQ_SET1);
3733 for(j = 0; j < 100000; j++)
3735 Value32 = REG_RD(pDevice, Nvram.SwArb);
3736 if(Value32 & SW_ARB_GNT1)
3745 REG_WR(pDevice, Grc.MiscCfg, GRC_MISC_CFG_CORE_CLOCK_RESET);
3746 MM_Wait(40); MM_Wait(40); MM_Wait(40);
3748 /* make sure we re-enable indirect accesses */
3749 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG,
3750 pDevice->MiscHostCtrl);
3752 /* Set MAX PCI retry to zero. */
3753 Value32 = T3_PCI_STATE_PCI_ROM_ENABLE | T3_PCI_STATE_PCI_ROM_RETRY_ENABLE;
3754 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
3756 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
3758 Value32 |= T3_PCI_STATE_RETRY_SAME_DMA;
3761 MM_WriteConfig32(pDevice, T3_PCI_STATE_REG, Value32);
3763 /* Restore PCI command register. */
3764 MM_WriteConfig32(pDevice, PCI_COMMAND_REG,
3765 pDevice->PciCommandStatusWords);
3767 /* Disable PCI-X relaxed ordering bit. */
3768 MM_ReadConfig32(pDevice, PCIX_CAP_REG, &Value32);
3769 Value32 &= ~PCIX_ENABLE_RELAXED_ORDERING;
3770 MM_WriteConfig32(pDevice, PCIX_CAP_REG, Value32);
3772 /* Enable memory arbiter. */
3773 REG_WR(pDevice, MemArbiter.Mode, T3_MEM_ARBITER_MODE_ENABLE);
3775 #ifdef BIG_ENDIAN_PCI /* This from jfd */
3776 Value32 = GRC_MODE_WORD_SWAP_DATA|
3777 GRC_MODE_WORD_SWAP_NON_FRAME_DATA;
3779 #ifdef BIG_ENDIAN_HOST
3780 /* Reconfigure the mode register. */
3781 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA |
3782 GRC_MODE_WORD_SWAP_NON_FRAME_DATA |
3783 GRC_MODE_BYTE_SWAP_DATA |
3784 GRC_MODE_WORD_SWAP_DATA;
3786 /* Reconfigure the mode register. */
3787 Value32 = GRC_MODE_BYTE_SWAP_NON_FRAME_DATA | GRC_MODE_BYTE_SWAP_DATA;
3790 REG_WR(pDevice, Grc.Mode, Value32);
3792 /* Prevent PXE from restarting. */
3793 MEM_WR_OFFSET(pDevice, 0x0b50, T3_MAGIC_NUM);
3795 if(pDevice->EnableTbi) {
3796 pDevice->MacMode = MAC_MODE_PORT_MODE_TBI;
3797 REG_WR(pDevice, MacCtrl.Mode, MAC_MODE_PORT_MODE_TBI);
3800 REG_WR(pDevice, MacCtrl.Mode, 0);
3803 /* Wait for the firmware to finish initialization. */
3804 for(j = 0; j < 100000; j++)
3808 Value32 = MEM_RD_OFFSET(pDevice, 0x0b50);
3809 if(Value32 == ~T3_MAGIC_NUM)
3814 return LM_STATUS_SUCCESS;
3817 /******************************************************************************/
3821 /******************************************************************************/
3822 __inline static void
3823 LM_ServiceTxInterrupt(
3824 PLM_DEVICE_BLOCK pDevice) {
3829 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3831 /* Get our copy of the consumer index. The buffer descriptors */
3832 /* that are in between the consumer indices are freed. */
3833 SwConIdx = pDevice->SendConIdx;
3835 /* Move the packets from the TxPacketActiveQ that are sent out to */
3836 /* the TxPacketXmittedQ. Packets that are sent use the */
3837 /* descriptors that are between SwConIdx and HwConIdx. */
3838 while(SwConIdx != HwConIdx)
3840 /* Get the packet that was sent from the TxPacketActiveQ. */
3841 pPacket = (PLM_PACKET) QQ_PopHead(
3842 &pDevice->TxPacketActiveQ.Container);
3844 /* Set the return status. */
3845 pPacket->PacketStatus = LM_STATUS_SUCCESS;
3847 /* Put the packet in the TxPacketXmittedQ for indication later. */
3848 QQ_PushTail(&pDevice->TxPacketXmittedQ.Container, pPacket);
3850 /* Move to the next packet's BD. */
3851 SwConIdx = (SwConIdx + pPacket->u.Tx.FragCount) &
3852 T3_SEND_RCB_ENTRY_COUNT_MASK;
3854 /* Update the number of unused BDs. */
3855 atomic_add(pPacket->u.Tx.FragCount, &pDevice->SendBdLeft);
3857 /* Get the new updated HwConIdx. */
3858 HwConIdx = pDevice->pStatusBlkVirt->Idx[0].SendConIdx;
3861 /* Save the new SwConIdx. */
3862 pDevice->SendConIdx = SwConIdx;
3864 } /* LM_ServiceTxInterrupt */
3868 /******************************************************************************/
3872 /******************************************************************************/
3873 __inline static void
3874 LM_ServiceRxInterrupt(
3875 PLM_DEVICE_BLOCK pDevice) {
3878 LM_UINT32 HwRcvRetProdIdx;
3879 LM_UINT32 SwRcvRetConIdx;
3881 /* Loop thru the receive return rings for received packets. */
3882 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3884 SwRcvRetConIdx = pDevice->RcvRetConIdx;
3885 while(SwRcvRetConIdx != HwRcvRetProdIdx)
3887 pRcvBd = &pDevice->pRcvRetBdVirt[SwRcvRetConIdx];
3889 /* Get the received packet descriptor. */
3890 pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
3891 MM_UINT_PTR(pRcvBd->Opaque));
3893 /* Check the error flag. */
3894 if(pRcvBd->ErrorFlag &&
3895 pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
3897 pPacket->PacketStatus = LM_STATUS_FAILURE;
3899 pDevice->RxCounters.RxPacketErrCnt++;
3901 if(pRcvBd->ErrorFlag & RCV_BD_ERR_BAD_CRC)
3903 pDevice->RxCounters.RxErrCrcCnt++;
3906 if(pRcvBd->ErrorFlag & RCV_BD_ERR_COLL_DETECT)
3908 pDevice->RxCounters.RxErrCollCnt++;
3911 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LINK_LOST_DURING_PKT)
3913 pDevice->RxCounters.RxErrLinkLostCnt++;
3916 if(pRcvBd->ErrorFlag & RCV_BD_ERR_PHY_DECODE_ERR)
3918 pDevice->RxCounters.RxErrPhyDecodeCnt++;
3921 if(pRcvBd->ErrorFlag & RCV_BD_ERR_ODD_NIBBLED_RCVD_MII)
3923 pDevice->RxCounters.RxErrOddNibbleCnt++;
3926 if(pRcvBd->ErrorFlag & RCV_BD_ERR_MAC_ABORT)
3928 pDevice->RxCounters.RxErrMacAbortCnt++;
3931 if(pRcvBd->ErrorFlag & RCV_BD_ERR_LEN_LT_64)
3933 pDevice->RxCounters.RxErrShortPacketCnt++;
3936 if(pRcvBd->ErrorFlag & RCV_BD_ERR_TRUNC_NO_RESOURCES)
3938 pDevice->RxCounters.RxErrNoResourceCnt++;
3941 if(pRcvBd->ErrorFlag & RCV_BD_ERR_GIANT_FRAME_RCVD)
3943 pDevice->RxCounters.RxErrLargePacketCnt++;
3948 pPacket->PacketStatus = LM_STATUS_SUCCESS;
3949 pPacket->PacketSize = pRcvBd->Len - 4;
3951 pPacket->Flags = pRcvBd->Flags;
3952 if(pRcvBd->Flags & RCV_BD_FLAG_VLAN_TAG)
3954 pPacket->VlanTag = pRcvBd->VlanTag;
3957 pPacket->u.Rx.TcpUdpChecksum = pRcvBd->TcpUdpCksum;
3960 /* Put the packet descriptor containing the received packet */
3961 /* buffer in the RxPacketReceivedQ for indication later. */
3962 QQ_PushTail(&pDevice->RxPacketReceivedQ.Container, pPacket);
3964 /* Go to the next buffer descriptor. */
3965 SwRcvRetConIdx = (SwRcvRetConIdx + 1) &
3966 T3_RCV_RETURN_RCB_ENTRY_COUNT_MASK;
3968 /* Get the updated HwRcvRetProdIdx. */
3969 HwRcvRetProdIdx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
3972 pDevice->RcvRetConIdx = SwRcvRetConIdx;
3974 /* Update the receive return ring consumer index. */
3975 MB_REG_WR(pDevice, Mailbox.RcvRetConIdx[0].Low, SwRcvRetConIdx);
3976 } /* LM_ServiceRxInterrupt */
3980 /******************************************************************************/
3982 /* This is the interrupt event handler routine. It acknowledges all */
3983 /* pending interrupts and process all pending events. */
3986 /* LM_STATUS_SUCCESS */
3987 /******************************************************************************/
3989 LM_ServiceInterrupts(
3990 PLM_DEVICE_BLOCK pDevice)
3993 int ServicePhyInt = FALSE;
3995 /* Setup the phy chip whenever the link status changes. */
3996 if(pDevice->LinkChngMode == T3_LINK_CHNG_MODE_USE_STATUS_REG)
3998 Value32 = REG_RD(pDevice, MacCtrl.Status);
3999 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
4001 if (Value32 & MAC_STATUS_MI_INTERRUPT)
4003 ServicePhyInt = TRUE;
4006 else if(Value32 & MAC_STATUS_LINK_STATE_CHANGED)
4008 ServicePhyInt = TRUE;
4013 if(pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_LINK_CHANGED_STATUS)
4015 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4016 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4017 ServicePhyInt = TRUE;
4020 #if INCLUDE_TBI_SUPPORT
4021 if (pDevice->IgnoreTbiLinkChange == TRUE)
4023 ServicePhyInt = FALSE;
4026 if (ServicePhyInt == TRUE)
4028 LM_SetupPhy(pDevice);
4031 /* Service receive and transmit interrupts. */
4032 LM_ServiceRxInterrupt(pDevice);
4033 LM_ServiceTxInterrupt(pDevice);
4035 /* No spinlock for this queue since this routine is serialized. */
4036 if(!QQ_Empty(&pDevice->RxPacketReceivedQ.Container))
4038 /* Indicate receive packets. */
4039 MM_IndicateRxPackets(pDevice);
4040 /* LM_QueueRxPackets(pDevice); */
4043 /* No spinlock for this queue since this routine is serialized. */
4044 if(!QQ_Empty(&pDevice->TxPacketXmittedQ.Container))
4046 MM_IndicateTxPackets(pDevice);
4049 return LM_STATUS_SUCCESS;
4050 } /* LM_ServiceInterrupts */
4054 /******************************************************************************/
4058 /******************************************************************************/
4061 PLM_DEVICE_BLOCK pDevice,
4062 PLM_UINT8 pMcAddress) {
4066 pEntry = pDevice->McTable[0];
4067 for(j = 0; j < pDevice->McEntryCount; j++)
4069 if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
4071 /* Found a match, increment the instance count. */
4072 pEntry[LM_MC_INSTANCE_COUNT_INDEX] += 1;
4074 return LM_STATUS_SUCCESS;
4077 pEntry += LM_MC_ENTRY_SIZE;
4080 if(pDevice->McEntryCount >= LM_MAX_MC_TABLE_SIZE)
4082 return LM_STATUS_FAILURE;
4085 pEntry = pDevice->McTable[pDevice->McEntryCount];
4087 COPY_ETH_ADDRESS(pMcAddress, pEntry);
4088 pEntry[LM_MC_INSTANCE_COUNT_INDEX] = 1;
4090 pDevice->McEntryCount++;
4092 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask | LM_ACCEPT_MULTICAST);
4094 return LM_STATUS_SUCCESS;
4095 } /* LM_MulticastAdd */
4099 /******************************************************************************/
4103 /******************************************************************************/
4106 PLM_DEVICE_BLOCK pDevice,
4107 PLM_UINT8 pMcAddress) {
4111 pEntry = pDevice->McTable[0];
4112 for(j = 0; j < pDevice->McEntryCount; j++)
4114 if(IS_ETH_ADDRESS_EQUAL(pEntry, pMcAddress))
4116 /* Found a match, decrement the instance count. */
4117 pEntry[LM_MC_INSTANCE_COUNT_INDEX] -= 1;
4119 /* No more instance left, remove the address from the table. */
4120 /* Move the last entry in the table to the delete slot. */
4121 if(pEntry[LM_MC_INSTANCE_COUNT_INDEX] == 0 &&
4122 pDevice->McEntryCount > 1)
4126 pDevice->McTable[pDevice->McEntryCount-1], pEntry);
4127 pEntry[LM_MC_INSTANCE_COUNT_INDEX] =
4128 pDevice->McTable[pDevice->McEntryCount-1]
4129 [LM_MC_INSTANCE_COUNT_INDEX];
4131 pDevice->McEntryCount--;
4133 /* Update the receive mask if the table is empty. */
4134 if(pDevice->McEntryCount == 0)
4136 LM_SetReceiveMask(pDevice,
4137 pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4140 return LM_STATUS_SUCCESS;
4143 pEntry += LM_MC_ENTRY_SIZE;
4146 return LM_STATUS_FAILURE;
4147 } /* LM_MulticastDel */
4151 /******************************************************************************/
4155 /******************************************************************************/
4158 PLM_DEVICE_BLOCK pDevice) {
4159 pDevice->McEntryCount = 0;
4161 LM_SetReceiveMask(pDevice, pDevice->ReceiveMask & ~LM_ACCEPT_MULTICAST);
4163 return LM_STATUS_SUCCESS;
4164 } /* LM_MulticastClear */
4168 /******************************************************************************/
4172 /******************************************************************************/
4175 PLM_DEVICE_BLOCK pDevice,
4176 PLM_UINT8 pMacAddress)
4180 for(j = 0; j < 4; j++)
4182 REG_WR(pDevice, MacCtrl.MacAddr[j].High,
4183 (pMacAddress[0] << 8) | pMacAddress[1]);
4184 REG_WR(pDevice, MacCtrl.MacAddr[j].Low,
4185 (pMacAddress[2] << 24) | (pMacAddress[3] << 16) |
4186 (pMacAddress[4] << 8) | pMacAddress[5]);
4189 return LM_STATUS_SUCCESS;
4193 /******************************************************************************/
4195 /* Sets up the default line speed, and duplex modes based on the requested */
4200 /******************************************************************************/
4202 LM_TranslateRequestedMediaType(
4203 LM_REQUESTED_MEDIA_TYPE RequestedMediaType,
4204 PLM_MEDIA_TYPE pMediaType,
4205 PLM_LINE_SPEED pLineSpeed,
4206 PLM_DUPLEX_MODE pDuplexMode) {
4207 *pMediaType = LM_MEDIA_TYPE_AUTO;
4208 *pLineSpeed = LM_LINE_SPEED_UNKNOWN;
4209 *pDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4211 /* determine media type */
4212 switch(RequestedMediaType) {
4213 case LM_REQUESTED_MEDIA_TYPE_BNC:
4214 *pMediaType = LM_MEDIA_TYPE_BNC;
4215 *pLineSpeed = LM_LINE_SPEED_10MBPS;
4216 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4219 case LM_REQUESTED_MEDIA_TYPE_UTP_AUTO:
4220 *pMediaType = LM_MEDIA_TYPE_UTP;
4223 case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS:
4224 *pMediaType = LM_MEDIA_TYPE_UTP;
4225 *pLineSpeed = LM_LINE_SPEED_10MBPS;
4226 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4229 case LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS_FULL_DUPLEX:
4230 *pMediaType = LM_MEDIA_TYPE_UTP;
4231 *pLineSpeed = LM_LINE_SPEED_10MBPS;
4232 *pDuplexMode = LM_DUPLEX_MODE_FULL;
4235 case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS:
4236 *pMediaType = LM_MEDIA_TYPE_UTP;
4237 *pLineSpeed = LM_LINE_SPEED_100MBPS;
4238 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4241 case LM_REQUESTED_MEDIA_TYPE_UTP_100MBPS_FULL_DUPLEX:
4242 *pMediaType = LM_MEDIA_TYPE_UTP;
4243 *pLineSpeed = LM_LINE_SPEED_100MBPS;
4244 *pDuplexMode = LM_DUPLEX_MODE_FULL;
4247 case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS:
4248 *pMediaType = LM_MEDIA_TYPE_UTP;
4249 *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4250 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4253 case LM_REQUESTED_MEDIA_TYPE_UTP_1000MBPS_FULL_DUPLEX:
4254 *pMediaType = LM_MEDIA_TYPE_UTP;
4255 *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4256 *pDuplexMode = LM_DUPLEX_MODE_FULL;
4259 case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS:
4260 *pMediaType = LM_MEDIA_TYPE_FIBER;
4261 *pLineSpeed = LM_LINE_SPEED_100MBPS;
4262 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4265 case LM_REQUESTED_MEDIA_TYPE_FIBER_100MBPS_FULL_DUPLEX:
4266 *pMediaType = LM_MEDIA_TYPE_FIBER;
4267 *pLineSpeed = LM_LINE_SPEED_100MBPS;
4268 *pDuplexMode = LM_DUPLEX_MODE_FULL;
4271 case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS:
4272 *pMediaType = LM_MEDIA_TYPE_FIBER;
4273 *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4274 *pDuplexMode = LM_DUPLEX_MODE_HALF;
4277 case LM_REQUESTED_MEDIA_TYPE_FIBER_1000MBPS_FULL_DUPLEX:
4278 *pMediaType = LM_MEDIA_TYPE_FIBER;
4279 *pLineSpeed = LM_LINE_SPEED_1000MBPS;
4280 *pDuplexMode = LM_DUPLEX_MODE_FULL;
4287 return LM_STATUS_SUCCESS;
4288 } /* LM_TranslateRequestedMediaType */
4290 /******************************************************************************/
4294 /* LM_STATUS_LINK_ACTIVE */
4295 /* LM_STATUS_LINK_DOWN */
4296 /******************************************************************************/
4299 PLM_DEVICE_BLOCK pDevice)
4301 LM_LINE_SPEED CurrentLineSpeed;
4302 LM_DUPLEX_MODE CurrentDuplexMode;
4303 LM_STATUS CurrentLinkStatus;
4307 #if 1 /* jmb: bugfix -- moved here, out of code that sets initial pwr state */
4308 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x2);
4310 if((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
4312 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4313 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4315 if(!pDevice->InitDone)
4320 if(!(Value32 & PHY_STATUS_LINK_PASS))
4322 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
4324 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4325 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4327 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4328 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4330 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4331 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4333 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4334 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4336 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4337 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4339 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4340 for(j = 0; j < 1000; j++)
4344 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4345 if(Value32 & PHY_STATUS_LINK_PASS)
4352 if((pDevice->PhyId & PHY_ID_REV_MASK) == PHY_BCM5401_B0_REV)
4354 if(!(Value32 & PHY_STATUS_LINK_PASS) &&
4355 (pDevice->OldLineSpeed == LM_LINE_SPEED_1000MBPS))
4357 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_PHY_RESET);
4358 for(j = 0; j < 100; j++)
4362 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4363 if(!(Value32 & PHY_CTRL_PHY_RESET))
4370 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x0c20);
4372 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0012);
4373 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1804);
4375 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x0013);
4376 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x1204);
4378 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4379 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0132);
4381 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x8006);
4382 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0232);
4384 LM_WritePhy(pDevice, BCM540X_DSP_ADDRESS_REG, 0x201f);
4385 LM_WritePhy(pDevice, BCM540X_DSP_RW_PORT, 0x0a20);
4390 else if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
4391 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
4393 /* Bug: 5701 A0, B0 TX CRC workaround. */
4394 LM_WritePhy(pDevice, 0x15, 0x0a75);
4395 LM_WritePhy(pDevice, 0x1c, 0x8c68);
4396 LM_WritePhy(pDevice, 0x1c, 0x8d68);
4397 LM_WritePhy(pDevice, 0x1c, 0x8c68);
4400 /* Acknowledge interrupts. */
4401 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
4402 LM_ReadPhy(pDevice, BCM540X_INT_STATUS_REG, &Value32);
4404 /* Configure the interrupt mask. */
4405 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
4407 LM_WritePhy(pDevice, BCM540X_INT_MASK_REG, ~BCM540X_INT_LINK_CHANGE);
4410 /* Configure PHY led mode. */
4411 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701 ||
4412 (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700))
4414 if(pDevice->LedMode == LED_MODE_THREE_LINK)
4416 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG,
4417 BCM540X_EXT_CTRL_LINK3_LED_MODE);
4421 LM_WritePhy(pDevice, BCM540X_EXT_CTRL_REG, 0);
4425 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4427 /* Get current link and duplex mode. */
4428 for(j = 0; j < 100; j++)
4430 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4431 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
4433 if(Value32 & PHY_STATUS_LINK_PASS)
4440 if(Value32 & PHY_STATUS_LINK_PASS)
4443 /* Determine the current line and duplex settings. */
4444 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4445 for(j = 0; j < 2000; j++)
4449 LM_ReadPhy(pDevice, BCM540X_AUX_STATUS_REG, &Value32);
4456 switch(Value32 & BCM540X_AUX_SPEED_MASK)
4458 case BCM540X_AUX_10BASET_HD:
4459 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4460 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4463 case BCM540X_AUX_10BASET_FD:
4464 CurrentLineSpeed = LM_LINE_SPEED_10MBPS;
4465 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4468 case BCM540X_AUX_100BASETX_HD:
4469 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4470 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4473 case BCM540X_AUX_100BASETX_FD:
4474 CurrentLineSpeed = LM_LINE_SPEED_100MBPS;
4475 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4478 case BCM540X_AUX_100BASET_HD:
4479 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4480 CurrentDuplexMode = LM_DUPLEX_MODE_HALF;
4483 case BCM540X_AUX_100BASET_FD:
4484 CurrentLineSpeed = LM_LINE_SPEED_1000MBPS;
4485 CurrentDuplexMode = LM_DUPLEX_MODE_FULL;
4490 CurrentLineSpeed = LM_LINE_SPEED_UNKNOWN;
4491 CurrentDuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4495 /* Make sure we are in auto-neg mode. */
4496 for (j = 0; j < 200; j++)
4498 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4499 if(Value32 && Value32 != 0x7fff)
4504 if(Value32 == 0 && pDevice->RequestedMediaType ==
4505 LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS)
4513 /* Use the current line settings for "auto" mode. */
4514 if(pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
4515 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
4517 if(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)
4519 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4521 /* We may be exiting low power mode and the link is in */
4522 /* 10mb. In this case, we need to restart autoneg. */
4523 LM_ReadPhy(pDevice, BCM540X_1000BASET_CTRL_REG, &Value32);
4524 pDevice->advertising1000 = Value32;
4525 /* 5702FE supports 10/100Mb only. */
4526 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5703 ||
4527 pDevice->BondId != GRC_MISC_BD_ID_5702FE)
4529 if(!(Value32 & (BCM540X_AN_AD_1000BASET_HALF |
4530 BCM540X_AN_AD_1000BASET_FULL)))
4532 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4538 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4543 /* Force line settings. */
4544 /* Use the current setting if it matches the user's requested */
4546 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
4547 if((pDevice->LineSpeed == CurrentLineSpeed) &&
4548 (pDevice->DuplexMode == CurrentDuplexMode))
4550 if ((pDevice->DisableAutoNeg &&
4551 !(Value32 & PHY_CTRL_AUTO_NEG_ENABLE)) ||
4552 (!pDevice->DisableAutoNeg &&
4553 (Value32 & PHY_CTRL_AUTO_NEG_ENABLE)))
4555 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4559 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4564 CurrentLinkStatus = LM_STATUS_LINK_SETTING_MISMATCH;
4568 /* Save line settings. */
4569 pDevice->LineSpeed = CurrentLineSpeed;
4570 pDevice->DuplexMode = CurrentDuplexMode;
4571 pDevice->MediaType = LM_MEDIA_TYPE_UTP;
4574 return CurrentLinkStatus;
4575 } /* LM_InitBcm540xPhy */
4577 /******************************************************************************/
4581 /******************************************************************************/
4584 PLM_DEVICE_BLOCK pDevice,
4585 LM_UINT32 LocalPhyAd,
4586 LM_UINT32 RemotePhyAd)
4588 LM_FLOW_CONTROL FlowCap;
4590 /* Resolve flow control. */
4591 FlowCap = LM_FLOW_CONTROL_NONE;
4593 /* See Table 28B-3 of 802.3ab-1999 spec. */
4594 if(pDevice->FlowControlCap & LM_FLOW_CONTROL_AUTO_PAUSE)
4596 if(LocalPhyAd & PHY_AN_AD_PAUSE_CAPABLE)
4598 if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
4600 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
4602 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4603 LM_FLOW_CONTROL_RECEIVE_PAUSE;
4605 else if(RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE)
4607 FlowCap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
4612 if(RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE)
4614 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE |
4615 LM_FLOW_CONTROL_RECEIVE_PAUSE;
4619 else if(LocalPhyAd & PHY_AN_AD_ASYM_PAUSE)
4621 if((RemotePhyAd & PHY_LINK_PARTNER_PAUSE_CAPABLE) &&
4622 (RemotePhyAd & PHY_LINK_PARTNER_ASYM_PAUSE))
4624 FlowCap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4630 FlowCap = pDevice->FlowControlCap;
4633 /* Enable/disable rx PAUSE. */
4634 pDevice->RxMode &= ~RX_MODE_ENABLE_FLOW_CONTROL;
4635 if(FlowCap & LM_FLOW_CONTROL_RECEIVE_PAUSE &&
4636 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4637 pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE))
4639 pDevice->FlowControl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
4640 pDevice->RxMode |= RX_MODE_ENABLE_FLOW_CONTROL;
4643 REG_WR(pDevice, MacCtrl.RxMode, pDevice->RxMode);
4645 /* Enable/disable tx PAUSE. */
4646 pDevice->TxMode &= ~TX_MODE_ENABLE_FLOW_CONTROL;
4647 if(FlowCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE &&
4648 (pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE ||
4649 pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE))
4651 pDevice->FlowControl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
4652 pDevice->TxMode |= TX_MODE_ENABLE_FLOW_CONTROL;
4655 REG_WR(pDevice, MacCtrl.TxMode, pDevice->TxMode);
4657 return LM_STATUS_SUCCESS;
4661 #if INCLUDE_TBI_SUPPORT
4662 /******************************************************************************/
4666 /******************************************************************************/
4669 PLM_DEVICE_BLOCK pDevice)
4674 Value32 = REG_RD(pDevice, MacCtrl.Status);
4676 /* Reset the SERDES during init and when we have link. */
4677 if(!pDevice->InitDone || Value32 & MAC_STATUS_PCS_SYNCED)
4679 /* Set PLL lock range. */
4680 LM_WritePhy(pDevice, 0x16, 0x8007);
4682 /* Software reset. */
4683 LM_WritePhy(pDevice, 0x00, 0x8000);
4685 /* Wait for reset to complete. */
4686 for(j = 0; j < 500; j++)
4691 /* Config mode; seletct PMA/Ch 1 regs. */
4692 LM_WritePhy(pDevice, 0x10, 0x8411);
4694 /* Enable auto-lock and comdet, select txclk for tx. */
4695 LM_WritePhy(pDevice, 0x11, 0x0a10);
4697 LM_WritePhy(pDevice, 0x18, 0x00a0);
4698 LM_WritePhy(pDevice, 0x16, 0x41ff);
4700 /* Assert and deassert POR. */
4701 LM_WritePhy(pDevice, 0x13, 0x0400);
4703 LM_WritePhy(pDevice, 0x13, 0x0000);
4705 LM_WritePhy(pDevice, 0x11, 0x0a50);
4707 LM_WritePhy(pDevice, 0x11, 0x0a10);
4709 /* Delay for signal to stabilize. */
4710 for(j = 0; j < 15000; j++)
4715 /* Deselect the channel register so we can read the PHY id later. */
4716 LM_WritePhy(pDevice, 0x10, 0x8011);
4719 return LM_STATUS_SUCCESS;
4724 /******************************************************************************/
4728 /******************************************************************************/
4731 PLM_DEVICE_BLOCK pDevice)
4733 LM_STATUS CurrentLinkStatus;
4734 AUTONEG_STATUS AnStatus = 0;
4739 pDevice->MacMode &= ~(MAC_MODE_HALF_DUPLEX | MAC_MODE_PORT_MODE_MASK);
4741 /* Initialize the send_config register. */
4742 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
4744 /* Enable TBI and full duplex mode. */
4745 pDevice->MacMode |= MAC_MODE_PORT_MODE_TBI;
4746 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4748 /* Initialize the BCM8002 SERDES PHY. */
4749 switch(pDevice->PhyId & PHY_ID_MASK)
4751 case PHY_BCM8002_PHY_ID:
4752 LM_InitBcm800xPhy(pDevice);
4759 /* Enable link change interrupt. */
4760 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
4762 /* Default to link down. */
4763 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4765 /* Get the link status. */
4766 Value32 = REG_RD(pDevice, MacCtrl.Status);
4767 if(Value32 & MAC_STATUS_PCS_SYNCED)
4769 if((pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO) ||
4770 (pDevice->DisableAutoNeg == FALSE))
4772 /* auto-negotiation mode. */
4773 /* Initialize the autoneg default capaiblities. */
4774 AutonegInit(&pDevice->AnInfo);
4776 /* Set the context pointer to point to the main device structure. */
4777 pDevice->AnInfo.pContext = pDevice;
4779 /* Setup flow control advertisement register. */
4780 Value32 = GetPhyAdFlowCntrlSettings(pDevice);
4781 if(Value32 & PHY_AN_AD_PAUSE_CAPABLE)
4783 pDevice->AnInfo.mr_adv_sym_pause = 1;
4787 pDevice->AnInfo.mr_adv_sym_pause = 0;
4790 if(Value32 & PHY_AN_AD_ASYM_PAUSE)
4792 pDevice->AnInfo.mr_adv_asym_pause = 1;
4796 pDevice->AnInfo.mr_adv_asym_pause = 0;
4799 /* Try to autoneg up to six times. */
4800 if (pDevice->IgnoreTbiLinkChange)
4808 for (j = 0; j < Cnt; j++)
4810 REG_WR(pDevice, MacCtrl.TxAutoNeg, 0);
4812 Value32 = pDevice->MacMode & ~MAC_MODE_PORT_MODE_MASK;
4813 REG_WR(pDevice, MacCtrl.Mode, Value32);
4816 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4817 MAC_MODE_SEND_CONFIGS);
4821 pDevice->AnInfo.State = AN_STATE_UNKNOWN;
4822 pDevice->AnInfo.CurrentTime_us = 0;
4824 REG_WR(pDevice, Grc.Timer, 0);
4825 for(k = 0; (pDevice->AnInfo.CurrentTime_us < 75000) &&
4828 AnStatus = Autoneg8023z(&pDevice->AnInfo);
4830 if((AnStatus == AUTONEG_STATUS_DONE) ||
4831 (AnStatus == AUTONEG_STATUS_FAILED))
4836 pDevice->AnInfo.CurrentTime_us = REG_RD(pDevice, Grc.Timer);
4839 if((AnStatus == AUTONEG_STATUS_DONE) ||
4840 (AnStatus == AUTONEG_STATUS_FAILED))
4846 if (!(REG_RD(pDevice, MacCtrl.Status) &
4847 MAC_STATUS_PCS_SYNCED)) {
4853 /* Stop sending configs. */
4854 MM_AnTxIdle(&pDevice->AnInfo);
4856 /* Resolve flow control settings. */
4857 if((AnStatus == AUTONEG_STATUS_DONE) &&
4858 pDevice->AnInfo.mr_an_complete && pDevice->AnInfo.mr_link_ok &&
4859 pDevice->AnInfo.mr_lp_adv_full_duplex)
4861 LM_UINT32 RemotePhyAd;
4862 LM_UINT32 LocalPhyAd;
4865 if(pDevice->AnInfo.mr_adv_sym_pause)
4867 LocalPhyAd |= PHY_AN_AD_PAUSE_CAPABLE;
4870 if(pDevice->AnInfo.mr_adv_asym_pause)
4872 LocalPhyAd |= PHY_AN_AD_ASYM_PAUSE;
4876 if(pDevice->AnInfo.mr_lp_adv_sym_pause)
4878 RemotePhyAd |= PHY_LINK_PARTNER_PAUSE_CAPABLE;
4881 if(pDevice->AnInfo.mr_lp_adv_asym_pause)
4883 RemotePhyAd |= PHY_LINK_PARTNER_ASYM_PAUSE;
4886 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
4888 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4890 for (j = 0; j < 30; j++)
4893 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4894 MAC_STATUS_CFG_CHANGED);
4896 if ((REG_RD(pDevice, MacCtrl.Status) &
4897 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4900 if (pDevice->PollTbiLink)
4902 Value32 = REG_RD(pDevice, MacCtrl.Status);
4903 if (Value32 & MAC_STATUS_RECEIVING_CFG)
4905 pDevice->IgnoreTbiLinkChange = TRUE;
4909 pDevice->IgnoreTbiLinkChange = FALSE;
4912 Value32 = REG_RD(pDevice, MacCtrl.Status);
4913 if (CurrentLinkStatus == LM_STATUS_LINK_DOWN &&
4914 (Value32 & MAC_STATUS_PCS_SYNCED) &&
4915 ((Value32 & MAC_STATUS_RECEIVING_CFG) == 0))
4917 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4922 /* We are forcing line speed. */
4923 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
4924 LM_SetFlowControl(pDevice, 0, 0);
4926 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
4927 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4928 MAC_MODE_SEND_CONFIGS);
4931 /* Set the link polarity bit. */
4932 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
4933 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4935 pDevice->pStatusBlkVirt->Status = STATUS_BLOCK_UPDATED |
4936 (pDevice->pStatusBlkVirt->Status & ~STATUS_BLOCK_LINK_CHANGED_STATUS);
4938 for (j = 0; j < 100; j++)
4940 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
4941 MAC_STATUS_CFG_CHANGED);
4943 if ((REG_RD(pDevice, MacCtrl.Status) &
4944 (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED)) == 0)
4948 Value32 = REG_RD(pDevice, MacCtrl.Status);
4949 if((Value32 & MAC_STATUS_PCS_SYNCED) == 0)
4951 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
4952 if (pDevice->DisableAutoNeg == FALSE)
4954 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode |
4955 MAC_MODE_SEND_CONFIGS);
4957 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
4961 /* Initialize the current link status. */
4962 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
4964 pDevice->LineSpeed = LM_LINE_SPEED_1000MBPS;
4965 pDevice->DuplexMode = LM_DUPLEX_MODE_FULL;
4966 REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4967 LED_CTRL_1000MBPS_LED_ON);
4971 pDevice->LineSpeed = LM_LINE_SPEED_UNKNOWN;
4972 pDevice->DuplexMode = LM_DUPLEX_MODE_UNKNOWN;
4973 REG_WR(pDevice, MacCtrl.LedCtrl, LED_CTRL_OVERRIDE_LINK_LED |
4974 LED_CTRL_OVERRIDE_TRAFFIC_LED);
4977 /* Indicate link status. */
4978 if (pDevice->LinkStatus != CurrentLinkStatus) {
4979 pDevice->LinkStatus = CurrentLinkStatus;
4980 MM_IndicateStatus(pDevice, CurrentLinkStatus);
4983 return LM_STATUS_SUCCESS;
4985 #endif /* INCLUDE_TBI_SUPPORT */
4988 /******************************************************************************/
4992 /******************************************************************************/
4995 PLM_DEVICE_BLOCK pDevice)
4997 LM_STATUS CurrentLinkStatus;
5000 /* Assume there is not link first. */
5001 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5003 /* Disable phy link change attention. */
5004 REG_WR(pDevice, MacCtrl.MacEvent, 0);
5006 /* Clear link change attention. */
5007 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5008 MAC_STATUS_CFG_CHANGED);
5010 /* Disable auto-polling for the moment. */
5011 pDevice->MiMode = 0xc0000;
5012 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5015 /* Determine the requested line speed and duplex. */
5016 pDevice->OldLineSpeed = pDevice->LineSpeed;
5017 LM_TranslateRequestedMediaType(pDevice->RequestedMediaType,
5018 &pDevice->MediaType, &pDevice->LineSpeed, &pDevice->DuplexMode);
5020 /* Initialize the phy chip. */
5021 switch(pDevice->PhyId & PHY_ID_MASK)
5023 case PHY_BCM5400_PHY_ID:
5024 case PHY_BCM5401_PHY_ID:
5025 case PHY_BCM5411_PHY_ID:
5026 case PHY_BCM5701_PHY_ID:
5027 case PHY_BCM5703_PHY_ID:
5028 case PHY_BCM5704_PHY_ID:
5029 CurrentLinkStatus = LM_InitBcm540xPhy(pDevice);
5036 if(CurrentLinkStatus == LM_STATUS_LINK_SETTING_MISMATCH)
5038 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5041 /* Setup flow control. */
5042 pDevice->FlowControl = LM_FLOW_CONTROL_NONE;
5043 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5045 LM_FLOW_CONTROL FlowCap; /* Flow control capability. */
5047 FlowCap = LM_FLOW_CONTROL_NONE;
5049 if(pDevice->DuplexMode == LM_DUPLEX_MODE_FULL)
5051 if(pDevice->DisableAutoNeg == FALSE ||
5052 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5053 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
5055 LM_UINT32 ExpectedPhyAd;
5056 LM_UINT32 LocalPhyAd;
5057 LM_UINT32 RemotePhyAd;
5059 LM_ReadPhy(pDevice, PHY_AN_AD_REG, &LocalPhyAd);
5060 pDevice->advertising = LocalPhyAd;
5061 LocalPhyAd &= (PHY_AN_AD_ASYM_PAUSE | PHY_AN_AD_PAUSE_CAPABLE);
5063 ExpectedPhyAd = GetPhyAdFlowCntrlSettings(pDevice);
5065 if(LocalPhyAd != ExpectedPhyAd)
5067 CurrentLinkStatus = LM_STATUS_LINK_DOWN;
5071 LM_ReadPhy(pDevice, PHY_LINK_PARTNER_ABILITY_REG,
5074 LM_SetFlowControl(pDevice, LocalPhyAd, RemotePhyAd);
5079 pDevice->FlowControlCap &= ~LM_FLOW_CONTROL_AUTO_PAUSE;
5080 LM_SetFlowControl(pDevice, 0, 0);
5085 if(CurrentLinkStatus == LM_STATUS_LINK_DOWN)
5087 LM_ForceAutoNeg(pDevice, pDevice->RequestedMediaType);
5089 /* If we force line speed, we make get link right away. */
5090 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5091 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5092 if(Value32 & PHY_STATUS_LINK_PASS)
5094 CurrentLinkStatus = LM_STATUS_LINK_ACTIVE;
5098 /* GMII interface. */
5099 pDevice->MacMode &= ~MAC_MODE_PORT_MODE_MASK;
5100 if(CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5102 if(pDevice->LineSpeed == LM_LINE_SPEED_100MBPS ||
5103 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS)
5105 pDevice->MacMode |= MAC_MODE_PORT_MODE_MII;
5109 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5113 pDevice->MacMode |= MAC_MODE_PORT_MODE_GMII;
5116 /* Set the MAC to operate in the appropriate duplex mode. */
5117 pDevice->MacMode &= ~MAC_MODE_HALF_DUPLEX;
5118 if(pDevice->DuplexMode == LM_DUPLEX_MODE_HALF)
5120 pDevice->MacMode |= MAC_MODE_HALF_DUPLEX;
5123 /* Set the link polarity bit. */
5124 pDevice->MacMode &= ~MAC_MODE_LINK_POLARITY;
5125 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5127 if((pDevice->LedMode == LED_MODE_LINK10) ||
5128 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE &&
5129 pDevice->LineSpeed == LM_LINE_SPEED_10MBPS))
5131 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5136 if (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE)
5138 pDevice->MacMode |= MAC_MODE_LINK_POLARITY;
5142 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5143 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5145 Value32 = LED_CTRL_PHY_MODE_1;
5149 if(pDevice->LedMode == LED_MODE_OUTPUT)
5151 Value32 = LED_CTRL_PHY_MODE_2;
5155 Value32 = LED_CTRL_PHY_MODE_1;
5158 REG_WR(pDevice, MacCtrl.LedCtrl, Value32);
5161 REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
5163 /* Enable auto polling. */
5164 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5166 pDevice->MiMode |= MI_MODE_AUTO_POLLING_ENABLE;
5167 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5170 /* Enable phy link change attention. */
5171 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_MI_INTERRUPT)
5173 REG_WR(pDevice, MacCtrl.MacEvent, MAC_EVENT_ENABLE_MI_INTERRUPT);
5177 REG_WR(pDevice, MacCtrl.MacEvent,
5178 MAC_EVENT_ENABLE_LINK_STATE_CHANGED_ATTN);
5180 if ((T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700) &&
5181 (CurrentLinkStatus == LM_STATUS_LINK_ACTIVE) &&
5182 (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
5183 (((pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE) &&
5184 (pDevice->PciState & T3_PCI_STATE_BUS_SPEED_HIGH)) ||
5185 !(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE)))
5188 REG_WR(pDevice, MacCtrl.Status, MAC_STATUS_SYNC_CHANGED |
5189 MAC_STATUS_CFG_CHANGED);
5190 MEM_WR_OFFSET(pDevice, T3_FIRMWARE_MAILBOX,
5191 T3_MAGIC_NUM_DISABLE_DMAW_ON_LINK_CHANGE);
5194 /* Indicate link status. */
5195 if (pDevice->LinkStatus != CurrentLinkStatus) {
5196 pDevice->LinkStatus = CurrentLinkStatus;
5197 MM_IndicateStatus(pDevice, CurrentLinkStatus);
5200 return LM_STATUS_SUCCESS;
5201 } /* LM_SetupCopperPhy */
5203 /******************************************************************************/
5207 /******************************************************************************/
5210 PLM_DEVICE_BLOCK pDevice)
5215 #if INCLUDE_TBI_SUPPORT
5216 if(pDevice->EnableTbi)
5218 LmStatus = LM_SetupFiberPhy(pDevice);
5221 #endif /* INCLUDE_TBI_SUPPORT */
5223 LmStatus = LM_SetupCopperPhy(pDevice);
5225 if (pDevice->ChipRevId == T3_CHIP_ID_5704_A0)
5227 if (!(pDevice->PciState & T3_PCI_STATE_CONVENTIONAL_PCI_MODE))
5229 Value32 = REG_RD(pDevice, PciCfg.PciState);
5230 REG_WR(pDevice, PciCfg.PciState,
5231 Value32 | T3_PCI_STATE_RETRY_SAME_DMA);
5234 if ((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) &&
5235 (pDevice->DuplexMode == LM_DUPLEX_MODE_HALF))
5237 REG_WR(pDevice, MacCtrl.TxLengths, 0x26ff);
5241 REG_WR(pDevice, MacCtrl.TxLengths, 0x2620);
5247 /******************************************************************************/
5251 /******************************************************************************/
5254 PLM_DEVICE_BLOCK pDevice,
5256 PLM_UINT32 pData32) {
5260 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5262 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
5263 ~MI_MODE_AUTO_POLLING_ENABLE);
5267 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
5268 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
5269 MI_COM_CMD_READ | MI_COM_START;
5271 REG_WR(pDevice, MacCtrl.MiCom, Value32);
5273 for(j = 0; j < 20; j++)
5277 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5279 if(!(Value32 & MI_COM_BUSY))
5282 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5283 Value32 &= MI_COM_PHY_DATA_MASK;
5288 if(Value32 & MI_COM_BUSY)
5295 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5297 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5304 /******************************************************************************/
5308 /******************************************************************************/
5311 PLM_DEVICE_BLOCK pDevice,
5317 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5319 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode &
5320 ~MI_MODE_AUTO_POLLING_ENABLE);
5324 Value32 = (pDevice->PhyAddr << MI_COM_FIRST_PHY_ADDR_BIT) |
5325 ((PhyReg & MI_COM_PHY_REG_ADDR_MASK) << MI_COM_FIRST_PHY_REG_ADDR_BIT) |
5326 (Data32 & MI_COM_PHY_DATA_MASK) | MI_COM_CMD_WRITE | MI_COM_START;
5328 REG_WR(pDevice, MacCtrl.MiCom, Value32);
5330 for(j = 0; j < 20; j++)
5334 Value32 = REG_RD(pDevice, MacCtrl.MiCom);
5336 if(!(Value32 & MI_COM_BUSY))
5343 if(pDevice->PhyIntMode == T3_PHY_INT_MODE_AUTO_POLLING)
5345 REG_WR(pDevice, MacCtrl.MiMode, pDevice->MiMode);
5351 /******************************************************************************/
5355 /******************************************************************************/
5358 PLM_DEVICE_BLOCK pDevice,
5359 LM_POWER_STATE PowerLevel) {
5360 LM_UINT32 PmeSupport;
5364 /* make sureindirect accesses are enabled*/
5365 MM_WriteConfig32(pDevice, T3_PCI_MISC_HOST_CTRL_REG, pDevice->MiscHostCtrl);
5367 /* Clear the PME_ASSERT bit and the power state bits. Also enable */
5369 MM_ReadConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, &PmCtrl);
5371 PmCtrl |= T3_PM_PME_ASSERTED;
5372 PmCtrl &= ~T3_PM_POWER_STATE_MASK;
5374 /* Set the appropriate power state. */
5375 if(PowerLevel == LM_POWER_STATE_D0)
5378 /* Bring the card out of low power mode. */
5379 PmCtrl |= T3_PM_POWER_STATE_D0;
5380 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5382 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl);
5384 #if 0 /* Bugfix by jmb...can't call WritePhy here because pDevice not fully initialized */
5385 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x02);
5388 return LM_STATUS_SUCCESS;
5390 else if(PowerLevel == LM_POWER_STATE_D1)
5392 PmCtrl |= T3_PM_POWER_STATE_D1;
5394 else if(PowerLevel == LM_POWER_STATE_D2)
5396 PmCtrl |= T3_PM_POWER_STATE_D2;
5398 else if(PowerLevel == LM_POWER_STATE_D3)
5400 PmCtrl |= T3_PM_POWER_STATE_D3;
5404 return LM_STATUS_FAILURE;
5406 PmCtrl |= T3_PM_PME_ENABLE;
5408 /* Mask out all interrupts so LM_SetupPhy won't be called while we are */
5409 /* setting new line speed. */
5410 Value32 = REG_RD(pDevice, PciCfg.MiscHostCtrl);
5411 REG_WR(pDevice, PciCfg.MiscHostCtrl, Value32 | MISC_HOST_CTRL_MASK_PCI_INT);
5413 if(!pDevice->RestoreOnWakeUp)
5415 pDevice->RestoreOnWakeUp = TRUE;
5416 pDevice->WakeUpDisableAutoNeg = pDevice->DisableAutoNeg;
5417 pDevice->WakeUpRequestedMediaType = pDevice->RequestedMediaType;
5420 /* Force auto-negotiation to 10 line speed. */
5421 pDevice->DisableAutoNeg = FALSE;
5422 pDevice->RequestedMediaType = LM_REQUESTED_MEDIA_TYPE_UTP_10MBPS;
5423 LM_SetupPhy(pDevice);
5425 /* Put the driver in the initial state, and go through the power down */
5429 MM_ReadConfig32(pDevice, T3_PCI_PM_CAP_REG, &PmeSupport);
5431 if (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE)
5435 LM_WritePhy(pDevice, BCM5401_AUX_CTRL, 0x5a);
5439 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5440 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5442 Value32 = LED_CTRL_PHY_MODE_1;
5446 if(pDevice->LedMode == LED_MODE_OUTPUT)
5448 Value32 = LED_CTRL_PHY_MODE_2;
5452 Value32 = LED_CTRL_PHY_MODE_1;
5456 Value32 = MAC_MODE_PORT_MODE_MII;
5457 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700)
5459 if(pDevice->LedMode == LED_MODE_LINK10 ||
5460 pDevice->WolSpeed == WOL_SPEED_10MB)
5462 Value32 |= MAC_MODE_LINK_POLARITY;
5467 Value32 |= MAC_MODE_LINK_POLARITY;
5469 REG_WR(pDevice, MacCtrl.Mode, Value32);
5470 MM_Wait(40); MM_Wait(40); MM_Wait(40);
5472 /* Always enable magic packet wake-up if we have vaux. */
5473 if((PmeSupport & T3_PCI_PM_CAP_PME_D3COLD) &&
5474 (pDevice->WakeUpModeCap & LM_WAKE_UP_MODE_MAGIC_PACKET))
5476 Value32 |= MAC_MODE_DETECT_MAGIC_PACKET_ENABLE;
5479 REG_WR(pDevice, MacCtrl.Mode, Value32);
5481 /* Enable the receiver. */
5482 REG_WR(pDevice, MacCtrl.RxMode, RX_MODE_ENABLE);
5485 /* Disable tx/rx clocks, and seletect an alternate clock. */
5486 if(pDevice->WolSpeed == WOL_SPEED_100MB)
5488 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5489 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5491 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5492 T3_PCI_SELECT_ALTERNATE_CLOCK;
5496 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK;
5498 REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5502 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5503 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5505 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5506 T3_PCI_SELECT_ALTERNATE_CLOCK | T3_PCI_44MHZ_CORE_CLOCK;
5510 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5511 T3_PCI_44MHZ_CORE_CLOCK;
5514 REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5518 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5519 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5521 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5522 T3_PCI_44MHZ_CORE_CLOCK;
5526 Value32 = T3_PCI_44MHZ_CORE_CLOCK;
5529 REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5533 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5534 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5536 Value32 = T3_PCI_DISABLE_RX_CLOCK | T3_PCI_DISABLE_TX_CLOCK |
5537 T3_PCI_SELECT_ALTERNATE_CLOCK |
5538 T3_PCI_POWER_DOWN_PCI_PLL133;
5542 Value32 = T3_PCI_SELECT_ALTERNATE_CLOCK |
5543 T3_PCI_POWER_DOWN_PCI_PLL133;
5546 REG_WR(pDevice, PciCfg.ClockCtrl, Value32);
5551 if(!pDevice->EepromWp && (pDevice->WakeUpModeCap != LM_WAKE_UP_MODE_NONE))
5553 /* Switch adapter to auxilliary power. */
5554 if(T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5700 ||
5555 T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5701)
5557 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5558 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5559 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5560 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5561 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5562 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5563 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5568 /* GPIO0 = 0, GPIO1 = 1, GPIO2 = 1. */
5569 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5570 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5571 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5572 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5573 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5574 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5577 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 1. */
5578 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5579 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5580 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5581 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5582 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5583 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1 |
5584 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT2);
5587 /* GPIO0 = 1, GPIO1 = 1, GPIO2 = 0. */
5588 REG_WR(pDevice, Grc.LocalCtrl, pDevice->GrcLocalCtrl |
5589 GRC_MISC_LOCAL_CTRL_GPIO_OE0 |
5590 GRC_MISC_LOCAL_CTRL_GPIO_OE1 |
5591 GRC_MISC_LOCAL_CTRL_GPIO_OE2 |
5592 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT0 |
5593 GRC_MISC_LOCAL_CTRL_GPIO_OUTPUT1);
5598 /* Set the phy to low power mode. */
5599 /* Put the the hardware in low power mode. */
5600 MM_WriteConfig32(pDevice, T3_PCI_PM_STATUS_CTRL_REG, PmCtrl);
5602 return LM_STATUS_SUCCESS;
5603 } /* LM_SetPowerState */
5607 /******************************************************************************/
5611 /******************************************************************************/
5613 GetPhyAdFlowCntrlSettings(
5614 PLM_DEVICE_BLOCK pDevice)
5620 /* Auto negotiation flow control only when autonegotiation is enabled. */
5621 if(pDevice->DisableAutoNeg == FALSE ||
5622 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_AUTO ||
5623 pDevice->RequestedMediaType == LM_REQUESTED_MEDIA_TYPE_UTP_AUTO)
5625 /* Please refer to Table 28B-3 of the 802.3ab-1999 spec. */
5626 if((pDevice->FlowControlCap == LM_FLOW_CONTROL_AUTO_PAUSE) ||
5627 ((pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE) &&
5628 (pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)))
5630 Value32 |= PHY_AN_AD_PAUSE_CAPABLE;
5632 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
5634 Value32 |= PHY_AN_AD_ASYM_PAUSE;
5636 else if(pDevice->FlowControlCap & LM_FLOW_CONTROL_RECEIVE_PAUSE)
5638 Value32 |= PHY_AN_AD_PAUSE_CAPABLE | PHY_AN_AD_ASYM_PAUSE;
5647 /******************************************************************************/
5651 /* LM_STATUS_FAILURE */
5652 /* LM_STATUS_SUCCESS */
5654 /******************************************************************************/
5656 LM_ForceAutoNegBcm540xPhy(
5657 PLM_DEVICE_BLOCK pDevice,
5658 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5660 LM_MEDIA_TYPE MediaType;
5661 LM_LINE_SPEED LineSpeed;
5662 LM_DUPLEX_MODE DuplexMode;
5663 LM_UINT32 NewPhyCtrl;
5667 /* Get the interface type, line speed, and duplex mode. */
5668 LM_TranslateRequestedMediaType(RequestedMediaType, &MediaType, &LineSpeed,
5671 if (pDevice->RestoreOnWakeUp)
5673 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5674 pDevice->advertising1000 = 0;
5675 Value32 = PHY_AN_AD_10BASET_FULL | PHY_AN_AD_10BASET_HALF;
5676 if (pDevice->WolSpeed == WOL_SPEED_100MB)
5678 Value32 |= PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5680 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5681 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5682 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5683 pDevice->advertising = Value32;
5685 /* Setup the auto-negotiation advertisement register. */
5686 else if(LineSpeed == LM_LINE_SPEED_UNKNOWN)
5688 /* Setup the 10/100 Mbps auto-negotiation advertisement register. */
5689 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD |
5690 PHY_AN_AD_10BASET_HALF | PHY_AN_AD_10BASET_FULL |
5691 PHY_AN_AD_100BASETX_FULL | PHY_AN_AD_100BASETX_HALF;
5692 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5694 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5695 pDevice->advertising = Value32;
5697 /* Advertise 1000Mbps */
5698 Value32 = BCM540X_AN_AD_1000BASET_HALF | BCM540X_AN_AD_1000BASET_FULL;
5700 #if INCLUDE_5701_AX_FIX
5701 /* Bug: workaround for CRC error in gigabit mode when we are in */
5702 /* slave mode. This will force the PHY to operate in */
5704 if(pDevice->ChipRevId == T3_CHIP_ID_5701_A0 ||
5705 pDevice->ChipRevId == T3_CHIP_ID_5701_B0)
5707 Value32 |= BCM540X_CONFIG_AS_MASTER |
5708 BCM540X_ENABLE_CONFIG_AS_MASTER;
5712 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5713 pDevice->advertising1000 = Value32;
5717 if(LineSpeed == LM_LINE_SPEED_1000MBPS)
5719 Value32 = PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5720 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5722 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5723 pDevice->advertising = Value32;
5725 if(DuplexMode != LM_DUPLEX_MODE_FULL)
5727 Value32 = BCM540X_AN_AD_1000BASET_HALF;
5731 Value32 = BCM540X_AN_AD_1000BASET_FULL;
5734 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, Value32);
5735 pDevice->advertising1000 = Value32;
5737 else if(LineSpeed == LM_LINE_SPEED_100MBPS)
5739 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5740 pDevice->advertising1000 = 0;
5742 if(DuplexMode != LM_DUPLEX_MODE_FULL)
5744 Value32 = PHY_AN_AD_100BASETX_HALF;
5748 Value32 = PHY_AN_AD_100BASETX_FULL;
5751 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5752 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5754 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5755 pDevice->advertising = Value32;
5757 else if(LineSpeed == LM_LINE_SPEED_10MBPS)
5759 LM_WritePhy(pDevice, BCM540X_1000BASET_CTRL_REG, 0);
5760 pDevice->advertising1000 = 0;
5762 if(DuplexMode != LM_DUPLEX_MODE_FULL)
5764 Value32 = PHY_AN_AD_10BASET_HALF;
5768 Value32 = PHY_AN_AD_10BASET_FULL;
5771 Value32 |= PHY_AN_AD_PROTOCOL_802_3_CSMA_CD;
5772 Value32 |= GetPhyAdFlowCntrlSettings(pDevice);
5774 LM_WritePhy(pDevice, PHY_AN_AD_REG, Value32);
5775 pDevice->advertising = Value32;
5779 /* Force line speed if auto-negotiation is disabled. */
5780 if(pDevice->DisableAutoNeg && LineSpeed != LM_LINE_SPEED_UNKNOWN)
5782 /* This code path is executed only when there is link. */
5783 pDevice->MediaType = MediaType;
5784 pDevice->LineSpeed = LineSpeed;
5785 pDevice->DuplexMode = DuplexMode;
5787 /* Force line seepd. */
5791 case LM_LINE_SPEED_10MBPS:
5792 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_10MBPS;
5794 case LM_LINE_SPEED_100MBPS:
5795 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_100MBPS;
5797 case LM_LINE_SPEED_1000MBPS:
5798 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5801 NewPhyCtrl |= PHY_CTRL_SPEED_SELECT_1000MBPS;
5805 if(DuplexMode == LM_DUPLEX_MODE_FULL)
5807 NewPhyCtrl |= PHY_CTRL_FULL_DUPLEX_MODE;
5810 /* Don't do anything if the PHY_CTRL is already what we wanted. */
5811 LM_ReadPhy(pDevice, PHY_CTRL_REG, &Value32);
5812 if(Value32 != NewPhyCtrl)
5814 /* Temporary bring the link down before forcing line speed. */
5815 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_LOOPBACK_MODE);
5817 /* Wait for link to go down. */
5818 for(Cnt = 0; Cnt < 15000; Cnt++)
5822 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5823 LM_ReadPhy(pDevice, PHY_STATUS_REG, &Value32);
5825 if(!(Value32 & PHY_STATUS_LINK_PASS))
5832 LM_WritePhy(pDevice, PHY_CTRL_REG, NewPhyCtrl);
5838 LM_WritePhy(pDevice, PHY_CTRL_REG, PHY_CTRL_AUTO_NEG_ENABLE |
5839 PHY_CTRL_RESTART_AUTO_NEG);
5842 return LM_STATUS_SUCCESS;
5843 } /* LM_ForceAutoNegBcm540xPhy */
5847 /******************************************************************************/
5851 /******************************************************************************/
5854 PLM_DEVICE_BLOCK pDevice,
5855 LM_REQUESTED_MEDIA_TYPE RequestedMediaType)
5859 /* Initialize the phy chip. */
5860 switch(pDevice->PhyId & PHY_ID_MASK)
5862 case PHY_BCM5400_PHY_ID:
5863 case PHY_BCM5401_PHY_ID:
5864 case PHY_BCM5411_PHY_ID:
5865 case PHY_BCM5701_PHY_ID:
5866 case PHY_BCM5703_PHY_ID:
5867 case PHY_BCM5704_PHY_ID:
5868 LmStatus = LM_ForceAutoNegBcm540xPhy(pDevice, RequestedMediaType);
5872 LmStatus = LM_STATUS_FAILURE;
5877 } /* LM_ForceAutoNeg */
5879 /******************************************************************************/
5883 /******************************************************************************/
5884 LM_STATUS LM_LoadFirmware(PLM_DEVICE_BLOCK pDevice,
5885 PT3_FWIMG_INFO pFwImg,
5892 if (LoadCpu & T3_RX_CPU_ID)
5894 if (LM_HaltCpu(pDevice,T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
5896 return LM_STATUS_FAILURE;
5899 /* First of all clear scrach pad memory */
5900 for (i = 0; i < T3_RX_CPU_SPAD_SIZE; i+=4)
5902 LM_RegWrInd(pDevice,T3_RX_CPU_SPAD_ADDR+i,0);
5905 /* Copy code first */
5906 address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5907 for (i = 0; i <= pFwImg->Text.Length; i+=4)
5909 LM_RegWrInd(pDevice,address+i,
5910 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
5913 address = T3_RX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5914 for (i = 0; i <= pFwImg->ROnlyData.Length; i+=4)
5916 LM_RegWrInd(pDevice,address+i,
5917 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
5920 address = T3_RX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5921 for (i= 0; i <= pFwImg->Data.Length; i+=4)
5923 LM_RegWrInd(pDevice,address+i,
5924 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
5928 if (LoadCpu & T3_TX_CPU_ID)
5930 if (LM_HaltCpu(pDevice,T3_TX_CPU_ID) != LM_STATUS_SUCCESS)
5932 return LM_STATUS_FAILURE;
5935 /* First of all clear scrach pad memory */
5936 for (i = 0; i < T3_TX_CPU_SPAD_SIZE; i+=4)
5938 LM_RegWrInd(pDevice,T3_TX_CPU_SPAD_ADDR+i,0);
5941 /* Copy code first */
5942 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Text.Offset & 0xffff);
5943 for (i= 0; i <= pFwImg->Text.Length; i+=4)
5945 LM_RegWrInd(pDevice,address+i,
5946 ((LM_UINT32 *)pFwImg->Text.Buffer)[i/4]);
5949 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->ROnlyData.Offset & 0xffff);
5950 for (i= 0; i <= pFwImg->ROnlyData.Length; i+=4)
5952 LM_RegWrInd(pDevice,address+i,
5953 ((LM_UINT32 *)pFwImg->ROnlyData.Buffer)[i/4]);
5956 address = T3_TX_CPU_SPAD_ADDR + (pFwImg->Data.Offset & 0xffff);
5957 for (i= 0; i <= pFwImg->Data.Length; i+=4)
5959 LM_RegWrInd(pDevice,address+i,
5960 ((LM_UINT32 *)pFwImg->Data.Buffer)[i/4]);
5964 if (StartCpu & T3_RX_CPU_ID)
5967 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5968 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
5969 for (i = 0 ; i < 5; i++)
5971 if (pFwImg->StartAddress == REG_RD(pDevice,rxCpu.reg.PC))
5974 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5975 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
5976 REG_WR(pDevice,rxCpu.reg.PC,pFwImg->StartAddress);
5980 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
5981 REG_WR(pDevice,rxCpu.reg.mode, 0);
5984 if (StartCpu & T3_TX_CPU_ID)
5987 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
5988 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
5989 for (i = 0 ; i < 5; i++)
5991 if (pFwImg->StartAddress == REG_RD(pDevice,txCpu.reg.PC))
5994 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
5995 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
5996 REG_WR(pDevice,txCpu.reg.PC,pFwImg->StartAddress);
6000 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
6001 REG_WR(pDevice,txCpu.reg.mode, 0);
6004 return LM_STATUS_SUCCESS;
6007 STATIC LM_STATUS LM_HaltCpu(PLM_DEVICE_BLOCK pDevice,LM_UINT32 cpu_number)
6011 if (cpu_number == T3_RX_CPU_ID)
6013 for (i = 0 ; i < 10000; i++)
6015 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
6016 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
6018 if (REG_RD(pDevice,rxCpu.reg.mode) & CPU_MODE_HALT)
6022 REG_WR(pDevice,rxCpu.reg.state, 0xffffffff);
6023 REG_WR(pDevice,rxCpu.reg.mode,CPU_MODE_HALT);
6028 for (i = 0 ; i < 10000; i++)
6030 REG_WR(pDevice,txCpu.reg.state, 0xffffffff);
6031 REG_WR(pDevice,txCpu.reg.mode,CPU_MODE_HALT);
6033 if (REG_RD(pDevice,txCpu.reg.mode) & CPU_MODE_HALT)
6038 return (( i == 10000) ? LM_STATUS_FAILURE : LM_STATUS_SUCCESS);
6043 LM_BlinkLED(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlinkDurationSec)
6049 if(BlinkDurationSec == 0)
6053 if(BlinkDurationSec > 120)
6055 BlinkDurationSec = 120;
6058 Oldcfg = REG_RD(pDevice, MacCtrl.LedCtrl);
6059 for(j = 0; j < BlinkDurationSec * 2; j++)
6063 /* Turn on the LEDs. */
6064 REG_WR(pDevice, MacCtrl.LedCtrl,
6065 LED_CTRL_OVERRIDE_LINK_LED |
6066 LED_CTRL_1000MBPS_LED_ON |
6067 LED_CTRL_100MBPS_LED_ON |
6068 LED_CTRL_10MBPS_LED_ON |
6069 LED_CTRL_OVERRIDE_TRAFFIC_LED |
6070 LED_CTRL_BLINK_TRAFFIC_LED |
6071 LED_CTRL_TRAFFIC_LED);
6075 /* Turn off the LEDs. */
6076 REG_WR(pDevice, MacCtrl.LedCtrl,
6077 LED_CTRL_OVERRIDE_LINK_LED |
6078 LED_CTRL_OVERRIDE_TRAFFIC_LED);
6082 current->state = TASK_INTERRUPTIBLE;
6083 if (schedule_timeout(HZ/2) != 0) {
6088 udelay(100000); /* 1s sleep */
6091 REG_WR(pDevice, MacCtrl.LedCtrl, Oldcfg);
6095 int t3_do_dma(PLM_DEVICE_BLOCK pDevice,
6096 LM_PHYSICAL_ADDRESS host_addr_phy, int length,
6099 T3_DMA_DESC dma_desc;
6101 LM_UINT32 dma_desc_addr;
6104 REG_WR(pDevice, BufMgr.Mode, 0);
6105 REG_WR(pDevice, Ftq.Reset, 0);
6107 dma_desc.host_addr.High = host_addr_phy.High;
6108 dma_desc.host_addr.Low = host_addr_phy.Low;
6109 dma_desc.nic_mbuf = 0x2100;
6110 dma_desc.len = length;
6111 dma_desc.flags = 0x00000004; /* Generate Rx-CPU event */
6115 dma_desc.cqid_sqid = (T3_QID_RX_BD_COMP << 8) |
6116 T3_QID_DMA_HIGH_PRI_READ;
6117 REG_WR(pDevice, DmaRead.Mode, DMA_READ_MODE_ENABLE);
6121 dma_desc.cqid_sqid = (T3_QID_RX_DATA_COMP << 8) |
6122 T3_QID_DMA_HIGH_PRI_WRITE;
6123 REG_WR(pDevice, DmaWrite.Mode, DMA_WRITE_MODE_ENABLE);
6126 dma_desc_addr = T3_NIC_DMA_DESC_POOL_ADDR;
6128 /* Writing this DMA descriptor to DMA memory */
6129 for (i = 0; i < sizeof(T3_DMA_DESC); i += 4)
6131 value32 = *((PLM_UINT32) (((PLM_UINT8) &dma_desc) + i));
6132 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, dma_desc_addr+i);
6133 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_DATA_REG, cpu_to_le32(value32));
6135 MM_WriteConfig32(pDevice, T3_PCI_MEM_WIN_ADDR_REG, 0);
6138 REG_WR(pDevice, Ftq.DmaHighReadFtqFifoEnqueueDequeue, dma_desc_addr);
6140 REG_WR(pDevice, Ftq.DmaHighWriteFtqFifoEnqueueDequeue, dma_desc_addr);
6142 for (i = 0; i < 40; i++)
6145 value32 = REG_RD(pDevice, Ftq.RcvBdCompFtqFifoEnqueueDequeue);
6147 value32 = REG_RD(pDevice, Ftq.RcvDataCompFtqFifoEnqueueDequeue);
6149 if ((value32 & 0xffff) == dma_desc_addr)
6155 return LM_STATUS_SUCCESS;
6159 LM_DmaTest(PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt,
6160 LM_PHYSICAL_ADDRESS BufferPhy, LM_UINT32 BufferSize)
6164 int dma_success = 0;
6166 if(T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5700 &&
6167 T3_ASIC_REV(pDevice->ChipRevId) != T3_ASIC_REV_5701)
6169 return LM_STATUS_SUCCESS;
6171 while (!dma_success)
6173 /* Fill data with incremental patterns */
6174 ptr = (LM_UINT32 *)pBufferVirt;
6175 for (j = 0; j < BufferSize/4; j++)
6178 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 1) == LM_STATUS_FAILURE)
6180 return LM_STATUS_FAILURE;
6184 ptr = (LM_UINT32 *)pBufferVirt;
6185 /* Fill data with zero */
6186 for (j = 0; j < BufferSize/4; j++)
6189 if (t3_do_dma(pDevice,BufferPhy,BufferSize, 0) == LM_STATUS_FAILURE)
6191 return LM_STATUS_FAILURE;
6195 /* Check for data */
6196 ptr = (LM_UINT32 *)pBufferVirt;
6197 for (j = 0; j < BufferSize/4; j++)
6201 if ((pDevice->DmaReadWriteCtrl & DMA_CTRL_WRITE_BOUNDARY_MASK)
6202 == DMA_CTRL_WRITE_BOUNDARY_DISABLE)
6204 pDevice->DmaReadWriteCtrl = (pDevice->DmaReadWriteCtrl &
6205 ~DMA_CTRL_WRITE_BOUNDARY_MASK) |
6206 DMA_CTRL_WRITE_BOUNDARY_16;
6207 REG_WR(pDevice, PciCfg.DmaReadWriteCtrl,
6208 pDevice->DmaReadWriteCtrl);
6213 return LM_STATUS_FAILURE;
6217 if (j == (BufferSize/4))
6220 return LM_STATUS_SUCCESS;
6222 #endif /* CFG_CMD_NET, !CONFIG_NET_MULTI, CONFIG_TIGON3 */