Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2062 lines
62 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. mp_init.c
  5. Abstract:
  6. This module contains miniport initialization related routines
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. DChen 11-01-99 created
  11. Notes:
  12. --*/
  13. #include "precomp.h"
  14. #if DBG
  15. #define _FILENUMBER 'TINI'
  16. #endif
  17. typedef struct _MP_REG_ENTRY
  18. {
  19. NDIS_STRING RegName; // variable name text
  20. BOOLEAN bRequired; // 1 -> required, 0 -> optional
  21. UINT FieldOffset; // offset to MP_ADAPTER field
  22. UINT FieldSize; // size (in bytes) of the field
  23. UINT Default; // default value to use
  24. UINT Min; // minimum value allowed
  25. UINT Max; // maximum value allowed
  26. } MP_REG_ENTRY, *PMP_REG_ENTRY;
  27. MP_REG_ENTRY NICRegTable[] = {
  28. // reg value name Offset in MP_ADAPTER Field size Default Value Min Max
  29. #if DBG
  30. {NDIS_STRING_CONST("Debug"), 0, MP_OFFSET(Debug), MP_SIZE(Debug), MP_WARN, 0, 0xffffffff},
  31. #endif
  32. {NDIS_STRING_CONST("NumRfd"), 0, MP_OFFSET(NumRfd), MP_SIZE(NumRfd), 32, NIC_MIN_RFDS, NIC_MAX_RFDS},
  33. {NDIS_STRING_CONST("NumTcb"), 0, MP_OFFSET(NumTcb), MP_SIZE(NumTcb), NIC_DEF_TCBS, 1, NIC_MAX_TCBS},
  34. {NDIS_STRING_CONST("NumCoalesce"), 0, MP_OFFSET(NumBuffers), MP_SIZE(NumBuffers), 8, 1, 32},
  35. {NDIS_STRING_CONST("PhyAddress"), 0, MP_OFFSET(PhyAddress), MP_SIZE(PhyAddress), 0xFF, 0, 0xFF},
  36. {NDIS_STRING_CONST("Connector"), 0, MP_OFFSET(Connector), MP_SIZE(Connector), 0, 0, 0x2},
  37. {NDIS_STRING_CONST("TxFifo"), 0, MP_OFFSET(AiTxFifo), MP_SIZE(AiTxFifo), DEFAULT_TX_FIFO_LIMIT, 0, 15},
  38. {NDIS_STRING_CONST("RxFifo"), 0, MP_OFFSET(AiRxFifo), MP_SIZE(AiRxFifo), DEFAULT_RX_FIFO_LIMIT, 0, 15},
  39. {NDIS_STRING_CONST("TxDmaCount"), 0, MP_OFFSET(AiTxDmaCount), MP_SIZE(AiTxDmaCount), 0, 0, 63},
  40. {NDIS_STRING_CONST("RxDmaCount"), 0, MP_OFFSET(AiRxDmaCount), MP_SIZE(AiRxDmaCount), 0, 0, 63},
  41. {NDIS_STRING_CONST("UnderrunRetry"), 0, MP_OFFSET(AiUnderrunRetry), MP_SIZE(AiUnderrunRetry), DEFAULT_UNDERRUN_RETRY, 0, 3},
  42. {NDIS_STRING_CONST("Threshold"), 0, MP_OFFSET(AiThreshold), MP_SIZE(AiThreshold), 200, 0, 200},
  43. {NDIS_STRING_CONST("MWIEnable"), 0, MP_OFFSET(MWIEnable), MP_SIZE(MWIEnable), 1, 0, 1},
  44. {NDIS_STRING_CONST("Congest"), 0, MP_OFFSET(Congest), MP_SIZE(Congest), 0, 0, 0x1},
  45. {NDIS_STRING_CONST("SpeedDuplex"), 0, MP_OFFSET(SpeedDuplex), MP_SIZE(SpeedDuplex), 0, 0, 4}
  46. };
  47. #define NIC_NUM_REG_PARAMS (sizeof (NICRegTable) / sizeof(MP_REG_ENTRY))
  48. #if LBFO
  49. NDIS_STRING strBundleId = NDIS_STRING_CONST("BundleId");
  50. #endif
  51. NDIS_STATUS MpFindAdapter(
  52. IN PMP_ADAPTER Adapter,
  53. IN NDIS_HANDLE WrapperConfigurationContext
  54. )
  55. /*++
  56. Routine Description:
  57. Find the adapter and get all the assigned resources
  58. Arguments:
  59. Adapter Pointer to our adapter
  60. Return Value:
  61. NDIS_STATUS_SUCCESS
  62. NDIS_STATUS_ADAPTER_NOT_FOUND (event is logged as well)
  63. --*/
  64. {
  65. #define NIC_PCI_E100_HDR_LENGTH 0xe2
  66. NDIS_STATUS Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
  67. ULONG ErrorCode;
  68. ULONG ErrorValue;
  69. ULONG ulResult;
  70. UCHAR buffer[NIC_PCI_E100_HDR_LENGTH ];
  71. PPCI_COMMON_CONFIG pPciConfig = (PPCI_COMMON_CONFIG) buffer;
  72. USHORT usPciCommand;
  73. UCHAR resBuf[NIC_RESOURCE_BUF_SIZE];
  74. PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)resBuf;
  75. UINT bufSize = NIC_RESOURCE_BUF_SIZE;
  76. PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc;
  77. ULONG index;
  78. BOOLEAN bResPort = FALSE, bResInterrupt = FALSE, bResMemory = FALSE;
  79. DBGPRINT(MP_TRACE, ("---> MpFindAdapter\n"));
  80. do
  81. {
  82. //
  83. // Find our adapter - read in the device and vendor IDs
  84. //
  85. ulResult = NdisReadPciSlotInformation(
  86. Adapter->AdapterHandle,
  87. 0, // not used
  88. FIELD_OFFSET(PCI_COMMON_CONFIG, VendorID),
  89. buffer,
  90. NIC_PCI_E100_HDR_LENGTH );
  91. if (ulResult != NIC_PCI_E100_HDR_LENGTH )
  92. {
  93. DBGPRINT(MP_ERROR,
  94. ("NdisReadPciSlotInformation (PCI_COMMON_CONFIG) ulResult=%d\n", ulResult));
  95. ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
  96. ErrorValue = ERRLOG_READ_PCI_SLOT_FAILED;
  97. break;
  98. }
  99. //
  100. // Right type of adapter?
  101. //
  102. if (pPciConfig->VendorID != NIC_PCI_VENDOR_ID ||
  103. pPciConfig->DeviceID != NIC_PCI_DEVICE_ID)
  104. {
  105. DBGPRINT(MP_ERROR, ("VendorID/DeviceID don't match - %x/%x\n",
  106. pPciConfig->VendorID, pPciConfig->DeviceID));
  107. ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
  108. ErrorValue = ERRLOG_VENDOR_DEVICE_NOMATCH;
  109. break;
  110. }
  111. DBGPRINT(MP_INFO, ("Adapter is found - VendorID/DeviceID=%x/%x\n",
  112. pPciConfig->VendorID, pPciConfig->DeviceID));
  113. // save info from config space
  114. Adapter->RevsionID = pPciConfig->RevisionID;
  115. Adapter->SubVendorID = pPciConfig->u.type0.SubVendorID;
  116. Adapter->SubSystemID = pPciConfig->u.type0.SubSystemID;
  117. MpExtractPMInfoFromPciSpace (Adapter, (PUCHAR)pPciConfig);
  118. // --- HW_START
  119. usPciCommand = pPciConfig->Command;
  120. if ((usPciCommand & PCI_ENABLE_WRITE_AND_INVALIDATE) && (Adapter->MWIEnable))
  121. Adapter->MWIEnable = TRUE;
  122. else
  123. Adapter->MWIEnable = FALSE;
  124. // Enable bus matering if it isn't enabled by the BIOS
  125. if (!(usPciCommand & PCI_ENABLE_BUS_MASTER))
  126. {
  127. DBGPRINT(MP_WARN, ("Bus master is not enabled by BIOS! usPciCommand=%x\n",
  128. usPciCommand));
  129. usPciCommand |= CMD_BUS_MASTER;
  130. ulResult = NdisWritePciSlotInformation(
  131. Adapter->AdapterHandle,
  132. 0,
  133. FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
  134. &usPciCommand,
  135. sizeof(USHORT));
  136. if (ulResult != sizeof(USHORT))
  137. {
  138. DBGPRINT(MP_ERROR,
  139. ("NdisWritePciSlotInformation (Command) ulResult=%d\n", ulResult));
  140. ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
  141. ErrorValue = ERRLOG_WRITE_PCI_SLOT_FAILED;
  142. break;
  143. }
  144. ulResult = NdisReadPciSlotInformation(
  145. Adapter->AdapterHandle,
  146. 0,
  147. FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
  148. &usPciCommand,
  149. sizeof(USHORT));
  150. if (ulResult != sizeof(USHORT))
  151. {
  152. DBGPRINT(MP_ERROR,
  153. ("NdisReadPciSlotInformation (Command) ulResult=%d\n", ulResult));
  154. ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
  155. ErrorValue = ERRLOG_READ_PCI_SLOT_FAILED;
  156. break;
  157. }
  158. if (!(usPciCommand & PCI_ENABLE_BUS_MASTER))
  159. {
  160. DBGPRINT(MP_ERROR, ("Failed to enable bus master! usPciCommand=%x\n",
  161. usPciCommand));
  162. ErrorCode = NDIS_ERROR_CODE_ADAPTER_DISABLED;
  163. ErrorValue = ERRLOG_BUS_MASTER_DISABLED;
  164. break;
  165. }
  166. }
  167. DBGPRINT(MP_INFO, ("Bus master is enabled. usPciCommand=%x\n", usPciCommand));
  168. // --- HW_END
  169. //
  170. // Adapter is found. Now get the assigned resources
  171. //
  172. NdisMQueryAdapterResources(
  173. &Status,
  174. WrapperConfigurationContext,
  175. resList,
  176. &bufSize);
  177. if (Status != NDIS_STATUS_SUCCESS)
  178. {
  179. ErrorCode = NDIS_ERROR_CODE_RESOURCE_CONFLICT;
  180. ErrorValue = ERRLOG_QUERY_ADAPTER_RESOURCES;
  181. break;
  182. }
  183. for (index=0; index < resList->Count; index++)
  184. {
  185. pResDesc = &resList->PartialDescriptors[index];
  186. switch(pResDesc->Type)
  187. {
  188. case CmResourceTypePort:
  189. Adapter->IoBaseAddress = NdisGetPhysicalAddressLow(pResDesc->u.Port.Start);
  190. Adapter->IoRange = pResDesc->u.Port.Length;
  191. bResPort = TRUE;
  192. DBGPRINT(MP_INFO, ("IoBaseAddress = 0x%x\n", Adapter->IoBaseAddress));
  193. DBGPRINT(MP_INFO, ("IoRange = x%x\n", Adapter->IoRange));
  194. break;
  195. case CmResourceTypeInterrupt:
  196. Adapter->InterruptLevel = pResDesc->u.Interrupt.Level;
  197. bResInterrupt = TRUE;
  198. DBGPRINT(MP_INFO, ("InterruptLevel = x%x\n", Adapter->InterruptLevel));
  199. break;
  200. case CmResourceTypeMemory:
  201. // Our CSR memory space should be 0x1000, other memory is for
  202. // flash address, a boot ROM address, etc.
  203. if (pResDesc->u.Memory.Length == 0x1000)
  204. {
  205. Adapter->MemPhysAddress = pResDesc->u.Memory.Start;
  206. bResMemory = TRUE;
  207. DBGPRINT(MP_INFO,
  208. ("MemPhysAddress(Low) = 0x%0x\n", NdisGetPhysicalAddressLow(Adapter->MemPhysAddress)));
  209. DBGPRINT(MP_INFO,
  210. ("MemPhysAddress(High) = 0x%0x\n", NdisGetPhysicalAddressHigh(Adapter->MemPhysAddress)));
  211. }
  212. break;
  213. }
  214. }
  215. if (!bResPort || !bResInterrupt || !bResMemory)
  216. {
  217. Status = NDIS_STATUS_RESOURCE_CONFLICT;
  218. ErrorCode = NDIS_ERROR_CODE_RESOURCE_CONFLICT;
  219. if (!bResPort)
  220. {
  221. ErrorValue = ERRLOG_NO_IO_RESOURCE;
  222. }
  223. else if (!bResInterrupt)
  224. {
  225. ErrorValue = ERRLOG_NO_INTERRUPT_RESOURCE;
  226. }
  227. else
  228. {
  229. ErrorValue = ERRLOG_NO_MEMORY_RESOURCE;
  230. }
  231. break;
  232. }
  233. Status = NDIS_STATUS_SUCCESS;
  234. } while (FALSE);
  235. if (Status != NDIS_STATUS_SUCCESS)
  236. {
  237. NdisWriteErrorLogEntry(
  238. Adapter->AdapterHandle,
  239. ErrorCode,
  240. 1,
  241. ErrorValue);
  242. }
  243. DBGPRINT_S(Status, ("<--- MpFindAdapter, Status=%x\n", Status));
  244. return Status;
  245. }
  246. NDIS_STATUS NICReadAdapterInfo(
  247. IN PMP_ADAPTER Adapter)
  248. /*++
  249. Routine Description:
  250. Read the mac addresss from the adapter
  251. Arguments:
  252. Adapter Pointer to our adapter
  253. Return Value:
  254. NDIS_STATUS_SUCCESS
  255. NDIS_STATUS_INVALID_ADDRESS
  256. --*/
  257. {
  258. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  259. USHORT usValue;
  260. int i;
  261. DBGPRINT(MP_TRACE, ("--> NICReadAdapterInfo\n"));
  262. Adapter->EepromAddressSize =
  263. GetEEpromAddressSize(GetEEpromSize(Adapter->PortOffset));
  264. DBGPRINT(MP_WARN, ("EepromAddressSize = %d\n", Adapter->EepromAddressSize));
  265. // Read node address from the EEPROM
  266. for (i=0; i<6; i += 2)
  267. {
  268. usValue = ReadEEprom(Adapter->PortOffset,
  269. (USHORT)(EEPROM_NODE_ADDRESS_BYTE_0 + (i/2)),
  270. Adapter->EepromAddressSize);
  271. *((PUSHORT)(&Adapter->PermanentAddress[i])) = usValue;
  272. }
  273. DBGPRINT(MP_INFO, ("Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
  274. Adapter->PermanentAddress[0], Adapter->PermanentAddress[1],
  275. Adapter->PermanentAddress[2], Adapter->PermanentAddress[3],
  276. Adapter->PermanentAddress[4], Adapter->PermanentAddress[5]));
  277. if (ETH_IS_MULTICAST(Adapter->PermanentAddress) ||
  278. ETH_IS_BROADCAST(Adapter->PermanentAddress))
  279. {
  280. DBGPRINT(MP_ERROR, ("Permanent address is invalid\n"));
  281. NdisWriteErrorLogEntry(
  282. Adapter->AdapterHandle,
  283. NDIS_ERROR_CODE_NETWORK_ADDRESS,
  284. 0);
  285. Status = NDIS_STATUS_INVALID_ADDRESS;
  286. }
  287. else
  288. {
  289. if (!Adapter->bOverrideAddress)
  290. {
  291. ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentAddress, Adapter->PermanentAddress);
  292. }
  293. DBGPRINT(MP_INFO, ("Current Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
  294. Adapter->CurrentAddress[0], Adapter->CurrentAddress[1],
  295. Adapter->CurrentAddress[2], Adapter->CurrentAddress[3],
  296. Adapter->CurrentAddress[4], Adapter->CurrentAddress[5]));
  297. }
  298. DBGPRINT_S(Status, ("<-- NICReadAdapterInfo, Status=%x\n", Status));
  299. return Status;
  300. }
  301. NDIS_STATUS MpAllocAdapterBlock(
  302. OUT PMP_ADAPTER *pAdapter)
  303. /*++
  304. Routine Description:
  305. Allocate MP_ADAPTER data block and do some initialization
  306. Arguments:
  307. Adapter Pointer to receive pointer to our adapter
  308. Return Value:
  309. NDIS_STATUS_SUCCESS
  310. NDIS_STATUS_FAILURE
  311. --*/
  312. {
  313. PMP_ADAPTER Adapter;
  314. NDIS_HANDLE PacketPoolHandle;
  315. NDIS_HANDLE BufferPoolHandle;
  316. PNDIS_PACKET Packet;
  317. PNDIS_BUFFER Buffer;
  318. NDIS_STATUS Status;
  319. LONG index;
  320. DBGPRINT(MP_TRACE, ("--> NICAllocAdapter\n"));
  321. *pAdapter = NULL;
  322. do
  323. {
  324. // Allocate MP_ADAPTER block
  325. Status = MP_ALLOCMEMTAG(&Adapter, sizeof(MP_ADAPTER));
  326. if (Status != NDIS_STATUS_SUCCESS)
  327. {
  328. DBGPRINT(MP_ERROR, ("Failed to allocate memory - ADAPTER\n"));
  329. break;
  330. }
  331. // Clean up the memory block
  332. NdisZeroMemory(Adapter, sizeof(MP_ADAPTER));
  333. MP_INC_REF(Adapter);
  334. // Init lists, spinlocks, etc.
  335. InitializeQueueHeader(&Adapter->SendWaitQueue);
  336. InitializeQueueHeader(&Adapter->SendCancelQueue);
  337. InitializeListHead(&Adapter->RecvList);
  338. InitializeListHead(&Adapter->RecvPendList);
  339. InitializeListHead(&Adapter->PoMgmt.PatternList);
  340. NdisInitializeEvent(&Adapter->ExitEvent);
  341. NdisInitializeEvent(&Adapter->AllPacketsReturnedEvent);
  342. MP_INC_RCV_REF(Adapter);
  343. NdisAllocateSpinLock(&Adapter->Lock);
  344. NdisAllocateSpinLock(&Adapter->SendLock);
  345. NdisAllocateSpinLock(&Adapter->RcvLock);
  346. } while (FALSE);
  347. *pAdapter = Adapter;
  348. DBGPRINT_S(Status, ("<-- NICAllocAdapter, Status=%x\n", Status));
  349. return Status;
  350. }
  351. VOID MpFreeAdapter(
  352. IN PMP_ADAPTER Adapter)
  353. /*++
  354. Routine Description:
  355. Free all the resources and MP_ADAPTER data block
  356. Arguments:
  357. Adapter Pointer to our adapter
  358. Return Value:
  359. None
  360. --*/
  361. {
  362. PMP_TXBUF pMpTxBuf;
  363. PMP_RFD pMpRfd;
  364. DBGPRINT(MP_TRACE, ("--> NICFreeAdapter\n"));
  365. // No active and waiting sends
  366. ASSERT(Adapter->nBusySend == 0);
  367. ASSERT(Adapter->nWaitSend == 0);
  368. ASSERT(IsQueueEmpty(&Adapter->SendWaitQueue));
  369. ASSERT(IsQueueEmpty(&Adapter->SendCancelQueue));
  370. // No other pending operations
  371. ASSERT(IsListEmpty(&Adapter->RecvPendList));
  372. ASSERT(Adapter->bAllocNewRfd == FALSE);
  373. ASSERT(!MP_TEST_FLAG(Adapter, fMP_ADAPTER_LINK_DETECTION));
  374. ASSERT(MP_GET_REF(Adapter) == 0);
  375. //
  376. // Free hardware resources
  377. //
  378. if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_INTERRUPT_IN_USE))
  379. {
  380. NdisMDeregisterInterrupt(&Adapter->Interrupt);
  381. MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_INTERRUPT_IN_USE);
  382. }
  383. if (Adapter->CSRAddress)
  384. {
  385. NdisMUnmapIoSpace(
  386. Adapter->AdapterHandle,
  387. Adapter->CSRAddress,
  388. NIC_MAP_IOSPACE_LENGTH);
  389. Adapter->CSRAddress = NULL;
  390. }
  391. if (Adapter->PortOffset)
  392. {
  393. NdisMDeregisterIoPortRange(
  394. Adapter->AdapterHandle,
  395. Adapter->IoBaseAddress,
  396. Adapter->IoRange,
  397. Adapter->PortOffset);
  398. Adapter->PortOffset = NULL;
  399. }
  400. //
  401. // Free RECV memory/NDIS buffer/NDIS packets/shared memory
  402. //
  403. ASSERT(Adapter->nReadyRecv == Adapter->CurrNumRfd);
  404. while (!IsListEmpty(&Adapter->RecvList))
  405. {
  406. pMpRfd = (PMP_RFD)RemoveHeadList(&Adapter->RecvList);
  407. NICFreeRfd(Adapter, pMpRfd);
  408. }
  409. // Free receive buffer pool
  410. if (Adapter->RecvBufferPool)
  411. {
  412. NdisFreeBufferPool(Adapter->RecvBufferPool);
  413. Adapter->RecvBufferPool = NULL;
  414. }
  415. // Free receive packet pool
  416. if (Adapter->RecvPacketPool)
  417. {
  418. NdisFreePacketPool(Adapter->RecvPacketPool);
  419. Adapter->RecvPacketPool = NULL;
  420. }
  421. if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE))
  422. {
  423. NdisDeleteNPagedLookasideList(&Adapter->RecvLookaside);
  424. MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE);
  425. }
  426. //
  427. // Free SEND memory/NDIS buffer/NDIS packets/shared memory
  428. //
  429. while (!IsSListEmpty(&Adapter->SendBufList))
  430. {
  431. pMpTxBuf = (PMP_TXBUF)PopEntryList(&Adapter->SendBufList);
  432. ASSERT(pMpTxBuf);
  433. // Free the shared memory associated with each MP_TXBUF
  434. if (pMpTxBuf->AllocVa)
  435. {
  436. NdisMFreeSharedMemory(
  437. Adapter->AdapterHandle,
  438. pMpTxBuf->AllocSize,
  439. TRUE,
  440. pMpTxBuf->AllocVa,
  441. pMpTxBuf->AllocPa);
  442. pMpTxBuf->AllocVa = NULL;
  443. }
  444. // Free the NDIS buffer
  445. if (pMpTxBuf->NdisBuffer)
  446. {
  447. NdisFreeBuffer(pMpTxBuf->NdisBuffer);
  448. pMpTxBuf->NdisBuffer = NULL;
  449. }
  450. }
  451. // Free the send buffer pool
  452. if (Adapter->SendBufferPool)
  453. {
  454. NdisFreeBufferPool(Adapter->SendBufferPool);
  455. Adapter->SendBufferPool = NULL;
  456. }
  457. // Free the memory for MP_TXBUF structures
  458. if (Adapter->MpTxBufMem)
  459. {
  460. MP_FREEMEM(Adapter->MpTxBufMem, Adapter->MpTxBufMemSize, 0);
  461. Adapter->MpTxBufMem = NULL;
  462. }
  463. // Free the shared memory for HW_TCB structures
  464. if (Adapter->HwSendMemAllocVa)
  465. {
  466. NdisMFreeSharedMemory(
  467. Adapter->AdapterHandle,
  468. Adapter->HwSendMemAllocSize,
  469. FALSE,
  470. Adapter->HwSendMemAllocVa,
  471. Adapter->HwSendMemAllocPa);
  472. Adapter->HwSendMemAllocVa = NULL;
  473. }
  474. // Free the shared memory for other command data structures
  475. if (Adapter->HwMiscMemAllocVa)
  476. {
  477. NdisMFreeSharedMemory(
  478. Adapter->AdapterHandle,
  479. Adapter->HwMiscMemAllocSize,
  480. FALSE,
  481. Adapter->HwMiscMemAllocVa,
  482. Adapter->HwMiscMemAllocPa);
  483. Adapter->HwMiscMemAllocVa = NULL;
  484. }
  485. // Free the memory for MP_TCB structures
  486. if (Adapter->MpTcbMem)
  487. {
  488. MP_FREEMEM(Adapter->MpTcbMem, Adapter->MpTcbMemSize, 0);
  489. Adapter->MpTcbMem = NULL;
  490. }
  491. // Free map registers. This must be after all the shared memory is freed
  492. if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_MAP_REGISTER))
  493. {
  494. NdisMFreeMapRegisters(Adapter->AdapterHandle);
  495. MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_MAP_REGISTER);
  496. }
  497. //Free all the wake up patterns on this adapter
  498. MPRemoveAllWakeUpPatterns(Adapter);
  499. NdisFreeSpinLock(&Adapter->Lock);
  500. #if LBFO
  501. if (Adapter->BundleId.MaximumLength)
  502. {
  503. MP_FREE_NDIS_STRING(&Adapter->BundleId);
  504. }
  505. #endif
  506. #if OFFLOAD
  507. // Free the shared memory for offload tasks
  508. if (Adapter->OffloadSharedMem.StartVa)
  509. {
  510. NdisMFreeSharedMemory(
  511. Adapter->AdapterHandle,
  512. Adapter->OffloadSharedMemSize,
  513. FALSE,
  514. Adapter->OffloadSharedMem.StartVa,
  515. Adapter->OffloadSharedMem.PhyAddr);
  516. Adapter->OffloadSharedMem.StartVa = NULL;
  517. }
  518. #endif
  519. MP_FREEMEM(Adapter, sizeof(MP_ADAPTER), 0);
  520. DBGPRINT(MP_TRACE, ("<-- NICFreeAdapter\n"));
  521. }
  522. NDIS_STATUS NICReadRegParameters(
  523. IN PMP_ADAPTER Adapter,
  524. IN NDIS_HANDLE WrapperConfigurationContext)
  525. /*++
  526. Routine Description:
  527. Read the following from the registry
  528. 1. All the parameters
  529. 2. NetworkAddres
  530. 3. LBFO - BundleId
  531. Arguments:
  532. Adapter Pointer to our adapter
  533. WrapperConfigurationContext For use by NdisOpenConfiguration
  534. Return Value:
  535. NDIS_STATUS_SUCCESS
  536. NDIS_STATUS_FAILURE
  537. NDIS_STATUS_RESOURCES
  538. --*/
  539. {
  540. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  541. NDIS_HANDLE ConfigurationHandle;
  542. PMP_REG_ENTRY pRegEntry;
  543. UINT i;
  544. UINT value;
  545. PUCHAR pointer;
  546. PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
  547. PUCHAR NetworkAddress;
  548. UINT Length;
  549. DBGPRINT(MP_TRACE, ("--> NICReadRegParameters\n"));
  550. // Open the registry for this adapter
  551. NdisOpenConfiguration(
  552. &Status,
  553. &ConfigurationHandle,
  554. WrapperConfigurationContext);
  555. if (Status != NDIS_STATUS_SUCCESS)
  556. {
  557. DBGPRINT(MP_ERROR, ("NdisOpenConfiguration failed\n"));
  558. DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
  559. return Status;
  560. }
  561. // read all the registry values
  562. for (i = 0, pRegEntry = NICRegTable; i < NIC_NUM_REG_PARAMS; i++, pRegEntry++)
  563. {
  564. pointer = (PUCHAR) Adapter + pRegEntry->FieldOffset;
  565. DBGPRINT_UNICODE(MP_INFO, &pRegEntry->RegName);
  566. // Get the configuration value for a specific parameter. Under NT the
  567. // parameters are all read in as DWORDs.
  568. NdisReadConfiguration(
  569. &Status,
  570. &ReturnedValue,
  571. ConfigurationHandle,
  572. &pRegEntry->RegName,
  573. NdisParameterInteger);
  574. // If the parameter was present, then check its value for validity.
  575. if (Status == NDIS_STATUS_SUCCESS)
  576. {
  577. // Check that param value is not too small or too large
  578. if (ReturnedValue->ParameterData.IntegerData < pRegEntry->Min ||
  579. ReturnedValue->ParameterData.IntegerData > pRegEntry->Max)
  580. {
  581. value = pRegEntry->Default;
  582. }
  583. else
  584. {
  585. value = ReturnedValue->ParameterData.IntegerData;
  586. }
  587. DBGPRINT_RAW(MP_INFO, ("= 0x%x\n", value));
  588. }
  589. else if (pRegEntry->bRequired)
  590. {
  591. DBGPRINT_RAW(MP_ERROR, (" -- failed\n"));
  592. ASSERT(FALSE);
  593. Status = NDIS_STATUS_FAILURE;
  594. break;
  595. }
  596. else
  597. {
  598. value = pRegEntry->Default;
  599. DBGPRINT_RAW(MP_INFO, ("= 0x%x (default)\n", value));
  600. Status = NDIS_STATUS_SUCCESS;
  601. }
  602. // Store the value in the adapter structure.
  603. switch(pRegEntry->FieldSize)
  604. {
  605. case 1:
  606. *((PUCHAR) pointer) = (UCHAR) value;
  607. break;
  608. case 2:
  609. *((PUSHORT) pointer) = (USHORT) value;
  610. break;
  611. case 4:
  612. *((PULONG) pointer) = (ULONG) value;
  613. break;
  614. default:
  615. DBGPRINT(MP_ERROR, ("Bogus field size %d\n", pRegEntry->FieldSize));
  616. break;
  617. }
  618. }
  619. // Read NetworkAddress registry value
  620. // Use it as the current address if any
  621. if (Status == NDIS_STATUS_SUCCESS)
  622. {
  623. NdisReadNetworkAddress(
  624. &Status,
  625. &NetworkAddress,
  626. &Length,
  627. ConfigurationHandle);
  628. // If there is a NetworkAddress override in registry, use it
  629. if ((Status == NDIS_STATUS_SUCCESS) && (Length == ETH_LENGTH_OF_ADDRESS))
  630. {
  631. if (ETH_IS_MULTICAST(NetworkAddress) || ETH_IS_BROADCAST(NetworkAddress))
  632. {
  633. DBGPRINT(MP_ERROR,
  634. ("Overriding NetworkAddress is invalid - %02x-%02x-%02x-%02x-%02x-%02x\n",
  635. NetworkAddress[0], NetworkAddress[1], NetworkAddress[2],
  636. NetworkAddress[3], NetworkAddress[4], NetworkAddress[5]));
  637. }
  638. else
  639. {
  640. ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentAddress, NetworkAddress);
  641. Adapter->bOverrideAddress = TRUE;
  642. }
  643. }
  644. Status = NDIS_STATUS_SUCCESS;
  645. }
  646. #if LBFO
  647. if (Status == NDIS_STATUS_SUCCESS)
  648. {
  649. // Read BundleIdentifier string
  650. NdisReadConfiguration(
  651. &Status,
  652. &ReturnedValue,
  653. ConfigurationHandle,
  654. &strBundleId,
  655. NdisParameterString);
  656. if (Status == NDIS_STATUS_SUCCESS)
  657. {
  658. ASSERT(ReturnedValue->ParameterType == NdisParameterString);
  659. if (ReturnedValue->ParameterData.StringData.Length !=0)
  660. {
  661. Status = MP_ALLOCMEMTAG(&Adapter->BundleId.Buffer,
  662. ReturnedValue->ParameterData.StringData.Length + sizeof(WCHAR));
  663. if (Status == NDIS_STATUS_SUCCESS)
  664. {
  665. Adapter->BundleId.MaximumLength =
  666. ReturnedValue->ParameterData.StringData.Length + sizeof(WCHAR);
  667. NdisUpcaseUnicodeString(
  668. &Adapter->BundleId,
  669. &ReturnedValue->ParameterData.StringData);
  670. }
  671. else
  672. {
  673. DBGPRINT(MP_ERROR, ("Failed to allocate memory - BundleIdentifier\n"));
  674. }
  675. }
  676. }
  677. else
  678. {
  679. // This parameter is optional, set status to SUCCESS
  680. Status = NDIS_STATUS_SUCCESS;
  681. }
  682. }
  683. #endif
  684. // Close the registry
  685. NdisCloseConfiguration(ConfigurationHandle);
  686. // Decode SpeedDuplex
  687. if (Status == NDIS_STATUS_SUCCESS && Adapter->SpeedDuplex)
  688. {
  689. switch(Adapter->SpeedDuplex)
  690. {
  691. case 1:
  692. Adapter->AiTempSpeed = 10; Adapter->AiForceDpx = 1;
  693. break;
  694. case 2:
  695. Adapter->AiTempSpeed = 10; Adapter->AiForceDpx = 2;
  696. break;
  697. case 3:
  698. Adapter->AiTempSpeed = 100; Adapter->AiForceDpx = 1;
  699. break;
  700. case 4:
  701. Adapter->AiTempSpeed = 100; Adapter->AiForceDpx = 2;
  702. break;
  703. }
  704. }
  705. DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
  706. return Status;
  707. }
  708. NDIS_STATUS NICAllocAdapterMemory(
  709. IN PMP_ADAPTER Adapter)
  710. /*++
  711. Routine Description:
  712. Allocate all the memory blocks for send, receive and others
  713. Arguments:
  714. Adapter Pointer to our adapter
  715. Return Value:
  716. NDIS_STATUS_SUCCESS
  717. NDIS_STATUS_FAILURE
  718. NDIS_STATUS_RESOURCES
  719. --*/
  720. {
  721. NDIS_STATUS Status;
  722. PMP_TCB pMpTCB;
  723. PMP_TXBUF pMpTxbuf;
  724. PUCHAR pMem;
  725. ULONG MemPhys;
  726. LONG index;
  727. LONG MapRegisterCount;
  728. ULONG ErrorValue = 0;
  729. UINT MaxNumBuffers;
  730. #if OFFLOAD
  731. BOOLEAN OffloadSharedMemSuccess = FALSE;
  732. UINT i;
  733. #endif
  734. DBGPRINT(MP_TRACE, ("--> NICAllocMemory\n"));
  735. DBGPRINT(MP_INFO, ("NumTcb=%d\n", Adapter->NumTcb));
  736. Adapter->NumTbd = Adapter->NumTcb * NIC_MAX_PHYS_BUF_COUNT;
  737. do
  738. {
  739. //
  740. // Try to use the ScatterGather method first, this is the preferred way
  741. // Only use map registers if we can't do scatter gather (e.g. on win9x)
  742. #if OFFLOAD
  743. Status = NdisMInitializeScatterGatherDma(
  744. Adapter->AdapterHandle,
  745. FALSE,
  746. LARGE_SEND_OFFLOAD_SIZE);
  747. #else
  748. Status = NdisMInitializeScatterGatherDma(
  749. Adapter->AdapterHandle,
  750. FALSE,
  751. NIC_MAX_PACKET_SIZE);
  752. #endif
  753. if (Status == NDIS_STATUS_SUCCESS)
  754. {
  755. MP_SET_FLAG(Adapter, fMP_ADAPTER_SCATTER_GATHER);
  756. }
  757. else
  758. {
  759. DBGPRINT(MP_WARN, ("Failed to init ScatterGather DMA, allocate map registers\n"));
  760. // We should limit the totoal map registers needed to 32
  761. Adapter->NumTcb = 32 / NIC_MAX_PHYS_BUF_COUNT;
  762. Adapter->NumTbd = Adapter->NumTcb * NIC_MAX_PHYS_BUF_COUNT;
  763. DBGPRINT(MP_WARN, ("NumTcb is reduced to %d", Adapter->NumTcb));
  764. while (Adapter->NumTcb > 0)
  765. {
  766. Status = NdisMAllocateMapRegisters(
  767. Adapter->AdapterHandle,
  768. 0,
  769. NDIS_DMA_32BITS,
  770. Adapter->NumTbd,
  771. NIC_MAX_PACKET_SIZE);
  772. if (Status == NDIS_STATUS_SUCCESS)
  773. {
  774. break;
  775. }
  776. // Reduce NumTcb and try again
  777. Adapter->NumTcb--;
  778. DBGPRINT(MP_WARN, ("NumTcb is reduced to %d", Adapter->NumTcb));
  779. Adapter->NumTbd = Adapter->NumTcb * NIC_MAX_PHYS_BUF_COUNT;
  780. }
  781. if (Status == NDIS_STATUS_SUCCESS)
  782. {
  783. MP_SET_FLAG(Adapter, fMP_ADAPTER_MAP_REGISTER);
  784. }
  785. else
  786. {
  787. ErrorValue = ERRLOG_OUT_OF_MAP_REGISTERS;
  788. DBGPRINT(MP_ERROR, ("Failed to allocate map registers\n"));
  789. break;
  790. }
  791. }
  792. //
  793. // Send + Misc
  794. //
  795. //
  796. // Allocate MP_TCB's
  797. //
  798. Adapter->MpTcbMemSize = Adapter->NumTcb * sizeof(MP_TCB);
  799. Status = MP_ALLOCMEMTAG(&pMem, Adapter->MpTcbMemSize);
  800. if (Status != NDIS_STATUS_SUCCESS)
  801. {
  802. ErrorValue = ERRLOG_OUT_OF_MEMORY;
  803. DBGPRINT(MP_ERROR, ("Failed to allocate MP_TCB's\n"));
  804. break;
  805. }
  806. NdisZeroMemory(pMem, Adapter->MpTcbMemSize);
  807. Adapter->MpTcbMem = pMem;
  808. //
  809. // Now the driver needs to allocate send buffer pool, the number
  810. // of send buffers the driver needs is the larger one of Adapter->NumBuffer
  811. // and Adapter->NumTcb.
  812. //
  813. MaxNumBuffers = Adapter->NumBuffers > Adapter->NumTcb ? Adapter->NumBuffers: Adapter->NumTcb;
  814. NdisAllocateBufferPool(
  815. &Status,
  816. &Adapter->SendBufferPool,
  817. MaxNumBuffers);
  818. if (Status != NDIS_STATUS_SUCCESS)
  819. {
  820. ErrorValue = ERRLOG_OUT_OF_BUFFER_POOL;
  821. DBGPRINT(MP_ERROR, ("Failed to allocate send buffer pool\n"));
  822. break;
  823. }
  824. // Allocate send buffers
  825. Adapter->MpTxBufMemSize = Adapter->NumBuffers * sizeof(MP_TXBUF);
  826. Status = MP_ALLOCMEMTAG(&pMem, Adapter->MpTxBufMemSize);
  827. if (Status != NDIS_STATUS_SUCCESS)
  828. {
  829. ErrorValue = ERRLOG_OUT_OF_MEMORY;
  830. DBGPRINT(MP_ERROR, ("Failed to allocate MP_TXBUF's\n"));
  831. break;
  832. }
  833. NdisZeroMemory(pMem, Adapter->MpTxBufMemSize);
  834. Adapter->MpTxBufMem = pMem;
  835. pMpTxbuf = (PMP_TXBUF) pMem;
  836. //
  837. // NdisMGetDmaAlignment is provided in XP (WINVER=0x0501) and higher
  838. // if you need to write a driver that runs on older versions of Windows
  839. // you need to compile with older versions of DDK which have WINVER < 0x0501
  840. // such as W2K DDK.
  841. //
  842. #if (WINVER < 0x0501)
  843. Adapter->CacheFillSize = NdisGetCacheFillSize();
  844. #else
  845. Adapter->CacheFillSize = NdisMGetDmaAlignment(Adapter->AdapterHandle);
  846. #endif
  847. DBGPRINT(MP_INFO, ("CacheFillSize=%d\n", Adapter->CacheFillSize));
  848. for (index = 0; index < Adapter->NumBuffers; index++)
  849. {
  850. pMpTxbuf->AllocSize = NIC_MAX_PACKET_SIZE + Adapter->CacheFillSize;
  851. pMpTxbuf->BufferSize = NIC_MAX_PACKET_SIZE;
  852. NdisMAllocateSharedMemory(
  853. Adapter->AdapterHandle,
  854. pMpTxbuf->AllocSize,
  855. TRUE, // CACHED
  856. &pMpTxbuf->AllocVa,
  857. &pMpTxbuf->AllocPa);
  858. if (!pMpTxbuf->AllocVa)
  859. {
  860. ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
  861. DBGPRINT(MP_ERROR, ("Failed to allocate a big buffer\n"));
  862. Status = NDIS_STATUS_RESOURCES;
  863. break;
  864. }
  865. // Align the buffer on the cache line boundary
  866. pMpTxbuf->pBuffer = MP_ALIGNMEM(pMpTxbuf->AllocVa, Adapter->CacheFillSize);
  867. pMpTxbuf->BufferPa.QuadPart = MP_ALIGNMEM_PA(pMpTxbuf->AllocPa, Adapter->CacheFillSize);
  868. NdisAllocateBuffer(
  869. &Status,
  870. &pMpTxbuf->NdisBuffer,
  871. Adapter->SendBufferPool,
  872. pMpTxbuf->pBuffer,
  873. pMpTxbuf->BufferSize);
  874. if (Status != NDIS_STATUS_SUCCESS)
  875. {
  876. ErrorValue = ERRLOG_OUT_OF_NDIS_BUFFER;
  877. DBGPRINT(MP_ERROR, ("Failed to allocate NDIS buffer for a big buffer\n"));
  878. NdisMFreeSharedMemory(
  879. Adapter->AdapterHandle,
  880. pMpTxbuf->AllocSize,
  881. TRUE, // CACHED
  882. pMpTxbuf->AllocVa,
  883. pMpTxbuf->AllocPa);
  884. break;
  885. }
  886. PushEntryList(&Adapter->SendBufList, &pMpTxbuf->SList);
  887. pMpTxbuf++;
  888. }
  889. if (Status != NDIS_STATUS_SUCCESS) break;
  890. // HW_START
  891. // Allocate shared memory for send
  892. Adapter->HwSendMemAllocSize = Adapter->NumTcb * (sizeof(TXCB_STRUC) +
  893. NIC_MAX_PHYS_BUF_COUNT * sizeof(TBD_STRUC));
  894. NdisMAllocateSharedMemory(
  895. Adapter->AdapterHandle,
  896. Adapter->HwSendMemAllocSize,
  897. FALSE,
  898. (PVOID) &Adapter->HwSendMemAllocVa,
  899. &Adapter->HwSendMemAllocPa);
  900. if (!Adapter->HwSendMemAllocVa)
  901. {
  902. ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
  903. DBGPRINT(MP_ERROR, ("Failed to allocate send memory\n"));
  904. Status = NDIS_STATUS_RESOURCES;
  905. break;
  906. }
  907. NdisZeroMemory(Adapter->HwSendMemAllocVa, Adapter->HwSendMemAllocSize);
  908. // Allocate shared memory for other uses
  909. Adapter->HwMiscMemAllocSize =
  910. sizeof(SELF_TEST_STRUC) + ALIGN_16 +
  911. sizeof(DUMP_AREA_STRUC) + ALIGN_16 +
  912. sizeof(NON_TRANSMIT_CB) + ALIGN_16 +
  913. sizeof(ERR_COUNT_STRUC) + ALIGN_16;
  914. // Allocate the shared memory for the command block data structures.
  915. NdisMAllocateSharedMemory(
  916. Adapter->AdapterHandle,
  917. Adapter->HwMiscMemAllocSize,
  918. FALSE,
  919. (PVOID *) &Adapter->HwMiscMemAllocVa,
  920. &Adapter->HwMiscMemAllocPa);
  921. if (!Adapter->HwMiscMemAllocVa)
  922. {
  923. ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
  924. DBGPRINT(MP_ERROR, ("Failed to allocate misc memory\n"));
  925. Status = NDIS_STATUS_RESOURCES;
  926. break;
  927. }
  928. NdisZeroMemory(Adapter->HwMiscMemAllocVa, Adapter->HwMiscMemAllocSize);
  929. pMem = Adapter->HwMiscMemAllocVa;
  930. MemPhys = NdisGetPhysicalAddressLow(Adapter->HwMiscMemAllocPa);
  931. Adapter->SelfTest = (PSELF_TEST_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
  932. Adapter->SelfTestPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
  933. pMem = (PUCHAR)Adapter->SelfTest + sizeof(SELF_TEST_STRUC);
  934. MemPhys = Adapter->SelfTestPhys + sizeof(SELF_TEST_STRUC);
  935. Adapter->NonTxCmdBlock = (PNON_TRANSMIT_CB)MP_ALIGNMEM(pMem, ALIGN_16);
  936. Adapter->NonTxCmdBlockPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
  937. pMem = (PUCHAR)Adapter->NonTxCmdBlock + sizeof(NON_TRANSMIT_CB);
  938. MemPhys = Adapter->NonTxCmdBlockPhys + sizeof(NON_TRANSMIT_CB);
  939. Adapter->DumpSpace = (PDUMP_AREA_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
  940. Adapter->DumpSpacePhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
  941. pMem = (PUCHAR)Adapter->DumpSpace + sizeof(DUMP_AREA_STRUC);
  942. MemPhys = Adapter->DumpSpacePhys + sizeof(DUMP_AREA_STRUC);
  943. Adapter->StatsCounters = (PERR_COUNT_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
  944. Adapter->StatsCounterPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
  945. // HW_END
  946. //
  947. // Recv
  948. //
  949. NdisInitializeNPagedLookasideList(
  950. &Adapter->RecvLookaside,
  951. NULL,
  952. NULL,
  953. 0,
  954. sizeof(MP_RFD),
  955. NIC_TAG,
  956. 0);
  957. MP_SET_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE);
  958. // set the max number of RFDs
  959. // disable the RFD grow/shrink scheme if user specifies a NumRfd value
  960. // larger than NIC_MAX_GROW_RFDS
  961. Adapter->MaxNumRfd = max(Adapter->NumRfd, NIC_MAX_GROW_RFDS);
  962. DBGPRINT(MP_INFO, ("NumRfd = %d\n", Adapter->NumRfd));
  963. DBGPRINT(MP_INFO, ("MaxNumRfd = %d\n", Adapter->MaxNumRfd));
  964. Adapter->HwRfdSize = sizeof(RFD_STRUC);
  965. // alloc the recv packet pool
  966. NdisAllocatePacketPoolEx(
  967. &Status,
  968. &Adapter->RecvPacketPool,
  969. Adapter->NumRfd,
  970. Adapter->MaxNumRfd,
  971. sizeof(PVOID) * 4);
  972. if (Status != NDIS_STATUS_SUCCESS)
  973. {
  974. ErrorValue = ERRLOG_OUT_OF_PACKET_POOL;
  975. break;
  976. }
  977. // alloc the buffer pool
  978. NdisAllocateBufferPool(
  979. &Status,
  980. &Adapter->RecvBufferPool,
  981. Adapter->MaxNumRfd);
  982. if (Status != NDIS_STATUS_SUCCESS)
  983. {
  984. ErrorValue = ERRLOG_OUT_OF_BUFFER_POOL;
  985. break;
  986. }
  987. Status = NDIS_STATUS_SUCCESS;
  988. } while (FALSE);
  989. if (Status != NDIS_STATUS_SUCCESS)
  990. {
  991. NdisWriteErrorLogEntry(
  992. Adapter->AdapterHandle,
  993. NDIS_ERROR_CODE_OUT_OF_RESOURCES,
  994. 1,
  995. ErrorValue);
  996. }
  997. #if OFFLOAD
  998. // Allocate the shared memory for the offloading packet
  999. // this miniport use this shared memory when OFFLAOD is on
  1000. for (i = 0; i < LARGE_SEND_MEM_SIZE_OPTION; i++)
  1001. {
  1002. NdisMAllocateSharedMemory(
  1003. Adapter->AdapterHandle,
  1004. LargeSendSharedMemArray[i],
  1005. FALSE,
  1006. (PVOID *)&(Adapter->OffloadSharedMem.StartVa),
  1007. &(Adapter->OffloadSharedMem.PhyAddr));
  1008. if (Adapter->OffloadSharedMem.StartVa)
  1009. {
  1010. Adapter->OffloadSharedMemSize = LargeSendSharedMemArray[i];
  1011. OffloadSharedMemSuccess = TRUE;
  1012. Adapter->OffloadEnable = TRUE;
  1013. break;
  1014. }
  1015. }
  1016. if (OffloadSharedMemSuccess == FALSE)
  1017. {
  1018. ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
  1019. DBGPRINT(MP_ERROR, ("Failed to allocate offload used memory\n"));
  1020. Adapter->OffloadEnable = FALSE;
  1021. }
  1022. #endif
  1023. DBGPRINT_S(Status, ("<-- NICAllocMemory, Status=%x\n", Status));
  1024. return Status;
  1025. }
  1026. VOID NICInitSend(
  1027. IN PMP_ADAPTER Adapter)
  1028. /*++
  1029. Routine Description:
  1030. Initialize send data structures
  1031. Arguments:
  1032. Adapter Pointer to our adapter
  1033. Return Value:
  1034. None
  1035. --*/
  1036. {
  1037. PMP_TCB pMpTcb;
  1038. PHW_TCB pHwTcb;
  1039. ULONG HwTcbPhys;
  1040. LONG TcbCount;
  1041. PTBD_STRUC pHwTbd;
  1042. ULONG HwTbdPhys;
  1043. DBGPRINT(MP_TRACE, ("--> NICInitSend\n"));
  1044. Adapter->TransmitIdle = TRUE;
  1045. Adapter->ResumeWait = TRUE;
  1046. // Setup the initial pointers to the SW and HW TCB data space
  1047. pMpTcb = (PMP_TCB) Adapter->MpTcbMem;
  1048. pHwTcb = (PHW_TCB) Adapter->HwSendMemAllocVa;
  1049. HwTcbPhys = NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);
  1050. // Setup the initial pointers to the TBD data space.
  1051. // TBDs are located immediately following the TCBs
  1052. pHwTbd = (PTBD_STRUC) (Adapter->HwSendMemAllocVa +
  1053. (sizeof(TXCB_STRUC) * Adapter->NumTcb));
  1054. HwTbdPhys = HwTcbPhys + (sizeof(TXCB_STRUC) * Adapter->NumTcb);
  1055. // Go through and set up each TCB
  1056. for (TcbCount = 0; TcbCount < Adapter->NumTcb; TcbCount++)
  1057. {
  1058. pMpTcb->HwTcb = pHwTcb; // save ptr to HW TCB
  1059. pMpTcb->HwTcbPhys = HwTcbPhys; // save HW TCB physical address
  1060. pMpTcb->HwTbd = pHwTbd; // save ptr to TBD array
  1061. pMpTcb->HwTbdPhys = HwTbdPhys; // save TBD array physical address
  1062. if (TcbCount)
  1063. pMpTcb->PrevHwTcb = pHwTcb - 1;
  1064. else
  1065. pMpTcb->PrevHwTcb = (PHW_TCB)((PUCHAR)Adapter->HwSendMemAllocVa +
  1066. ((Adapter->NumTcb - 1) * sizeof(HW_TCB)));
  1067. pHwTcb->TxCbHeader.CbStatus = 0; // clear the status
  1068. pHwTcb->TxCbHeader.CbCommand = CB_EL_BIT | CB_TX_SF_BIT | CB_TRANSMIT;
  1069. // Set the link pointer in HW TCB to the next TCB in the chain.
  1070. // If this is the last TCB in the chain, then set it to the first TCB.
  1071. if (TcbCount < Adapter->NumTcb - 1)
  1072. {
  1073. pMpTcb->Next = pMpTcb + 1;
  1074. pHwTcb->TxCbHeader.CbLinkPointer = HwTcbPhys + sizeof(HW_TCB);
  1075. }
  1076. else
  1077. {
  1078. pMpTcb->Next = (PMP_TCB) Adapter->MpTcbMem;
  1079. pHwTcb->TxCbHeader.CbLinkPointer =
  1080. NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);
  1081. }
  1082. pHwTcb->TxCbThreshold = (UCHAR) Adapter->AiThreshold;
  1083. pHwTcb->TxCbTbdPointer = HwTbdPhys;
  1084. pMpTcb++;
  1085. pHwTcb++;
  1086. HwTcbPhys += sizeof(TXCB_STRUC);
  1087. pHwTbd = (PTBD_STRUC)((PUCHAR)pHwTbd + sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT);
  1088. HwTbdPhys += sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT;
  1089. }
  1090. // set the TCB head/tail indexes
  1091. // head is the olded one to free, tail is the next one to use
  1092. Adapter->CurrSendHead = (PMP_TCB) Adapter->MpTcbMem;
  1093. Adapter->CurrSendTail = (PMP_TCB) Adapter->MpTcbMem;
  1094. // set the map register head/tail indexes if used
  1095. if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_MAP_REGISTER))
  1096. {
  1097. Adapter->CurrMapRegHead = 0;
  1098. Adapter->CurrMapRegTail = 0;
  1099. }
  1100. DBGPRINT(MP_TRACE, ("<-- NICInitSend, Status=%x\n"));
  1101. }
  1102. NDIS_STATUS NICInitRecv(
  1103. IN PMP_ADAPTER Adapter)
  1104. /*++
  1105. Routine Description:
  1106. Initialize receive data structures
  1107. Arguments:
  1108. Adapter Pointer to our adapter
  1109. Return Value:
  1110. NDIS_STATUS_SUCCESS
  1111. NDIS_STATUS_RESOURCES
  1112. --*/
  1113. {
  1114. NDIS_STATUS Status = NDIS_STATUS_RESOURCES;
  1115. PMP_RFD pMpRfd;
  1116. LONG RfdCount;
  1117. ULONG ErrorValue = 0;
  1118. DBGPRINT(MP_TRACE, ("--> NICInitRecv\n"));
  1119. // Setup each RFD
  1120. for (RfdCount = 0; RfdCount < Adapter->NumRfd; RfdCount++)
  1121. {
  1122. pMpRfd = NdisAllocateFromNPagedLookasideList(&Adapter->RecvLookaside);
  1123. if (!pMpRfd)
  1124. {
  1125. ErrorValue = ERRLOG_OUT_OF_LOOKASIDE_MEMORY;
  1126. continue;
  1127. }
  1128. // Allocate the shared memory for this RFD.
  1129. NdisMAllocateSharedMemory(
  1130. Adapter->AdapterHandle,
  1131. Adapter->HwRfdSize,
  1132. FALSE,
  1133. &pMpRfd->HwRfd,
  1134. &pMpRfd->HwRfdPa);
  1135. if (!pMpRfd->HwRfd)
  1136. {
  1137. ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
  1138. NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
  1139. continue;
  1140. }
  1141. ErrorValue = NICAllocRfd(Adapter, pMpRfd);
  1142. if (ErrorValue)
  1143. {
  1144. NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
  1145. continue;
  1146. }
  1147. // Add this RFD to the RecvList
  1148. Adapter->CurrNumRfd++;
  1149. NICReturnRFD(Adapter, pMpRfd);
  1150. }
  1151. if (Adapter->CurrNumRfd > NIC_MIN_RFDS)
  1152. {
  1153. Status = NDIS_STATUS_SUCCESS;
  1154. }
  1155. if (Status != NDIS_STATUS_SUCCESS)
  1156. {
  1157. NdisWriteErrorLogEntry(
  1158. Adapter->AdapterHandle,
  1159. NDIS_ERROR_CODE_OUT_OF_RESOURCES,
  1160. 1,
  1161. ErrorValue);
  1162. NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
  1163. }
  1164. DBGPRINT_S(Status, ("<-- NICInitRecv, Status=%x\n", Status));
  1165. return Status;
  1166. }
  1167. ULONG NICAllocRfd(
  1168. IN PMP_ADAPTER Adapter,
  1169. IN PMP_RFD pMpRfd)
  1170. /*++
  1171. Routine Description:
  1172. Allocate NDIS_PACKET and NDIS_BUFFER associated with a RFD
  1173. Arguments:
  1174. Adapter Pointer to our adapter
  1175. pMpRfd pointer to a RFD
  1176. Return Value:
  1177. ERRLOG_OUT_OF_NDIS_PACKET
  1178. ERRLOG_OUT_OF_NDIS_BUFFER
  1179. --*/
  1180. {
  1181. NDIS_STATUS Status;
  1182. PHW_RFD pHwRfd;
  1183. ULONG HwRfdPhys;
  1184. ULONG ErrorValue = 0;
  1185. do
  1186. {
  1187. pHwRfd = pMpRfd->HwRfd;
  1188. pMpRfd->HwRfdPhys = NdisGetPhysicalAddressLow(pMpRfd->HwRfdPa);
  1189. pMpRfd->Flags = 0;
  1190. pMpRfd->NdisPacket = NULL;
  1191. pMpRfd->NdisBuffer = NULL;
  1192. NdisAllocatePacket(
  1193. &Status,
  1194. &pMpRfd->NdisPacket,
  1195. Adapter->RecvPacketPool);
  1196. if (Status != NDIS_STATUS_SUCCESS)
  1197. {
  1198. ASSERT(pMpRfd->NdisPacket == NULL);
  1199. ErrorValue = ERRLOG_OUT_OF_NDIS_PACKET;
  1200. break;
  1201. }
  1202. // point our buffer for receives at this Rfd
  1203. NdisAllocateBuffer(
  1204. &Status,
  1205. &pMpRfd->NdisBuffer,
  1206. Adapter->RecvBufferPool,
  1207. (PVOID)&pHwRfd->RfdBuffer.RxMacHeader,
  1208. NIC_MAX_PACKET_SIZE);
  1209. if (Status != NDIS_STATUS_SUCCESS)
  1210. {
  1211. ASSERT(pMpRfd->NdisBuffer == NULL);
  1212. ErrorValue = ERRLOG_OUT_OF_NDIS_BUFFER;
  1213. break;
  1214. }
  1215. // Init each RFD header
  1216. pHwRfd->RfdRbdPointer = DRIVER_NULL;
  1217. pHwRfd->RfdSize = NIC_MAX_PACKET_SIZE;
  1218. NDIS_SET_PACKET_HEADER_SIZE(pMpRfd->NdisPacket, NIC_HEADER_SIZE);
  1219. NdisChainBufferAtFront(pMpRfd->NdisPacket, pMpRfd->NdisBuffer);
  1220. // Save ptr to MP_RFD in the packet, used in MPReturnPackets
  1221. MP_SET_PACKET_RFD(pMpRfd->NdisPacket, pMpRfd);
  1222. return ErrorValue;
  1223. } while (FALSE);
  1224. if (ErrorValue)
  1225. {
  1226. if (pMpRfd->NdisPacket)
  1227. {
  1228. NdisFreePacket(pMpRfd->NdisPacket);
  1229. }
  1230. if (pMpRfd->HwRfd)
  1231. {
  1232. NdisMFreeSharedMemory(
  1233. Adapter->AdapterHandle,
  1234. Adapter->HwRfdSize,
  1235. FALSE,
  1236. pMpRfd->HwRfd,
  1237. pMpRfd->HwRfdPa);
  1238. }
  1239. }
  1240. return ErrorValue;
  1241. }
  1242. VOID NICFreeRfd(
  1243. IN PMP_ADAPTER Adapter,
  1244. IN PMP_RFD pMpRfd)
  1245. /*++
  1246. Routine Description:
  1247. Free a RFD and assocaited NDIS_PACKET and NDIS_BUFFER
  1248. Arguments:
  1249. Adapter Pointer to our adapter
  1250. pMpRfd Pointer to a RFD
  1251. Return Value:
  1252. None
  1253. --*/
  1254. {
  1255. ASSERT(pMpRfd->NdisBuffer);
  1256. ASSERT(pMpRfd->NdisPacket);
  1257. ASSERT(pMpRfd->HwRfd);
  1258. NdisFreeBuffer(pMpRfd->NdisBuffer);
  1259. NdisFreePacket(pMpRfd->NdisPacket);
  1260. pMpRfd->NdisBuffer = NULL;
  1261. pMpRfd->NdisPacket = NULL;
  1262. NdisMFreeSharedMemory(
  1263. Adapter->AdapterHandle,
  1264. Adapter->HwRfdSize,
  1265. FALSE,
  1266. pMpRfd->HwRfd,
  1267. pMpRfd->HwRfdPa);
  1268. pMpRfd->HwRfd = NULL;
  1269. NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
  1270. }
  1271. NDIS_STATUS NICSelfTest(
  1272. IN PMP_ADAPTER Adapter)
  1273. /*++
  1274. Routine Description:
  1275. Perform a NIC self-test
  1276. Arguments:
  1277. Adapter Pointer to our adapter
  1278. Return Value:
  1279. NDIS_STATUS_SUCCESS
  1280. NDIS_STATUS_DEVICE_FAILED
  1281. --*/
  1282. {
  1283. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1284. ULONG SelfTestCommandCode;
  1285. DBGPRINT(MP_TRACE, ("--> NICSelfTest\n"));
  1286. DBGPRINT(MP_INFO, ("SelfTest=%x, SelfTestPhys=%x\n",
  1287. Adapter->SelfTest, Adapter->SelfTestPhys));
  1288. // Issue a software reset to the adapter
  1289. HwSoftwareReset(Adapter);
  1290. // Execute The PORT Self Test Command On The 82558.
  1291. ASSERT(Adapter->SelfTestPhys != 0);
  1292. SelfTestCommandCode = Adapter->SelfTestPhys;
  1293. // Setup SELF TEST Command Code in D3 - D0
  1294. SelfTestCommandCode |= PORT_SELFTEST;
  1295. // Initialize the self-test signature and results DWORDS
  1296. Adapter->SelfTest->StSignature = 0;
  1297. Adapter->SelfTest->StResults = 0xffffffff;
  1298. // Do the port command
  1299. Adapter->CSRAddress->Port = SelfTestCommandCode;
  1300. MP_STALL_EXECUTION(NIC_DELAY_POST_SELF_TEST_MS);
  1301. // if The First Self Test DWORD Still Zero, We've timed out. If the second
  1302. // DWORD is not zero then we have an error.
  1303. if ((Adapter->SelfTest->StSignature == 0) || (Adapter->SelfTest->StResults != 0))
  1304. {
  1305. DBGPRINT(MP_ERROR, ("StSignature=%x, StResults=%x\n",
  1306. Adapter->SelfTest->StSignature, Adapter->SelfTest->StResults));
  1307. NdisWriteErrorLogEntry(
  1308. Adapter->AdapterHandle,
  1309. NDIS_ERROR_CODE_HARDWARE_FAILURE,
  1310. 1,
  1311. ERRLOG_SELFTEST_FAILED);
  1312. Status = NDIS_STATUS_DEVICE_FAILED;
  1313. }
  1314. DBGPRINT_S(Status, ("<-- NICSelfTest, Status=%x\n", Status));
  1315. return Status;
  1316. }
  1317. NDIS_STATUS NICInitializeAdapter(
  1318. IN PMP_ADAPTER Adapter)
  1319. /*++
  1320. Routine Description:
  1321. Initialize the adapter and set up everything
  1322. Arguments:
  1323. Adapter Pointer to our adapter
  1324. Return Value:
  1325. NDIS_STATUS_SUCCESS
  1326. NDIS_STATUS_HARD_ERRORS
  1327. --*/
  1328. {
  1329. NDIS_STATUS Status;
  1330. USHORT EepromFlags;
  1331. DBGPRINT(MP_TRACE, ("--> NICInitializeAdapter\n"));
  1332. do
  1333. {
  1334. // set up our link indication variable
  1335. // it doesn't matter what this is right now because it will be
  1336. // set correctly if link fails
  1337. Adapter->MediaState = NdisMediaStateConnected;
  1338. Adapter->CurrentPowerState = NdisDeviceStateD0;
  1339. Adapter->NextPowerState = NdisDeviceStateD0;
  1340. // Issue a software reset to the D100
  1341. HwSoftwareReset(Adapter);
  1342. // Load the CU BASE (set to 0, because we use linear mode)
  1343. Adapter->CSRAddress->ScbGeneralPointer = 0;
  1344. Status = D100IssueScbCommand(Adapter, SCB_CUC_LOAD_BASE, FALSE);
  1345. if (Status != NDIS_STATUS_SUCCESS)
  1346. {
  1347. break;
  1348. }
  1349. // Wait for the SCB command word to clear before we set the general pointer
  1350. if (!WaitScb(Adapter))
  1351. {
  1352. Status = NDIS_STATUS_HARD_ERRORS;
  1353. break;
  1354. }
  1355. // Load the RU BASE (set to 0, because we use linear mode)
  1356. Adapter->CSRAddress->ScbGeneralPointer = 0;
  1357. Status = D100IssueScbCommand(Adapter, SCB_RUC_LOAD_BASE, FALSE);
  1358. if (Status != NDIS_STATUS_SUCCESS)
  1359. {
  1360. break;
  1361. }
  1362. // Configure the adapter
  1363. Status = HwConfigure(Adapter);
  1364. if (Status != NDIS_STATUS_SUCCESS) break;
  1365. Status = HwSetupIAAddress(Adapter);
  1366. if (Status != NDIS_STATUS_SUCCESS) break;
  1367. // Clear the internal counters
  1368. HwClearAllCounters(Adapter);
  1369. } while (FALSE);
  1370. if (Status != NDIS_STATUS_SUCCESS)
  1371. {
  1372. NdisWriteErrorLogEntry(
  1373. Adapter->AdapterHandle,
  1374. NDIS_ERROR_CODE_HARDWARE_FAILURE,
  1375. 1,
  1376. ERRLOG_INITIALIZE_ADAPTER);
  1377. }
  1378. DBGPRINT_S(Status, ("<-- NICInitializeAdapter, Status=%x\n", Status));
  1379. return Status;
  1380. }
  1381. VOID HwSoftwareReset(
  1382. IN PMP_ADAPTER Adapter)
  1383. /*++
  1384. Routine Description:
  1385. Issue a software reset to the hardware
  1386. Arguments:
  1387. Adapter Pointer to our adapter
  1388. Return Value:
  1389. None
  1390. --*/
  1391. {
  1392. DBGPRINT(MP_TRACE, ("--> HwSoftwareReset\n"));
  1393. // Issue a PORT command with a data word of 0
  1394. Adapter->CSRAddress->Port = PORT_SOFTWARE_RESET;
  1395. // wait after the port reset command
  1396. NdisStallExecution(NIC_DELAY_POST_RESET);
  1397. // Mask off our interrupt line -- its unmasked after reset
  1398. NICDisableInterrupt(Adapter);
  1399. DBGPRINT(MP_TRACE, ("<-- HwSoftwareReset\n"));
  1400. }
  1401. NDIS_STATUS HwConfigure(
  1402. IN PMP_ADAPTER Adapter)
  1403. /*++
  1404. Routine Description:
  1405. Configure the hardware
  1406. Arguments:
  1407. Adapter Pointer to our adapter
  1408. Return Value:
  1409. NDIS_STATUS_SUCCESS
  1410. NDIS_STATUS_HARD_ERRORS
  1411. --*/
  1412. {
  1413. NDIS_STATUS Status;
  1414. PCB_HEADER_STRUC NonTxCmdBlockHdr = (PCB_HEADER_STRUC)Adapter->NonTxCmdBlock;
  1415. UINT i;
  1416. DBGPRINT(MP_TRACE, ("--> HwConfigure\n"));
  1417. // Init the packet filter to nothing.
  1418. Adapter->PacketFilter = 0;
  1419. //
  1420. // Store the current setting for BROADCAST/PROMISCUOS modes
  1421. Adapter->OldParameterField = CB_557_CFIG_DEFAULT_PARM15;
  1422. // Setup the non-transmit command block header for the configure command.
  1423. NonTxCmdBlockHdr->CbStatus = 0;
  1424. NonTxCmdBlockHdr->CbCommand = CB_CONFIGURE;
  1425. NonTxCmdBlockHdr->CbLinkPointer = DRIVER_NULL;
  1426. // Fill in the configure command data.
  1427. // First fill in the static (end user can't change) config bytes
  1428. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[0] = CB_557_CFIG_DEFAULT_PARM0;
  1429. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[2] = CB_557_CFIG_DEFAULT_PARM2;
  1430. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] = CB_557_CFIG_DEFAULT_PARM3;
  1431. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] = CB_557_CFIG_DEFAULT_PARM6;
  1432. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[9] = CB_557_CFIG_DEFAULT_PARM9;
  1433. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[10] = CB_557_CFIG_DEFAULT_PARM10;
  1434. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[11] = CB_557_CFIG_DEFAULT_PARM11;
  1435. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[12] = CB_557_CFIG_DEFAULT_PARM12;
  1436. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[13] = CB_557_CFIG_DEFAULT_PARM13;
  1437. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[14] = CB_557_CFIG_DEFAULT_PARM14;
  1438. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[16] = CB_557_CFIG_DEFAULT_PARM16;
  1439. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[17] = CB_557_CFIG_DEFAULT_PARM17;
  1440. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[18] = CB_557_CFIG_DEFAULT_PARM18;
  1441. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[20] = CB_557_CFIG_DEFAULT_PARM20;
  1442. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] = CB_557_CFIG_DEFAULT_PARM21;
  1443. // Now fill in the rest of the configuration bytes (the bytes that contain
  1444. // user configurable parameters).
  1445. // Set the Tx and Rx Fifo limits
  1446. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[1] =
  1447. (UCHAR) ((Adapter->AiTxFifo << 4) | Adapter->AiRxFifo);
  1448. if (Adapter->MWIEnable)
  1449. {
  1450. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] |= CB_CFIG_B3_MWI_ENABLE;
  1451. }
  1452. // Set the Tx and Rx DMA maximum byte count fields.
  1453. if ((Adapter->AiRxDmaCount) || (Adapter->AiTxDmaCount))
  1454. {
  1455. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
  1456. Adapter->AiRxDmaCount;
  1457. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
  1458. (UCHAR) (Adapter->AiTxDmaCount | CB_CFIG_DMBC_EN);
  1459. }
  1460. else
  1461. {
  1462. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
  1463. CB_557_CFIG_DEFAULT_PARM4;
  1464. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
  1465. CB_557_CFIG_DEFAULT_PARM5;
  1466. }
  1467. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
  1468. (UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 & (~CB_CFIG_URUN_RETRY)) |
  1469. (Adapter->AiUnderrunRetry << 1)
  1470. );
  1471. // Setup for MII or 503 operation. The CRS+CDT bit should only be set
  1472. // when operating in 503 mode.
  1473. if (Adapter->PhyAddress == 32)
  1474. {
  1475. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
  1476. (CB_557_CFIG_DEFAULT_PARM8 & (~CB_CFIG_503_MII));
  1477. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
  1478. (CB_557_CFIG_DEFAULT_PARM15 | CB_CFIG_CRS_OR_CDT);
  1479. }
  1480. else
  1481. {
  1482. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
  1483. (CB_557_CFIG_DEFAULT_PARM8 | CB_CFIG_503_MII);
  1484. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
  1485. ((CB_557_CFIG_DEFAULT_PARM15 & (~CB_CFIG_CRS_OR_CDT)) | CB_CFIG_BROADCAST_DIS);
  1486. }
  1487. // Setup Full duplex stuff
  1488. // If forced to half duplex
  1489. if (Adapter->AiForceDpx == 1)
  1490. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
  1491. (CB_557_CFIG_DEFAULT_PARM19 &
  1492. (~(CB_CFIG_FORCE_FDX| CB_CFIG_FDX_ENABLE)));
  1493. // If forced to full duplex
  1494. else if (Adapter->AiForceDpx == 2)
  1495. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
  1496. (CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
  1497. // If auto-duplex
  1498. else
  1499. {
  1500. // We must force full duplex on if we are using PHY 0, and we are
  1501. // supposed to run in FDX mode. We do this because the D100 has only
  1502. // one FDX# input pin, and that pin will be connected to PHY 1.
  1503. if ((Adapter->PhyAddress == 0) && (Adapter->usDuplexMode == 2))
  1504. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
  1505. (CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
  1506. else
  1507. Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
  1508. CB_557_CFIG_DEFAULT_PARM19;
  1509. }
  1510. // display the config info to the debugger
  1511. DBGPRINT(MP_INFO, (" Issuing Configure command\n"));
  1512. DBGPRINT(MP_INFO, (" Config Block at virt addr "PTR_FORMAT", phys address %x\n",
  1513. &NonTxCmdBlockHdr->CbStatus, Adapter->NonTxCmdBlockPhys));
  1514. for (i=0; i < CB_CFIG_BYTE_COUNT; i++)
  1515. DBGPRINT(MP_INFO, (" Config byte %x = %.2x\n",
  1516. i, Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[i]));
  1517. // Wait for the SCB command word to clear before we set the general pointer
  1518. if (!WaitScb(Adapter))
  1519. {
  1520. Status = NDIS_STATUS_HARD_ERRORS;
  1521. }
  1522. else
  1523. {
  1524. ASSERT(Adapter->CSRAddress->ScbCommandLow == 0)
  1525. Adapter->CSRAddress->ScbGeneralPointer = Adapter->NonTxCmdBlockPhys;
  1526. // Submit the configure command to the chip, and wait for it to complete.
  1527. Status = D100SubmitCommandBlockAndWait(Adapter);
  1528. }
  1529. DBGPRINT_S(Status, ("<-- HwConfigure, Status=%x\n", Status));
  1530. return Status;
  1531. }
  1532. NDIS_STATUS HwSetupIAAddress(
  1533. IN PMP_ADAPTER Adapter)
  1534. /*++
  1535. Routine Description:
  1536. Set up the individual MAC address
  1537. Arguments:
  1538. Adapter Pointer to our adapter
  1539. Return Value:
  1540. NDIS_STATUS_SUCCESS
  1541. NDIS_SUCCESS_HARD_ERRORS
  1542. --*/
  1543. {
  1544. NDIS_STATUS Status;
  1545. UINT i;
  1546. PCB_HEADER_STRUC NonTxCmdBlockHdr = (PCB_HEADER_STRUC)Adapter->NonTxCmdBlock;
  1547. DBGPRINT(MP_TRACE, ("--> HwSetupIAAddress\n"));
  1548. // Individual Address Setup
  1549. NonTxCmdBlockHdr->CbStatus = 0;
  1550. NonTxCmdBlockHdr->CbCommand = CB_IA_ADDRESS;
  1551. NonTxCmdBlockHdr->CbLinkPointer = DRIVER_NULL;
  1552. // Copy in the station's individual address
  1553. for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++)
  1554. Adapter->NonTxCmdBlock->NonTxCb.Setup.IaAddress[i] = Adapter->CurrentAddress[i];
  1555. // Update the command list pointer. We don't need to do a WaitSCB here
  1556. // because this command is either issued immediately after a reset, or
  1557. // after another command that runs in polled mode. This guarantees that
  1558. // the low byte of the SCB command word will be clear. The only commands
  1559. // that don't run in polled mode are transmit and RU-start commands.
  1560. ASSERT(Adapter->CSRAddress->ScbCommandLow == 0)
  1561. Adapter->CSRAddress->ScbGeneralPointer = Adapter->NonTxCmdBlockPhys;
  1562. // Submit the IA configure command to the chip, and wait for it to complete.
  1563. Status = D100SubmitCommandBlockAndWait(Adapter);
  1564. DBGPRINT_S(Status, ("<-- HwSetupIAAddress, Status=%x\n", Status));
  1565. return Status;
  1566. }
  1567. NDIS_STATUS HwClearAllCounters(
  1568. IN PMP_ADAPTER Adapter)
  1569. /*++
  1570. Routine Description:
  1571. This routine will clear the hardware error statistic counters
  1572. Arguments:
  1573. Adapter Pointer to our adapter
  1574. Return Value:
  1575. NDIS_STATUS_SUCCESS
  1576. NDIS_STATUS_HARD_ERRORS
  1577. --*/
  1578. {
  1579. NDIS_STATUS Status;
  1580. BOOLEAN bResult;
  1581. DBGPRINT(MP_TRACE, ("--> HwClearAllCounters\n"));
  1582. do
  1583. {
  1584. // Load the dump counters pointer. Since this command is generated only
  1585. // after the IA setup has complete, we don't need to wait for the SCB
  1586. // command word to clear
  1587. ASSERT(Adapter->CSRAddress->ScbCommandLow == 0)
  1588. Adapter->CSRAddress->ScbGeneralPointer = Adapter->StatsCounterPhys;
  1589. // Issue the load dump counters address command
  1590. Status = D100IssueScbCommand(Adapter, SCB_CUC_DUMP_ADDR, FALSE);
  1591. if (Status != NDIS_STATUS_SUCCESS) break;
  1592. // Now dump and reset all of the statistics
  1593. Status = D100IssueScbCommand(Adapter, SCB_CUC_DUMP_RST_STAT, TRUE);
  1594. if (Status != NDIS_STATUS_SUCCESS) break;
  1595. // Now wait for the dump/reset to complete, timeout value 2 secs
  1596. MP_STALL_AND_WAIT(Adapter->StatsCounters->CommandComplete == 0xA007, 2000, bResult);
  1597. if (!bResult)
  1598. {
  1599. MP_SET_HARDWARE_ERROR(Adapter);
  1600. Status = NDIS_STATUS_HARD_ERRORS;
  1601. break;
  1602. }
  1603. // init packet counts
  1604. Adapter->GoodTransmits = 0;
  1605. Adapter->GoodReceives = 0;
  1606. // init transmit error counts
  1607. Adapter->TxAbortExcessCollisions = 0;
  1608. Adapter->TxLateCollisions = 0;
  1609. Adapter->TxDmaUnderrun = 0;
  1610. Adapter->TxLostCRS = 0;
  1611. Adapter->TxOKButDeferred = 0;
  1612. Adapter->OneRetry = 0;
  1613. Adapter->MoreThanOneRetry = 0;
  1614. Adapter->TotalRetries = 0;
  1615. // init receive error counts
  1616. Adapter->RcvCrcErrors = 0;
  1617. Adapter->RcvAlignmentErrors = 0;
  1618. Adapter->RcvResourceErrors = 0;
  1619. Adapter->RcvDmaOverrunErrors = 0;
  1620. Adapter->RcvCdtFrames = 0;
  1621. Adapter->RcvRuntErrors = 0;
  1622. } while (FALSE);
  1623. DBGPRINT_S(Status, ("<-- HwClearAllCounters, Status=%x\n", Status));
  1624. return Status;
  1625. }