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.

491 lines
11 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. MK7COMM.C
  10. Routines:
  11. MK7Reg_Write
  12. MK7Reg_Read
  13. MK7DisableInterrupt
  14. MK7EnableInterrupt
  15. MK7SwitchToRXMode
  16. MK7SwitchToTXMode
  17. SetSpeed
  18. MK7ChangeSpeedNow
  19. Comments:
  20. **********************************************************************/
  21. #include "precomp.h"
  22. #include "protot.h"
  23. #pragma hdrstop
  24. baudRateInfo supportedBaudRateTable[NUM_BAUDRATES] = {
  25. {
  26. BAUDRATE_2400, // Table index
  27. 2400, // bps
  28. NDIS_IRDA_SPEED_2400, // NDIS bit mask code (NOTE: We don't support
  29. // 2400. We set this bit to 0.)
  30. },
  31. {
  32. BAUDRATE_9600,
  33. 9600,
  34. NDIS_IRDA_SPEED_9600,
  35. },
  36. {
  37. BAUDRATE_19200,
  38. 19200,
  39. NDIS_IRDA_SPEED_19200,
  40. },
  41. {
  42. BAUDRATE_38400,
  43. 38400,
  44. NDIS_IRDA_SPEED_38400,
  45. },
  46. {
  47. BAUDRATE_57600,
  48. 57600,
  49. NDIS_IRDA_SPEED_57600,
  50. },
  51. {
  52. BAUDRATE_115200,
  53. 115200,
  54. NDIS_IRDA_SPEED_115200,
  55. },
  56. {
  57. BAUDRATE_576000,
  58. 576000,
  59. NDIS_IRDA_SPEED_576K,
  60. },
  61. {
  62. BAUDRATE_1152000,
  63. 1152000,
  64. NDIS_IRDA_SPEED_1152K,
  65. },
  66. {
  67. BAUDRATE_4M,
  68. 4000000,
  69. NDIS_IRDA_SPEED_4M,
  70. },
  71. {
  72. BAUDRATE_16M,
  73. 16000000,
  74. NDIS_IRDA_SPEED_16M,
  75. }
  76. };
  77. // Write to IRCONFIG2 w/ these to set SIR/MIR speeds
  78. MK7REG HwSirMirSpeedTable[] = {
  79. HW_SIR_SPEED_2400,
  80. HW_SIR_SPEED_9600,
  81. HW_SIR_SPEED_19200,
  82. HW_SIR_SPEED_38400,
  83. HW_SIR_SPEED_57600,
  84. HW_SIR_SPEED_115200,
  85. HW_MIR_SPEED_576000,
  86. HW_MIR_SPEED_1152000
  87. };
  88. #if DBG
  89. //----------------------------------------------------------------------
  90. //
  91. // NOTE: The following Write and Read routines are bracketed w/ DBG
  92. // switch. In the non-debug version, these 2 calls are inline
  93. // macros for faster execution.
  94. //
  95. //----------------------------------------------------------------------
  96. //----------------------------------------------------------------------
  97. // Procedure: [MK7Reg_Write]
  98. //
  99. // Description: Write to the MK7100 register.
  100. // (Note: In the free build, this is an inline macro. It's
  101. // here in the checked build for debugging.)
  102. //----------------------------------------------------------------------
  103. VOID MK7Reg_Write(PMK7_ADAPTER Adapter, ULONG port, USHORT val)
  104. {
  105. PUCHAR ioport;
  106. // Break this out for debugging
  107. ioport = Adapter->MappedIoBase + port;
  108. NdisRawWritePortUshort(ioport, val);
  109. }
  110. //----------------------------------------------------------------------
  111. // Procedure: [MK7Reg_Read]
  112. //
  113. // Description: Read from MK7100 register.
  114. // (Note: In the free build, this is an inline macro. It's
  115. // here in the checked build for debugging.)
  116. //----------------------------------------------------------------------
  117. VOID MK7Reg_Read(PMK7_ADAPTER Adapter, ULONG port, USHORT *pval)
  118. {
  119. PUCHAR ioport;
  120. // Break this out for debugging
  121. ioport = Adapter->MappedIoBase + port;
  122. NdisRawReadPortUshort(ioport, pval);
  123. }
  124. #endif
  125. //----------------------------------------------------------------------
  126. // Procedure: [MK7DisableInterrupt]
  127. //
  128. // Description: Disable all interrupts on the MK7
  129. //
  130. // Arguments:
  131. // Adapter - ptr to Adapter object instance
  132. //
  133. // Returns:
  134. // NDIS_STATUS_SUCCESS - If an adapter is successfully found and claimed
  135. // NDIS_STATUS_FAILURE - If an adapter is not found/claimed
  136. //
  137. //----------------------------------------------------------------------
  138. NDIS_STATUS MK7DisableInterrupt(PMK7_ADAPTER Adapter)
  139. {
  140. MK7REG mk7reg;
  141. UINT i;
  142. // NOTE: Workaround for potential hw problem where 0xFFFF is returned
  143. for (i=0; i<50; i++) {
  144. MK7Reg_Read(Adapter, R_CFG3, &mk7reg);
  145. if (mk7reg != 0xFFFF) {
  146. break;
  147. }
  148. }
  149. ASSERT(i < 50);
  150. mk7reg &= (~B_ENAB_INT);
  151. MK7Reg_Write(Adapter, R_CFG3, mk7reg);
  152. return(NDIS_STATUS_SUCCESS);
  153. }
  154. //----------------------------------------------------------------------
  155. // Procedure: [MK7EnableInterrupt]
  156. //
  157. // Description: Enable all interrupts on the MK7
  158. //
  159. // Arguments:
  160. // Adapter - ptr to Adapter object instance
  161. //
  162. // Returns:
  163. // NDIS_STATUS_SUCCESS - If an adapter is successfully found and claimed
  164. // NDIS_STATUS_FAILURE - If an adapter is not found/claimed
  165. //
  166. //----------------------------------------------------------------------
  167. NDIS_STATUS MK7EnableInterrupt(PMK7_ADAPTER Adapter)
  168. {
  169. MK7REG mk7reg;
  170. UINT i;
  171. // NOTE: Workaround for potential hw problem where 0xFFFF is returned
  172. for (i=0; i<50; i++) {
  173. MK7Reg_Read(Adapter, R_CFG3, &mk7reg);
  174. if (mk7reg != 0xFFFF) {
  175. break;
  176. }
  177. }
  178. ASSERT(i < 50);
  179. mk7reg |= B_ENAB_INT;
  180. MK7Reg_Write(Adapter, R_CFG3, mk7reg);
  181. // PROMPT - Always after an Enable
  182. MK7Reg_Write(Adapter, R_PRMT, 0);
  183. return(NDIS_STATUS_SUCCESS);
  184. }
  185. //----------------------------------------------------------------------
  186. // Procedure: [MK7SwitchToRXMode]
  187. //
  188. // Description: Put hw in receive mode.
  189. //
  190. // Actions:
  191. // - Hw registers are programmed accordingly.
  192. // - IOMode set to RX_MODE.
  193. // - SlaveTXStuckCnt reset.
  194. //----------------------------------------------------------------------
  195. VOID MK7SwitchToRXMode(PMK7_ADAPTER Adapter)
  196. {
  197. MK7REG mk7reg;
  198. MK7Reg_Read(Adapter, R_CFG0, &mk7reg);
  199. mk7reg &= (~B_CFG0_ENTX);
  200. MK7Reg_Write(Adapter, R_CFG0, mk7reg);
  201. Adapter->IOMode = RX_MODE;
  202. DBGLOG("- Switch to RX mode", 0);
  203. }
  204. //----------------------------------------------------------------------
  205. // Procedure: [MK7SwitchToTXMode]
  206. //
  207. // Description: Put hw in receive mode.
  208. //
  209. // Actions:
  210. // - Hw registers are programmed accordingly.
  211. // - IOMode set to TX_MODE.
  212. //----------------------------------------------------------------------
  213. VOID MK7SwitchToTXMode(PMK7_ADAPTER Adapter)
  214. {
  215. MK7REG mk7reg;
  216. MK7Reg_Read(Adapter, R_CFG0, &mk7reg);
  217. mk7reg |= B_CFG0_ENTX;
  218. MK7Reg_Write(Adapter, R_CFG0, mk7reg);
  219. Adapter->IOMode = TX_MODE;
  220. DBGLOG("- Switch to TX mode", 0);
  221. }
  222. //----------------------------------------------------------------------
  223. // Procedure: [SetSpeed]
  224. //
  225. // Description:
  226. // Set the hw to a new speed.
  227. // [IMPORTANT: This should be called only from xxxSetInformation().]
  228. //
  229. // Actions:
  230. //----------------------------------------------------------------------
  231. BOOLEAN SetSpeed(PMK7_ADAPTER Adapter)
  232. {
  233. UINT i, bps;
  234. MK7REG mk7reg;
  235. PTCB tcb;
  236. //******************************
  237. // The idea is any sends that came before the change-speed command are
  238. // sent at the old speed. There are 3 scenarios here:
  239. // 1. There's no TXs outstanding -- We can change speed right away.
  240. // 2. There's TXs oustanding in the TX ring but none in the TX q -- We
  241. // do not change speed right away.
  242. // 3. There's TXs oustanding in the TX q (may be also in the TX ring) --
  243. // We do not change speed right away.
  244. //******************************
  245. DBGLOG("=> SetSpeed", 0);
  246. // If we're already waiting to change speed, fail all such requests
  247. // until the original is done. (Is this good?)
  248. //if (Adapter->changeSpeedPending) {
  249. // LOG("SetSpeed: already pending", 0);
  250. // return (FALSE);
  251. //}
  252. // This means 1 TX is already active. Change speed on completion.
  253. if (Adapter->NumPacketsQueued == 1) {
  254. Adapter->changeSpeedPending = CHANGESPEED_ON_DONE; // After the latest tx
  255. DBGLOG("<= SetSpeed: Q", 0);
  256. return (TRUE);
  257. }
  258. else
  259. if (Adapter->NumPacketsQueued > 1) {
  260. Adapter->changeSpeedAfterThisPkt = Adapter->LastTxQueue;
  261. Adapter->changeSpeedPending = CHANGESPEED_ON_Q;
  262. DBGLOG("<= SetSpeed: Qs", 0);
  263. return (TRUE);
  264. }
  265. // There's nothing pending TX or TX completion we must be
  266. // changing speed in RX mode.
  267. MK7ChangeSpeedNow(Adapter);
  268. return(TRUE);
  269. }
  270. //----------------------------------------------------------------------
  271. // Procedure: [MK7ChangeSpeedNow]
  272. //
  273. // Description:
  274. // Set the hw to a new speed.
  275. //
  276. // Actions:
  277. //----------------------------------------------------------------------
  278. VOID MK7ChangeSpeedNow(PMK7_ADAPTER Adapter)
  279. {
  280. UINT i, bps;
  281. MK7REG mk7reg, mk7reg_cfg3, mk7reg_w;
  282. DBGLOG("=> MK7ChangeSpeedNow", 0);
  283. bps = Adapter->linkSpeedInfo->bitsPerSec;
  284. //****************************************
  285. // Clear IRENABLE Bit
  286. // This is the only writeable bit in this reg so just write it.
  287. //****************************************
  288. MK7Reg_Write(Adapter, R_ENAB, ~B_ENAB_IRENABLE);
  289. // NOTE: Workaround for potential hw problem where 0xFFFF is returned.
  290. // (See aLSO MK7EnableInterrupt & MK7DisableInterrupt)
  291. for (i=0; i<50; i++) {
  292. MK7Reg_Read(Adapter, R_CFG3, &mk7reg_cfg3);
  293. if (mk7reg_cfg3 != 0xFFFF) {
  294. break;
  295. }
  296. }
  297. ASSERT(i < 50);
  298. // Need distinguish between changing speed in RX or TX mode.
  299. // Prep the bit that says TX or RX
  300. if (Adapter->IOMode == TX_MODE) {
  301. mk7reg_w = 0x1000;
  302. }
  303. else {
  304. mk7reg_w = 0;
  305. }
  306. if (bps <= MAX_SIR_SPEED) { // SIR
  307. if (Adapter->Wireless) {
  308. // WIRELESS: ... no INVERTTX
  309. mk7reg_w |= 0x0E18;
  310. }
  311. else {
  312. // WIRED: ENRX, DMA, small pkts, SIR, SIR RX filter, INVERTTX
  313. mk7reg_w |= 0x0E1A;
  314. }
  315. MK7Reg_Write(Adapter, R_CFG0, mk7reg_w);
  316. // Baud rate & pulse width
  317. i = Adapter->linkSpeedInfo->tableIndex;
  318. mk7reg = HwSirMirSpeedTable[i];
  319. MK7Reg_Write(Adapter, R_CFG2, mk7reg);
  320. mk7reg_cfg3 &= ~B_FAST_TX;
  321. MK7Reg_Write(Adapter, R_CFG3, mk7reg_cfg3);
  322. DBGLOG(" SIR", 0);
  323. }
  324. else
  325. if (bps < MIN_FIR_SPEED) { // MIR
  326. if (Adapter->Wireless) {
  327. // WIRELESS: ... no INVERTTX
  328. mk7reg_w |= 0x0CA0;
  329. }
  330. else {
  331. // WIRED: ENRX, DMA, 16-bit CRC, MIR, INVERTTX
  332. mk7reg_w |= 0x0CA2;
  333. }
  334. MK7Reg_Write(Adapter, R_CFG0, mk7reg_w);
  335. // Baud rate & pulse width, & preamble
  336. i = Adapter->linkSpeedInfo->tableIndex;
  337. mk7reg = HwSirMirSpeedTable[i];
  338. mk7reg |= 0x0001; // Preamble
  339. MK7Reg_Write(Adapter, R_CFG2, mk7reg);
  340. mk7reg_cfg3 |= B_FAST_TX;
  341. MK7Reg_Write(Adapter, R_CFG3, mk7reg_cfg3);
  342. DBGLOG(" MIR", 0);
  343. }
  344. else
  345. if (bps < VFIR_SPEED) { // FIR
  346. if (Adapter->Wireless) {
  347. // WIRELESS: ... no INVERTTX
  348. mk7reg_w |= 0x0C40;
  349. }
  350. else {
  351. // WIRED: ENRX, DMA, 32-bit CRC, FIR, INVERTTX
  352. mk7reg_w |= 0x0C42;
  353. }
  354. MK7Reg_Write(Adapter, R_CFG0, mk7reg_w);
  355. MK7Reg_Write(Adapter, R_CFG2, 0x000A); // 10 Preambles
  356. mk7reg_cfg3 |= B_FAST_TX;
  357. MK7Reg_Write(Adapter, R_CFG3, mk7reg_cfg3);
  358. DBGLOG(" FIR", 0);
  359. }
  360. else { // VFIR
  361. // For testing 4Mbps in VFIR mode.
  362. //if (Adapter->Wireless) {
  363. // WIRELESS: ... no INVERTTX
  364. // mk7reg_w |= 0x0C40;
  365. //}
  366. //else {
  367. // WIRED: ENRX, DMA, 32-bit CRC, FIR, INVERTTX
  368. // mk7reg_w |= 0x0C42;
  369. //}
  370. //MK7Reg_Write(Adapter, R_CFG0, mk7reg_w);
  371. if (Adapter->Wireless) {
  372. // WIRELESS: ... no INVERTTX
  373. mk7reg_w |= 0x2C00;
  374. }
  375. else {
  376. // WIRED: VFIR, ENRX, DMA, 32-bit CRC, FIR, INVERTTX
  377. mk7reg_w |= 0x2C02;
  378. }
  379. MK7Reg_Write(Adapter, R_CFG0, mk7reg_w);
  380. MK7Reg_Write(Adapter, R_CFG2, 0x000A); // 10 Preambles
  381. mk7reg_cfg3 |= B_FAST_TX;
  382. MK7Reg_Write(Adapter, R_CFG3, mk7reg_cfg3);
  383. DBGLOG(" VFIR", 0);
  384. }
  385. Adapter->CurrentSpeed = bps;
  386. //****************************************
  387. // Set IRENABLE Bit
  388. //****************************************
  389. MK7Reg_Write(Adapter, R_ENAB, B_ENAB_IRENABLE);
  390. //****************************************
  391. // PROMPT
  392. //****************************************
  393. MK7Reg_Write(Adapter, R_PRMT, 0);
  394. return;
  395. }