Leaked source code of windows server 2003
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.

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