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.

1193 lines
33 KiB

  1. /*****************************************************************************
  2. ** **
  3. ** COPYRIGHT (C) 2000, 2001 MKNET CORPORATION **
  4. ** DEVELOPED FOR THE MK7100-BASED VFIR PCI CONTROLLER. **
  5. ** **
  6. *****************************************************************************/
  7. /**********************************************************************
  8. Module Name:
  9. MKINIT.C
  10. Routines:
  11. ClaimAdapter
  12. SetupIrIoMapping
  13. SetupAdapterInfo
  14. AllocAdapterMemory
  15. ReleaseAdapterMemory
  16. FreeAdapterObject
  17. SetupTransmitQueues
  18. SetupReceiveQueues
  19. InitializeMK7
  20. InitializeAdapter
  21. StartAdapter
  22. MK7ResetComplete
  23. ResetTransmitQueues
  24. ResetReceiveQueues
  25. Comments:
  26. Various one-time inits. This involves a combo of inits to the
  27. NDIS env and the MK7100 hw.
  28. **********************************************************************/
  29. #include "precomp.h"
  30. #include "protot.h"
  31. #pragma hdrstop
  32. //-----------------------------------------------------------------------------
  33. // Procedure: [ClaimAdapter]
  34. //
  35. // Description: Locate a MK7-based adapter and assign (claim) the adapter
  36. // hardware. This routine also stores the slot, base IO Address, and IRQ.
  37. //
  38. // Arguments:
  39. // Adapter - ptr to Adapter object instance.
  40. //
  41. // Returns:
  42. // NDIS_STATUS_SUCCESS - If an adapter is successfully found and claimed
  43. // NDIS_STATUS_FAILURE- If an adapter is not found/claimed
  44. //
  45. //-----------------------------------------------------------------------------
  46. NDIS_STATUS
  47. ClaimAdapter(PMK7_ADAPTER Adapter, NDIS_HANDLE WrapperConfigurationContext)
  48. {
  49. USHORT NumPciBoardsFound;
  50. ULONG Bus;
  51. UINT i,j;
  52. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  53. USHORT VendorID = MKNET_PCI_VENDOR_ID;
  54. USHORT DeviceID = MK7_PCI_DEVICE_ID;
  55. PCI_CARDS_FOUND_STRUC PciCardsFound;
  56. PNDIS_RESOURCE_LIST AssignedResources;
  57. DBGLOG("=> ClaimAdapter", 0);
  58. // "Bus" is not used??
  59. Bus = (ULONG) Adapter->BusNumber;
  60. if (Adapter->MKBusType != PCIBUS) {
  61. //Not supported - ISA, EISA or MicroChannel
  62. DBGLOG("<= ClaimAdapter (ERR - 1", 0);
  63. return (NDIS_STATUS_FAILURE);
  64. }
  65. NumPciBoardsFound = FindAndSetupPciDevice(Adapter,
  66. WrapperConfigurationContext,
  67. VendorID,
  68. DeviceID,
  69. &PciCardsFound);
  70. if(NumPciBoardsFound) {
  71. #if DBG
  72. DBGSTR(("\n\n Found the following adapters\n"));
  73. for(i=0; i < NumPciBoardsFound; i++) {
  74. DBGSTR(("slot=%x, io=%x, irq=%x \n",
  75. PciCardsFound.PciSlotInfo[i].SlotNumber,
  76. PciCardsFound.PciSlotInfo[i].BaseIo,
  77. PciCardsFound.PciSlotInfo[i].Irq));
  78. }
  79. #endif
  80. }
  81. else {
  82. DBGSTR(("our PCI board was not found!!!!!!\n"));
  83. MKLogError(Adapter,
  84. EVENT_16,
  85. NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
  86. 0);
  87. DBGLOG("<= ClaimAdapter (ERR - 2", 0);
  88. return (NDIS_STATUS_FAILURE);
  89. }
  90. i = 0; // only one adapter in the system
  91. // NOTE: i == the index into PciCardsFound that we want to use.
  92. //****************************************
  93. // Store our allocated resources in Adapter struct
  94. //****************************************
  95. Adapter->MKSlot = PciCardsFound.PciSlotInfo[i].SlotNumber;
  96. Adapter->MKInterrupt = PciCardsFound.PciSlotInfo[i].Irq;
  97. Adapter->MKBaseIo = PciCardsFound.PciSlotInfo[i].BaseIo;
  98. DBGLOG("<= ClaimAdapter", 0);
  99. return (NDIS_STATUS_SUCCESS);
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Procedure: [SetupIrIoMapping]
  103. //
  104. // Description: This sets up our assigned PCI I/O space w/ NDIS.
  105. //
  106. // Arguments:
  107. // Adapter - ptr to Adapter object instance
  108. //
  109. // Returns:
  110. // NDIS_STATUS_SUCCESS
  111. // not NDIS_STATUS_SUCCESS
  112. //-----------------------------------------------------------------------------
  113. NDIS_STATUS
  114. SetupIrIoMapping(PMK7_ADAPTER Adapter)
  115. {
  116. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  117. DBGFUNC("SetupIrIoMapping");
  118. DBGLOG("=> SetupIrIoMapping", 0);
  119. Adapter->MappedIoRange = Adapter->MKBaseSize;
  120. Status = NdisMRegisterIoPortRange(
  121. (PVOID *) &Adapter->MappedIoBase,
  122. Adapter->MK7AdapterHandle,
  123. (UINT) Adapter->MKBaseIo,
  124. Adapter->MappedIoRange);
  125. DBGSTR(("SetupPciRegs: io=%x, size=%x, stat=%x\n",
  126. Adapter->MKBaseIo, Adapter->MappedIoRange, Status));
  127. if (Status != NDIS_STATUS_SUCCESS) {
  128. DBGSTR(("ERROR: NdisMRegisterIoPortRange failed (Status = 0x%x)\n", Status));
  129. DBGLOG("<= SetupIrIoMapping (ERR)", 0);
  130. return (Status);
  131. }
  132. DBGLOG("<= SetupIrIoMapping", 0);
  133. return (Status);
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Procedure: [SetupAdapterInfo]
  137. //
  138. // Description: Sets up the various adapter fields in the specified Adapter
  139. // object.
  140. // Arguments:
  141. // Adapter - ptr to Adapter object instance
  142. //
  143. // Returns:
  144. // NDIS_STATUS_SUCCESS - If an adapter's IO mapping was setup correctly
  145. // not NDIS_STATUS_SUCCESS- If an adapter's IO space could not be registered
  146. //-----------------------------------------------------------------------------
  147. NDIS_STATUS
  148. SetupAdapterInfo(PMK7_ADAPTER Adapter)
  149. {
  150. NDIS_STATUS Status;
  151. DBGFUNC("SetupAdapterInfo");
  152. DBGLOG("=> SetupAdapterInfo", 0);
  153. // Setup the IR Registers I/O mapping
  154. Status = SetupIrIoMapping(Adapter);
  155. Adapter->InterruptMode = NdisInterruptLevelSensitive;
  156. // Adapter->InterruptMode = NdisInterruptLatched;
  157. DBGLOG("<= SetupAdapterInfo", 0);
  158. return (Status);
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Procedure: [AllocAdapterMemory]
  162. //
  163. // Description: Allocte and setup memory (control structures, shared memory
  164. // data buffers, ring buffers, etc.) for the MK7. Additional setups
  165. // may also be done later on, e.g., TX/RX CB lists, buffer lists, etc.
  166. //
  167. // Arguments:
  168. // Adapter - the adapter structure to allocate for.
  169. //
  170. // Returns:
  171. // NDIS_STATUS_SUCCESS - If the shared memory structures were setup
  172. // not NDIS_STATUS_SUCCESS- If not enough memory or map registers could be
  173. // allocated
  174. //-----------------------------------------------------------------------------
  175. NDIS_STATUS
  176. AllocAdapterMemory(PMK7_ADAPTER Adapter)
  177. {
  178. NDIS_STATUS Status;
  179. ULONG alignedphys;
  180. DBGFUNC("AllocAdapterMemory");
  181. DBGLOG("=> SetupAdapterMemory", 0);
  182. Adapter->MaxPhysicalMappings = MK7_MAXIMUM_PACKET_SIZE_ESC;
  183. //****************************************
  184. // We allocate several chunks of memory. They fall into 2 categories:
  185. // cached and non-cached. Memory that is shared w/ the hw is non-cached
  186. // for reason of simplicity. Cached memory is used for our internal
  187. // sw runtime operations.
  188. //
  189. // The following is done:
  190. // 1. Allocate RRDs and TRDs from non-cached memory. This is the
  191. // Ring descriptors for the hw. (The base address of this is
  192. // set in the Phoenix's Base Address Reg.)
  193. // 2. RX memory --
  194. // I. Alloc cached memory for RCBs and RPDs.
  195. // II. Alloc non-cached for RX DMA data buffers (these are
  196. // mapped to RX packet->buffers).
  197. // 3. TX memory --
  198. // I. Alloc cached for TCBs.
  199. // II. Alloc non-cached for TX DMA data buffers.
  200. //****************************************
  201. //****************************************
  202. // Since we use shared memory (NdisMAllocateSharedMemory), we have to
  203. // call NdisMAllocateMapRegisters even though we don't use such
  204. // mapping. So just ask for 1 map reg.
  205. //****************************************
  206. Adapter->NumMapRegisters = 1;
  207. Status = NdisMAllocateMapRegisters(
  208. Adapter->MK7AdapterHandle,
  209. 0,
  210. FALSE,
  211. Adapter->NumMapRegisters,
  212. Adapter->MaxPhysicalMappings );
  213. if (Status != NDIS_STATUS_SUCCESS) {
  214. Adapter->NumMapRegisters = 0;
  215. MKLogError(Adapter, EVENT_11, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  216. DBGSTR(("NdisMAllocateMapRegister Failed - %x\n", Status));
  217. DBGLOG("<= SetupAdapterMemory: (ERR - NdisMAllocateMapRegister)", 0);
  218. return(Status);
  219. }
  220. //****************************************
  221. // RRDs & TRDs (RX/TX Ring Descriptors)
  222. //
  223. // Allocate shared memory for the Phoenix Ring buffers. Each TRD and
  224. // RRD has a max count (we may not use all). This contiguous space
  225. // holds both the RRDs and TRDs. The 1st 64 entries are RRDs followed
  226. // immediately by 64 TRDs. Hence, the 1st TRD is always a max ring count
  227. // (64x8=512 bytes) from the 1st RRD. We always allocate the max for
  228. // simplicity. Allocate enough extras to align on 1k boundary.
  229. //****************************************
  230. Adapter->RxTxUnCachedSize = 1024 + ( (sizeof(RRD) + sizeof(TRD)) * MAX_RING_SIZE );
  231. NdisMAllocateSharedMemory(Adapter->MK7AdapterHandle,
  232. Adapter->RxTxUnCachedSize,
  233. FALSE, // non-cached
  234. (PVOID) &Adapter->RxTxUnCached,
  235. &Adapter->RxTxUnCachedPhys);
  236. if (Adapter->RxTxUnCached == NULL) {
  237. Adapter->pRrd = Adapter->pTrd = NULL;
  238. MKLogError(Adapter, EVENT_12, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  239. DBGSTR(("ERROR: Failed alloc for RRDs & TRDs\n"));
  240. DBGLOG("<= SetupAdapterMemory: (ERR - RRD/TRD mem)", Adapter->RxTxUnCachedSize);
  241. return (NDIS_STATUS_FAILURE);
  242. }
  243. // Align to 1K boundary.
  244. // NOTE: We don't modify RxTxUnCached. We need it for release later.
  245. alignedphys = NdisGetPhysicalAddressLow(Adapter->RxTxUnCachedPhys);
  246. alignedphys += 0x000003FF;
  247. alignedphys &= (~0x000003FF);
  248. Adapter->pRrdTrdPhysAligned = alignedphys;
  249. Adapter->pRrdTrd = Adapter->RxTxUnCached +
  250. (alignedphys - NdisGetPhysicalAddressLow(Adapter->RxTxUnCachedPhys));
  251. Adapter->pRrd = Adapter->pRrdTrd;
  252. Adapter->pRrdPhys = Adapter->pRrdTrdPhysAligned;
  253. // TRDs are right after RRDs (see Phoenix doc)
  254. Adapter->pTrd = Adapter->pRrd + (sizeof(RRD) * MAX_RING_SIZE);
  255. Adapter->pTrdPhys = Adapter->pRrdPhys + (sizeof(RRD) * MAX_RING_SIZE);
  256. //****************************************
  257. // Allocate RX memory
  258. //
  259. // 1. Cacheable control structures (RCBs, RPDs),
  260. // 2. Non-cacheable DMA buffers.
  261. //****************************************
  262. // RCBs and RPDs (cached)
  263. Adapter->RecvCachedSize = ( Adapter->NumRcb * sizeof(RCB) +
  264. Adapter->NumRpd * sizeof(RPD) );
  265. Status = ALLOC_SYS_MEM(&Adapter->RecvCached, Adapter->RecvCachedSize);
  266. if (Status != NDIS_STATUS_SUCCESS) {
  267. Adapter->RecvCached = (PUCHAR) 0;
  268. MKLogError(Adapter, EVENT_13, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  269. DBGSTR(("ERROR: Failed allocate %d bytes for RecvCached mem\n",
  270. Adapter->RecvCachedSize));
  271. DBGLOG("<= SetupAdapterMemory: (ERR - RCB/RPD mem)", Adapter->RecvCachedSize);
  272. return (Status);
  273. }
  274. DBGSTR(("Allocated %08x %8d bytes for RecvCached mem\n",
  275. Adapter->RecvCached, Adapter->RecvCachedSize));
  276. NdisZeroMemory((PVOID) Adapter->RecvCached, Adapter->RecvCachedSize);
  277. // RX data buffers (non-cached)
  278. // Alignment!?
  279. Adapter->RecvUnCachedSize = (Adapter->NumRpd * RPD_BUFFER_SIZE);
  280. NdisMAllocateSharedMemory(
  281. Adapter->MK7AdapterHandle,
  282. Adapter->RecvUnCachedSize,
  283. FALSE, // non-cached
  284. (PVOID) &Adapter->RecvUnCached,
  285. &Adapter->RecvUnCachedPhys );
  286. if (Adapter->RecvUnCached == NULL) {
  287. MKLogError(Adapter, EVENT_14, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  288. DBGSTR(("ERROR: Failed allocate %d bytes for RecvUnCached mem\n",
  289. Adapter->RecvUnCachedSize));
  290. DBGLOG("<= SetupAdapterMemory: (ERR - RPD buff mem)", Adapter->RecvUnCachedSize);
  291. return (NDIS_STATUS_FAILURE);
  292. }
  293. DBGSTR(("Allocated %08x %8d bytes for RecvUnCached mem\n",
  294. Adapter->RecvUnCached, Adapter->RecvUnCachedSize));
  295. NdisZeroMemory((PVOID) Adapter->RecvUnCached, Adapter->RecvUnCachedSize);
  296. //****************************************
  297. // Allocate TX memory
  298. //
  299. // 1. Cacheable control structure (TCBs),
  300. // 2. Non-cacheable DMA buffers (coalesce).
  301. //****************************************
  302. // TCBs (cached)
  303. Adapter->XmitCachedSize = (Adapter->NumTcb * sizeof(TCB));
  304. Status = ALLOC_SYS_MEM(&Adapter->XmitCached, Adapter->XmitCachedSize);
  305. if (Status != NDIS_STATUS_SUCCESS) {
  306. Adapter->XmitCached = (PUCHAR) 0;
  307. MKLogError(Adapter, EVENT_13, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  308. DBGSTR(("ERROR: Failed allocate %d bytes for XmitCached mem\n",
  309. Adapter->XmitCachedSize));
  310. DBGLOG("<= SetupAdapterMemory: (ERR - TCB mem)", Adapter->XmitCachedSize);
  311. return (Status);
  312. }
  313. DBGSTR(("Allocated %08x %8d bytes for XmitCached mem\n",
  314. Adapter->XmitCached, Adapter->XmitCachedSize));
  315. NdisZeroMemory((PVOID) Adapter->XmitCached, Adapter->XmitCachedSize);
  316. // TX coalesce data buffers (non-cached)
  317. Adapter->XmitUnCachedSize =
  318. ((Adapter->NumTcb + 1) * COALESCE_BUFFER_SIZE);
  319. //****************************************
  320. // Do we need to paragraph align this memory?
  321. //****************************************
  322. NdisMAllocateSharedMemory(
  323. Adapter->MK7AdapterHandle,
  324. Adapter->XmitUnCachedSize,
  325. FALSE,
  326. (PVOID) &Adapter->XmitUnCached,
  327. &Adapter->XmitUnCachedPhys);
  328. if (Adapter->XmitUnCached == NULL) {
  329. MKLogError(Adapter, EVENT_15, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
  330. DBGSTR(("ERROR: Failed allocate %d bytes for XmitUnCached mem\n",
  331. Adapter->XmitUnCachedSize));
  332. DBGLOG("<= SetupAdapterMemory: (ERR - TX buff mem)", (ULONG)0);
  333. return (NDIS_STATUS_FAILURE);
  334. }
  335. DBGSTR(("Allocated %08x %8d bytes for XmitUnCached mem\n",
  336. Adapter->XmitUnCached, Adapter->XmitUnCachedSize));
  337. // initialize this recently allocated area to zeros
  338. NdisZeroMemory((PVOID) Adapter->XmitUnCached, Adapter->XmitUnCachedSize);
  339. DBGLOG("<= SetupAdapterMemory", 0);
  340. return (NDIS_STATUS_SUCCESS);
  341. }
  342. //-----------------------------------------------------------------------------
  343. // Procedure: [ReleaseAdapterMemory]
  344. //
  345. // Description: This is the reverse of AllocAdapterMemory(). We deallocate the
  346. // shared memory data structures for the Adapter structure. This includes
  347. // the both the cached and uncached memory allocations. We also free any
  348. // allocated map registers in this routine.
  349. //
  350. // Arguments:
  351. // Adapter - Ptr to the Adapter structure
  352. //
  353. // Returns: (none)
  354. //-----------------------------------------------------------------------------
  355. VOID
  356. ReleaseAdapterMemory(PMK7_ADAPTER Adapter)
  357. {
  358. UINT i;
  359. PRCB rcb;
  360. PRPD rpd;
  361. DBGFUNC("ReleaseAdapterMemory");
  362. DBGLOG("=> ReleaseAdapterMemory", 0);
  363. //********************
  364. // Release RX memory
  365. //********************
  366. // Packet and buffer descriptors and pools
  367. if (Adapter->ReceivePacketPool) {
  368. DBGLOG("Freeing Packet Pool resources\n", 0);
  369. rcb = Adapter->pRcb;
  370. for (i=0; i<Adapter->NumRcb; i++) {
  371. NdisFreeBuffer(rcb->rpd->ReceiveBuffer);
  372. NdisFreePacket(rcb->rpd->ReceivePacket);
  373. rcb++;
  374. }
  375. rpd = (PRPD) QueuePopHead(&Adapter->FreeRpdList);
  376. while (rpd != (PRPD)NULL) {
  377. NdisFreeBuffer(rpd->ReceiveBuffer);
  378. NdisFreePacket(rpd->ReceivePacket);
  379. rpd = (PRPD) QueuePopHead(&Adapter->FreeRpdList);
  380. }
  381. NdisFreeBufferPool(Adapter->ReceiveBufferPool);
  382. NdisFreePacketPool(Adapter->ReceivePacketPool);
  383. }
  384. // RCBs (cacheable)
  385. if (Adapter->RecvCached) {
  386. DBGLOG("Freeing %d bytes RecvCached\n", Adapter->RecvCachedSize);
  387. NdisFreeMemory((PVOID) Adapter->RecvCached, Adapter->RecvCachedSize, 0);
  388. Adapter->RecvCached = (PUCHAR) 0;
  389. }
  390. // RX shared data buffer memory (non-cacheable)
  391. if (Adapter->RecvUnCached) {
  392. DBGLOG("Freeing %d bytes RecvUnCached\n", Adapter->RecvUnCachedSize);
  393. NdisMFreeSharedMemory(
  394. Adapter->MK7AdapterHandle,
  395. Adapter->RecvUnCachedSize,
  396. FALSE,
  397. (PVOID) Adapter->RecvUnCached,
  398. Adapter->RecvUnCachedPhys);
  399. Adapter->RecvUnCached = (PUCHAR) 0;
  400. }
  401. //********************
  402. // Release TX memory
  403. //********************
  404. // TCBs (cacheable)
  405. if (Adapter->XmitCached) {
  406. DBGLOG("Freeing %d bytes XmitCached\n", Adapter->XmitCachedSize);
  407. NdisFreeMemory((PVOID) Adapter->XmitCached, Adapter->XmitCachedSize, 0);
  408. Adapter->XmitCached = (PUCHAR) 0;
  409. }
  410. // TX shared data buffer memory (non-cacheable)
  411. if (Adapter->XmitUnCached) {
  412. DBGLOG("Freeing %d bytes XmitUnCached\n", Adapter->XmitUnCachedSize);
  413. // Now free the shared memory that was used for the command blocks and
  414. // transmit buffers.
  415. NdisMFreeSharedMemory(
  416. Adapter->MK7AdapterHandle,
  417. Adapter->XmitUnCachedSize,
  418. FALSE,
  419. (PVOID) Adapter->XmitUnCached,
  420. Adapter->XmitUnCachedPhys
  421. );
  422. Adapter->XmitUnCached = (PUCHAR) 0;
  423. }
  424. //********************
  425. // RRDs/TRDs (Ring) & Reg Map (non-cacheable)
  426. //********************
  427. // If this is a miniport driver we must free our allocated map registers
  428. if (Adapter->NumMapRegisters) {
  429. NdisMFreeMapRegisters(Adapter->MK7AdapterHandle);
  430. }
  431. // Now the TRDs & RRDs
  432. if (Adapter->RxTxUnCached) {
  433. NdisMFreeSharedMemory(
  434. Adapter->MK7AdapterHandle,
  435. Adapter->RxTxUnCachedSize,
  436. FALSE,
  437. (PVOID) Adapter->RxTxUnCached,
  438. Adapter->RxTxUnCachedPhys );
  439. }
  440. DBGLOG("<= ReleaseAdapterMemory", 0);
  441. }
  442. //-----------------------------------------------------------------------------
  443. // Procedure: [FreeAdapterObject]
  444. //
  445. // Description: Free all allocated resources for the adapter.
  446. //
  447. // Arguments:
  448. // Adapter - ptr to Adapter object instance
  449. //
  450. // Returns: (none)
  451. //-----------------------------------------------------------------------------
  452. VOID
  453. FreeAdapterObject(PMK7_ADAPTER Adapter)
  454. {
  455. DBGFUNC("FreeAdapterObject");
  456. // The reverse of AllocAdapterMemory().
  457. ReleaseAdapterMemory(Adapter);
  458. // Delete any IO mappings that we have registered
  459. if (Adapter->MappedIoBase) {
  460. NdisMDeregisterIoPortRange(
  461. Adapter->MK7AdapterHandle,
  462. (UINT) Adapter->MKBaseIo,
  463. Adapter->MappedIoRange,
  464. (PVOID) Adapter->MappedIoBase);
  465. }
  466. // free the adapter object itself
  467. FREE_SYS_MEM(Adapter, sizeof(MK7_ADAPTER));
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Procedure: [SetupTransmitQueues]
  471. //
  472. // Description: Setup TRBs, TRDs and TX data buffs at INIT time. This routine
  473. // may also be called at RESET time.
  474. //
  475. // Arguments:
  476. // Adapter - ptr to Adapter object instance
  477. // DebugPrint - A boolean value that will be TRUE if this routine is to
  478. // write all of transmit queue debug info to the debug terminal.
  479. //
  480. // Returns: (none)
  481. //-----------------------------------------------------------------------------
  482. VOID
  483. SetupTransmitQueues(PMK7_ADAPTER Adapter,
  484. BOOLEAN DebugPrint)
  485. {
  486. UINT i;
  487. PTCB tcb;
  488. PTRD trd;
  489. PUCHAR databuff;
  490. ULONG databuffphys;
  491. DBGLOG("=> SetupTransmitQueues", 0);
  492. Adapter->nextAvailTcbIdx = 0;
  493. Adapter->nextReturnTcbIdx = 0;
  494. Adapter->pTcb = (PTCB)Adapter->XmitCached;
  495. tcb = Adapter->pTcb; // TCB
  496. trd = (PTRD)Adapter->pTrd; // TRD
  497. databuff = Adapter->XmitUnCached;
  498. databuffphys = NdisGetPhysicalAddressLow(Adapter->XmitUnCachedPhys);// shared data buffer
  499. //****************************************
  500. // Pair up a TCB w/ a TRD, and init ownership of TRDs to the driver.
  501. // Setup the physical buffer to the Ring descriptor (TRD).
  502. //****************************************
  503. for (i=0; i<Adapter->NumTcb; i++) {
  504. tcb->trd = trd;
  505. tcb->buff = databuff;
  506. tcb->buffphy = databuffphys;
  507. LOGTXPHY(databuffphys); // for debug
  508. trd->count = 0;
  509. trd->status = 0;
  510. trd->addr = (UINT)databuffphys;
  511. GrantTrdToDrv(trd);
  512. Adapter->pTcbArray[i] = tcb;
  513. tcb++;
  514. trd++;
  515. databuff += COALESCE_BUFFER_SIZE;
  516. databuffphys += COALESCE_BUFFER_SIZE;
  517. }
  518. // Initialize the Transmit queueing pointers to NULL
  519. Adapter->FirstTxQueue = (PNDIS_PACKET) NULL;
  520. Adapter->LastTxQueue = (PNDIS_PACKET) NULL;
  521. Adapter->NumPacketsQueued = 0;
  522. DBGLOG("<= SetupTransmitQueues", 0);
  523. }
  524. //-----------------------------------------------------------------------------
  525. // Procedure: [SetupReceiveQueues]
  526. //
  527. // Description: Setup all rx-related descriptors, buffers, etc. using memory
  528. // allocated during init. Also setup our buffers for NDIS 5 and multiple
  529. // receive indications through a packet array.
  530. //
  531. // Arguments:
  532. // Adapter - ptr to Adapter object instance
  533. //
  534. // Returns: (none)
  535. //-----------------------------------------------------------------------------
  536. VOID
  537. SetupReceiveQueues(PMK7_ADAPTER Adapter)
  538. {
  539. UINT i;
  540. PRCB rcb;
  541. PRRD rrd;
  542. PRPD rpd;
  543. PUCHAR databuff;
  544. ULONG databuffphys;
  545. PRPD *TempPtr;
  546. NDIS_STATUS status;
  547. DBGLOG("=> SetupReceiveQueues", 0);
  548. QueueInitList(&Adapter->FreeRpdList);
  549. Adapter->nextRxRcbIdx = 0;
  550. // 4.0.1 BOC
  551. Adapter->UsedRpdCount = 0;
  552. Adapter->rcbPendRpdCnt = 0; // April 8, 2001.
  553. // 4.0.1 EOC
  554. Adapter->pRcb = (PRCB)Adapter->RecvCached;
  555. //****************************************
  556. // Our driver does not currently use async allocs. However, it's
  557. // still true that we have only one buffer per rx packet.
  558. //****************************************
  559. NdisAllocatePacketPool(&status,
  560. &Adapter->ReceivePacketPool,
  561. Adapter->NumRpd,
  562. NUM_BYTES_PROTOCOL_RESERVED_SECTION);
  563. ASSERT(status == NDIS_STATUS_SUCCESS);
  564. NdisAllocateBufferPool(&status,
  565. &Adapter->ReceiveBufferPool,
  566. Adapter->NumRpd);
  567. ASSERT(status == NDIS_STATUS_SUCCESS);
  568. //****************************************
  569. // Pair up a RCB w/ a RRD
  570. //****************************************
  571. rcb = Adapter->pRcb;
  572. rrd = (PRRD)Adapter->pRrd;
  573. for (i=0; i<Adapter->NumRcb; i++) {
  574. rcb->rrd = rrd;
  575. rrd->count = 0;
  576. GrantRrdToHw(rrd);
  577. Adapter->pRcbArray[i] = rcb;
  578. rcb++;
  579. rrd++;
  580. }
  581. //****************************************
  582. // Now set up the RPDs and the data buffers. The RPDs come right
  583. // after the RCBs in RecvCached memory. Put the RPDs on FreeRpdList.
  584. // Map the databuff to NDIS Packet/Buffer.
  585. // "Adapter->pRcb + Adapter->NumRcb" will skip over (NumRcb * sizeof(RCB))
  586. // bytes to get to RPDs because pRcb is ptr to RCB.
  587. //****************************************
  588. rpd = (PRPD) (Adapter->pRcb + Adapter->NumRcb);
  589. databuff = Adapter->RecvUnCached;
  590. databuffphys = NdisGetPhysicalAddressLow(Adapter->RecvUnCachedPhys);
  591. for (i=0; i<Adapter->NumRpd; i++) {
  592. rpd->databuff = databuff;
  593. rpd->databuffphys = databuffphys;
  594. LOGRXPHY(databuffphys);
  595. NdisAllocatePacket(&status,
  596. &rpd->ReceivePacket,
  597. Adapter->ReceivePacketPool);
  598. ASSERT(status== NDIS_STATUS_SUCCESS);
  599. //****************************************
  600. // Set the medium-specific header size in OOB data block.
  601. //****************************************
  602. NDIS_SET_PACKET_HEADER_SIZE(rpd->ReceivePacket, ADDR_SIZE+CONTROL_SIZE);
  603. NdisAllocateBuffer(&status,
  604. &rpd->ReceiveBuffer,
  605. Adapter->ReceiveBufferPool,
  606. (PVOID)databuff,
  607. MK7_MAXIMUM_PACKET_SIZE);
  608. ASSERT(status == NDIS_STATUS_SUCCESS);
  609. NdisChainBufferAtFront(rpd->ReceivePacket, rpd->ReceiveBuffer);
  610. QueuePutTail(&Adapter->FreeRpdList, &rpd->link);
  611. TempPtr = (PRPD *)&rpd->ReceivePacket->MiniportReserved;
  612. *TempPtr = rpd;
  613. rpd++;
  614. databuff += RPD_BUFFER_SIZE;
  615. databuffphys += RPD_BUFFER_SIZE;
  616. }
  617. //****************************************
  618. // Assign a RPB to each RCB, and setup the related RRD's data ptr.
  619. //****************************************
  620. rcb = Adapter->pRcb;
  621. rrd = rcb->rrd;
  622. for (i=0; i<Adapter->NumRcb; i++) {
  623. rpd = (PRPD) QueuePopHead(&Adapter->FreeRpdList);
  624. rcb->rpd = rpd;
  625. rrd->addr = rpd->databuffphys;
  626. rcb++;
  627. rrd = rcb->rrd;
  628. }
  629. }
  630. //-----------------------------------------------------------------------------
  631. // Procedure: [InitializeMK7] (RYM-IRDA)
  632. //
  633. // Description: Init the Phoenix core to SIR mode.
  634. //
  635. // Arguments:
  636. // Adapter - ptr to Adapter object instance
  637. //
  638. // Returns:
  639. // TRUE
  640. // FALSE
  641. //-----------------------------------------------------------------------------
  642. BOOLEAN
  643. InitializeMK7(PMK7_ADAPTER Adapter)
  644. {
  645. ULONG phyaddr;
  646. MK7REG mk7reg;
  647. DBGFUNC("InitializeMK7");
  648. //****************************************
  649. // Setup Ring Base Address & Ring Size. Need to shift down/right
  650. // 10 bits first.
  651. //****************************************
  652. phyaddr = (Adapter->pRrdTrdPhysAligned >> 10);
  653. MK7Reg_Write(Adapter, R_RBAL, (USHORT)phyaddr);
  654. MK7Reg_Write(Adapter, R_RBAU, (USHORT)(phyaddr >> 16));
  655. //****************************************
  656. // RX & TX ring sizes
  657. //
  658. // Now need to do this for RX & TX separately.
  659. //****************************************
  660. mk7reg = 0;
  661. switch(Adapter->NumRcb) {
  662. case 4: mk7reg = RINGSIZE_RX4; break;
  663. case 8: mk7reg = RINGSIZE_RX8; break;
  664. case 16: mk7reg = RINGSIZE_RX16; break;
  665. case 32: mk7reg = RINGSIZE_RX32; break;
  666. case 64: mk7reg = RINGSIZE_RX64; break;
  667. }
  668. switch(Adapter->NumTcb) {
  669. case 4: mk7reg |= RINGSIZE_TX4; break;
  670. case 8: mk7reg |= RINGSIZE_TX8; break;
  671. case 16: mk7reg |= RINGSIZE_TX16; break;
  672. case 32: mk7reg |= RINGSIZE_TX32; break;
  673. case 64: mk7reg |= RINGSIZE_TX64; break;
  674. }
  675. MK7Reg_Write(Adapter, R_RSIZ, mk7reg);
  676. //****************************************
  677. // The following is based on Phoenix's Programming Model
  678. // for SIR mode.
  679. //****************************************
  680. //****************************************
  681. // Step 1: clear IRENALBE
  682. // This is the only writeable bit in this reg so just write it.
  683. //****************************************
  684. MK7Reg_Write(Adapter, R_ENAB, ~B_ENAB_IRENABLE);
  685. //****************************************
  686. // Step 2: MAXRXALLOW
  687. //****************************************
  688. MK7Reg_Write(Adapter, R_MPLN, MK7_MAXIMUM_PACKET_SIZE_ESC);
  689. //****************************************
  690. // Step 3:
  691. // IRCONFIG0 - We init in SIR w/ filter, RX, etc.
  692. //****************************************
  693. #if DBG
  694. if (Adapter->LB == LOOPBACK_HW) {
  695. DBGLOG(" Loopback HW", 0);
  696. // MK7Reg_Write(Adapter, R_CFG0, 0x5C40); // HW loopback: ENTX, ENRX, + below
  697. MK7Reg_Write(Adapter, R_CFG0, 0xDC40); // HW loopback: ENTX, ENRX, + below
  698. }
  699. else {
  700. #endif
  701. // We need to clear EN_MEMSCHD in IRCONFIG0 to reset the TX/RX
  702. // indexes to 0. Eveytime we init we need to do this. Actually we
  703. // just set eveything to zero since we're in ~B_ENAB_IRENABLE mode
  704. // anyway & we do the real setup right away below.
  705. MK7Reg_Write(Adapter, R_CFG0, 0x0000);
  706. if (Adapter->Wireless) {
  707. // WIRELESS: ..., no invert TX
  708. MK7Reg_Write(Adapter, R_CFG0, 0x0E18);
  709. }
  710. else {
  711. // WIRED: ENRX, DMA, small pkts, SIR, SIR RX filter, invert TX
  712. MK7Reg_Write(Adapter, R_CFG0, 0x0E1A);
  713. }
  714. #if DBG
  715. }
  716. #endif
  717. //****************************************
  718. // Step 4:
  719. // Infrared Phy Reg - Baude Rate & Pulse width
  720. //****************************************
  721. mk7reg = HW_SIR_SPEED_9600;
  722. MK7Reg_Write(Adapter, R_CFG2, mk7reg);
  723. //****************************************
  724. // Setup CFG3 - 48Mhz, etc.
  725. //****************************************
  726. //MK7Reg_Write(Adapter, R_CFG3, 0xF606);
  727. // We want to set the following:
  728. // Bit 1 - 1 for 1 RCV pin (for all speeds)
  729. // 2/3 - 48MHz
  730. // 8 - 0 to disable interrupt
  731. // 9 - 0 for SIR
  732. // 11 - 0 for burst mode
  733. MK7Reg_Write(Adapter, R_CFG3, 0xF406);
  734. // Set SEL0/1 for power level control for the 8102. This
  735. // should not affect the 8100.
  736. // IMPORTANT: The FIRSL bit in this register is the same
  737. // as the FIRSL bit in CFG3!
  738. MK7Reg_Write(Adapter, R_GANA, 0x0000);
  739. //
  740. // More one-time inits are done later when we startup the controller
  741. // (see StartMK7()).
  742. //
  743. return (TRUE);
  744. }
  745. //-----------------------------------------------------------------------------
  746. // Procedure: [InitializeAdapter]
  747. //
  748. // Description:
  749. //
  750. // Arguments:
  751. // Adapter - ptr to Adapter object instance
  752. //
  753. // Returns:
  754. // TRUE - If the adapter was initialized
  755. // FALSE - If the adapter failed initialization
  756. //-----------------------------------------------------------------------------
  757. BOOLEAN
  758. InitializeAdapter(PMK7_ADAPTER Adapter)
  759. {
  760. UINT i;
  761. DBGFUNC("InitializeAdapter");
  762. for (i=0; i<NUM_BAUDRATES; i++) {
  763. if (supportedBaudRateTable[i].bitsPerSec <= Adapter->MaxConnSpeed) {
  764. Adapter->AllowedSpeedMask |= supportedBaudRateTable[i].ndisCode;
  765. }
  766. }
  767. Adapter->supportedSpeedsMask = ALL_IRDA_SPEEDS;
  768. Adapter->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
  769. Adapter->CurrentSpeed = DEFAULT_BAUD_RATE; // 9600
  770. //Adapter->extraBOFsRequired = MAX_EXTRA_SIR_BOFS; Now configurable
  771. Adapter->writePending = FALSE;
  772. // Set both TRUE to allow Windows to let us know when it wants an update.
  773. Adapter->mediaBusy = TRUE;
  774. // Adapter->haveIndicatedMediaBusy = TRUE; // 1.0.0
  775. NdisMInitializeTimer(&Adapter->MinTurnaroundTxTimer,
  776. Adapter->MK7AdapterHandle,
  777. (PNDIS_TIMER_FUNCTION)MinTurnaroundTxTimeout,
  778. (PVOID)Adapter);
  779. // 1.0.0
  780. NdisMInitializeTimer(&Adapter->MK7AsyncResetTimer,
  781. Adapter->MK7AdapterHandle,
  782. (PNDIS_TIMER_FUNCTION) MK7ResetComplete,
  783. (PVOID) Adapter);
  784. return (InitializeMK7(Adapter));
  785. }
  786. //----------------------------------------------------------------------
  787. // Procedure: [StartMK7]
  788. //
  789. // Description: All inits are done. Now we can enable the MK7 to
  790. // be able to do RXs and TXs.
  791. //
  792. //----------------------------------------------------------------------
  793. VOID StartMK7(PMK7_ADAPTER Adapter)
  794. {
  795. MK7REG mk7reg;
  796. //****************************************
  797. // The following is based on Phoenix's Programming Model
  798. // for SIR mode.
  799. //****************************************
  800. //****************************************
  801. // Step 5: IR_ENABLE
  802. // Now finish where InitializeMK7() left off. This completes
  803. // the one-time init of the MK7 core.
  804. //****************************************
  805. MK7Reg_Write(Adapter, R_ENAB, B_ENAB_IRENABLE);
  806. MK7Reg_Read(Adapter, R_ENAB, &mk7reg);
  807. // ASSERT(mk7reg == 0x8FFF);
  808. // Still need to do the 1st Prompt. This will be done later
  809. // when we call MK7EnableInterrupt().
  810. }
  811. //----------------------------------------------------------------------
  812. // Procedure: [StartAdapter]
  813. //
  814. // Description: All inits are done. Now we can enable the adapter to
  815. // be able to do RXs and TXs.
  816. //
  817. //----------------------------------------------------------------------
  818. VOID StartAdapter(PMK7_ADAPTER Adapter)
  819. {
  820. StartMK7(Adapter);
  821. }
  822. //-----------------------------------------------------------------------------
  823. // Procedure; [MKResetComplete]
  824. //
  825. // Description: This function is called by a timer indicating our
  826. // reset is done (by way of .5 seconds expiring)
  827. //
  828. // Arguements: NDIS_HANDLE MiniportAdapterContext
  829. //
  830. // Return: nothing, but sets NdisMResetComplete and enables ints.
  831. //-----------------------------------------------------------------------------
  832. VOID
  833. MK7ResetComplete(PVOID sysspiff1,
  834. NDIS_HANDLE MiniportAdapterContext,
  835. PVOID sysspiff2, PVOID sysspiff3)
  836. {
  837. PMK7_ADAPTER Adapter;
  838. MK7REG mk7reg;
  839. // DEBUGFUNC("MKResetComplete");
  840. // INITSTR(("\n"));
  841. Adapter = PMK7_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
  842. // NdisAcquireSpinLock(&Adapter->Lock); 4.0.1
  843. MK7Reg_Read(Adapter, R_INTS, &Adapter->recentInt);
  844. Adapter->recentInt = 0;
  845. MK7SwitchToRXMode(Adapter);
  846. NdisMResetComplete(Adapter->MK7AdapterHandle,
  847. (NDIS_STATUS) NDIS_STATUS_SUCCESS,
  848. TRUE);
  849. Adapter->hardwareStatus = NdisHardwareStatusReady;
  850. Adapter->ResetInProgress = FALSE;
  851. StartMK7(Adapter);
  852. MK7EnableInterrupt(Adapter);
  853. // PSTR("=> NDIS RESET COMPLETE\n\r");
  854. // NdisReleaseSpinLock(&Adapter->Lock); // 4.0.1
  855. }
  856. //-----------------------------------------------------------------------------
  857. // Procedure: [ResetTransmitQueues]
  858. //
  859. // Description: Setup TRBs, TRDs and TX data buffs at INIT time. And Reset
  860. // TCB/RCB Index to zero in both hardware and software
  861. //
  862. // Arguments:
  863. // Adapter - ptr to Adapter object instance
  864. // DebugPrint - A boolean value that will be TRUE if this routine is to
  865. // write all of transmit queue debug info to the debug terminal.
  866. //
  867. // Returns: (none)
  868. //-----------------------------------------------------------------------------
  869. VOID
  870. ResetTransmitQueues(PMK7_ADAPTER Adapter,
  871. BOOLEAN DebugPrint)
  872. {
  873. UINT i;
  874. PTCB tcb;
  875. PTRD trd;
  876. PUCHAR databuff;
  877. ULONG databuffphys;
  878. MK7REG mk7reg;
  879. DBGLOG("=> SetupTransmitQueues", 0);
  880. Adapter->nextAvailTcbIdx = 0;
  881. Adapter->nextReturnTcbIdx = 0;
  882. MK7Reg_Read(Adapter, R_CFG0, &mk7reg);
  883. mk7reg &= 0xfbff;
  884. MK7Reg_Write(Adapter, R_CFG0, mk7reg);
  885. mk7reg |= 0x0400;
  886. MK7Reg_Write(Adapter, R_CFG0, mk7reg);
  887. Adapter->pTcb = (PTCB)Adapter->XmitCached;
  888. tcb = Adapter->pTcb; // TCB
  889. trd = (PTRD)Adapter->pTrd; // TRD
  890. databuff = Adapter->XmitUnCached;
  891. databuffphys = NdisGetPhysicalAddressLow(Adapter->XmitUnCachedPhys);// shared data buffer
  892. //****************************************
  893. // Pair up a TCB w/ a TRD, and init ownership of TRDs to the driver.
  894. // Setup the physical buffer to the Ring descriptor (TRD).
  895. //****************************************
  896. for (i=0; i<Adapter->NumTcb; i++) {
  897. tcb->trd = trd;
  898. tcb->buff = databuff;
  899. tcb->buffphy = databuffphys;
  900. trd->count = 0;
  901. trd->status = 0;
  902. trd->addr = (UINT)databuffphys;
  903. GrantTrdToDrv(trd);
  904. Adapter->pTcbArray[i] = tcb;
  905. tcb++;
  906. trd++;
  907. databuff += COALESCE_BUFFER_SIZE;
  908. databuffphys += COALESCE_BUFFER_SIZE;
  909. }
  910. // Initialize the Transmit queueing pointers to NULL
  911. Adapter->FirstTxQueue = (PNDIS_PACKET) NULL;
  912. Adapter->LastTxQueue = (PNDIS_PACKET) NULL;
  913. Adapter->NumPacketsQueued = 0;
  914. DBGLOG("<= SetupTransmitQueues", 0);
  915. }
  916. //-----------------------------------------------------------------------------
  917. // Procedure: [ResetReceiveQueues]
  918. //
  919. // Description: Reset all the rrd's Ownership to HW
  920. // and byte_counts to zero. All other
  921. // setting (such as rpd) will remain
  922. // same. We do not reset all, because
  923. // some data buffers may still hold by
  924. // by the upper protocol layers.
  925. //
  926. // Arguments:
  927. // Adapter - ptr to Adapter object instance
  928. //
  929. // Returns: (none)
  930. //-----------------------------------------------------------------------------
  931. VOID
  932. ResetReceiveQueues(PMK7_ADAPTER Adapter)
  933. {
  934. UINT i;
  935. PRCB rcb;
  936. PRRD rrd;
  937. DBGLOG("=> SetupReceiveQueues", 0);
  938. Adapter->nextRxRcbIdx = 0;
  939. Adapter->pRcb = (PRCB)Adapter->RecvCached;
  940. //****************************************
  941. // Pair up a RCB w/ a RRD
  942. //****************************************
  943. rcb = Adapter->pRcb;
  944. rrd = (PRRD)Adapter->pRrd;
  945. for (i=0; i<Adapter->NumRcb; i++) {
  946. rcb->rrd = rrd;
  947. rrd->count = 0;
  948. GrantRrdToHw(rrd);
  949. Adapter->pRcbArray[i] = rcb;
  950. rcb++;
  951. rrd++;
  952. }
  953. }