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.

956 lines
27 KiB

  1. /*
  2. ************************************************************************
  3. *
  4. * INIT.C
  5. *
  6. *
  7. * Portions Copyright (C) 1996-2001 National Semiconductor Corp.
  8. * All rights reserved.
  9. * Copyright (C) 1996-2001 Microsoft Corporation. All Rights Reserved.
  10. *
  11. *
  12. *
  13. *************************************************************************
  14. */
  15. #include "nsc.h"
  16. #include "newdong.h"
  17. #include "init.tmh"
  18. #define SIR 0
  19. #define MIR 1
  20. #define FIR 2
  21. #define NSC_DEMO_IRDA_SPEEDS ( NDIS_IRDA_SPEED_2400 | \
  22. NDIS_IRDA_SPEED_2400 | \
  23. NDIS_IRDA_SPEED_9600 | \
  24. NDIS_IRDA_SPEED_19200 | \
  25. NDIS_IRDA_SPEED_38400 | \
  26. NDIS_IRDA_SPEED_57600 | \
  27. NDIS_IRDA_SPEED_115200 | \
  28. NDIS_IRDA_SPEED_1152K | \
  29. NDIS_IRDA_SPEED_4M )
  30. // NSC PC87108 index registers. See the spec for more info.
  31. //
  32. enum indexRegs {
  33. BAIC_REG = 0,
  34. CSRT_REG = 1,
  35. MCTL_REG = 2,
  36. GPDIR_REG = 3,
  37. GPDAT_REG = 4
  38. };
  39. #define CS_MODE_CONFIG_OFFSET 0x8
  40. const UCHAR bankCode[] = { 0x03, 0x08, 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4 };
  41. //////////////////////////////////////////////////////////////////////////
  42. // //
  43. // Function : NSC_WriteBankReg //
  44. // //
  45. // Description: //
  46. // Write a value to the specified register of the specified register //
  47. // bank. //
  48. // //
  49. //////////////////////////////////////////////////////////////////////////
  50. void NSC_WriteBankReg(PUCHAR comBase, UINT bankNum, UINT regNum, UCHAR val)
  51. {
  52. NdisRawWritePortUchar(comBase+3, bankCode[bankNum]);
  53. NdisRawWritePortUchar(comBase+regNum, val);
  54. // Always switch back to reg 0
  55. NdisRawWritePortUchar(comBase+3, bankCode[0]);
  56. }
  57. //////////////////////////////////////////////////////////////////////////
  58. // //
  59. // Function : NSC_ReadBankReg //
  60. // //
  61. // Description: //
  62. // Write the value from the specified register of the specified //
  63. // register bank. //
  64. // //
  65. //////////////////////////////////////////////////////////////////////////
  66. UCHAR NSC_ReadBankReg(PUCHAR comBase, UINT bankNum, UINT regNum)
  67. {
  68. UCHAR result;
  69. NdisRawWritePortUchar(comBase+3, bankCode[bankNum]);
  70. NdisRawReadPortUchar(comBase+regNum, &result);
  71. // Always switch back to reg 0
  72. NdisRawWritePortUchar(comBase+3, bankCode[0]);
  73. return result;
  74. }
  75. typedef struct _SYNC_PORT_ACCESS {
  76. PUCHAR PortBase;
  77. UINT BankNumber;
  78. UINT RegisterIndex;
  79. UCHAR Value;
  80. } SYNC_PORT_ACCESS, *PSYNC_PORT_ACCESS;
  81. VOID
  82. ReadBankReg(
  83. PVOID Context
  84. )
  85. {
  86. PSYNC_PORT_ACCESS PortAccess=(PSYNC_PORT_ACCESS)Context;
  87. NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[PortAccess->BankNumber]);
  88. NdisRawReadPortUchar(PortAccess->PortBase+PortAccess->RegisterIndex, &PortAccess->Value);
  89. // Always switch back to reg 0
  90. NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[0]);
  91. return;
  92. }
  93. VOID
  94. WriteBankReg(
  95. PVOID Context
  96. )
  97. {
  98. PSYNC_PORT_ACCESS PortAccess=(PSYNC_PORT_ACCESS)Context;
  99. NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[PortAccess->BankNumber]);
  100. NdisRawWritePortUchar(PortAccess->PortBase+PortAccess->RegisterIndex, PortAccess->Value);
  101. // Always switch back to reg 0
  102. NdisRawWritePortUchar(PortAccess->PortBase+3, bankCode[0]);
  103. return;
  104. }
  105. VOID
  106. SyncWriteBankReg(
  107. PNDIS_MINIPORT_INTERRUPT InterruptObject,
  108. PUCHAR PortBase,
  109. UINT BankNumber,
  110. UINT RegisterIndex,
  111. UCHAR Value
  112. )
  113. {
  114. SYNC_PORT_ACCESS PortAccess;
  115. ASSERT(BankNumber <= 7);
  116. ASSERT(RegisterIndex <= 7);
  117. PortAccess.PortBase = PortBase;
  118. PortAccess.BankNumber = BankNumber;
  119. PortAccess.RegisterIndex= RegisterIndex;
  120. PortAccess.Value = Value;
  121. NdisMSynchronizeWithInterrupt(
  122. InterruptObject,
  123. WriteBankReg,
  124. &PortAccess
  125. );
  126. return;
  127. }
  128. UCHAR
  129. SyncReadBankReg(
  130. PNDIS_MINIPORT_INTERRUPT InterruptObject,
  131. PUCHAR PortBase,
  132. UINT BankNumber,
  133. UINT RegisterIndex
  134. )
  135. {
  136. SYNC_PORT_ACCESS PortAccess;
  137. ASSERT(BankNumber <= 7);
  138. ASSERT(RegisterIndex <= 7);
  139. PortAccess.PortBase = PortBase;
  140. PortAccess.BankNumber = BankNumber;
  141. PortAccess.RegisterIndex= RegisterIndex;
  142. NdisMSynchronizeWithInterrupt(
  143. InterruptObject,
  144. ReadBankReg,
  145. &PortAccess
  146. );
  147. return PortAccess.Value;
  148. }
  149. BOOLEAN
  150. SyncGetDongleCapabilities(
  151. PNDIS_MINIPORT_INTERRUPT InterruptObject,
  152. UIR * Com,
  153. DongleParam *Dingle
  154. )
  155. {
  156. SYNC_DONGLE Dongle;
  157. Dongle.Com=Com;
  158. Dongle.Dingle=Dingle;
  159. NdisMSynchronizeWithInterrupt(
  160. InterruptObject,
  161. GetDongleCapabilities,
  162. &Dongle
  163. );
  164. return TRUE;
  165. }
  166. UINT
  167. SyncSetDongleCapabilities(
  168. PNDIS_MINIPORT_INTERRUPT InterruptObject,
  169. UIR * Com,
  170. DongleParam *Dingle
  171. )
  172. {
  173. SYNC_DONGLE Dongle;
  174. Dongle.Com=Com;
  175. Dongle.Dingle=Dingle;
  176. NdisMSynchronizeWithInterrupt(
  177. InterruptObject,
  178. SetDongleCapabilities,
  179. &Dongle
  180. );
  181. return 0;
  182. }
  183. typedef struct _SYNC_FIFO_STATUS {
  184. PUCHAR PortBase;
  185. PUCHAR Status;
  186. PULONG Length;
  187. } SYNC_FIFO_STATUS, *PSYNC_FIFO_STATUS;
  188. VOID
  189. GetFifoStatus(
  190. PVOID Context
  191. )
  192. {
  193. PSYNC_FIFO_STATUS FifoStatus=Context;
  194. NdisRawWritePortUchar(FifoStatus->PortBase+3, bankCode[5]);
  195. NdisRawReadPortUchar(FifoStatus->PortBase+FRM_ST, FifoStatus->Status);
  196. *FifoStatus->Length=0;
  197. if (*FifoStatus->Status & ST_FIFO_VALID) {
  198. UCHAR High;
  199. UCHAR Low;
  200. NdisRawReadPortUchar(FifoStatus->PortBase+RFRL_L, &Low);
  201. NdisRawReadPortUchar(FifoStatus->PortBase+RFRL_H, &High);
  202. *FifoStatus->Length = Low;
  203. *FifoStatus->Length |= (ULONG)High << 8;
  204. }
  205. NdisRawWritePortUchar(FifoStatus->PortBase+3, bankCode[0]);
  206. }
  207. BOOLEAN
  208. SyncGetFifoStatus(
  209. PNDIS_MINIPORT_INTERRUPT InterruptObject,
  210. PUCHAR PortBase,
  211. PUCHAR Status,
  212. PULONG Size
  213. )
  214. {
  215. SYNC_FIFO_STATUS FifoStatus;
  216. FifoStatus.PortBase=PortBase;
  217. FifoStatus.Status=Status;
  218. FifoStatus.Length=Size;
  219. NdisMSynchronizeWithInterrupt(
  220. InterruptObject,
  221. GetFifoStatus,
  222. &FifoStatus
  223. );
  224. return (*Status & ST_FIFO_VALID);
  225. }
  226. //////////////////////////////////////////////////////////////////////////
  227. // //
  228. // Function : Ir108ConfigWrite //
  229. // //
  230. // Description: //
  231. // Write the data in the indexed register of the configuration I/O. //
  232. // //
  233. //////////////////////////////////////////////////////////////////////////
  234. void Ir108ConfigWrite(PUCHAR configIOBase, UCHAR indexReg, UCHAR data, BOOLEAN CSMode)
  235. {
  236. UCHAR IndexStore;
  237. if (CSMode)
  238. {
  239. NdisRawWritePortUchar(configIOBase+indexReg, data);
  240. NdisRawWritePortUchar(configIOBase+indexReg, data);
  241. }
  242. else
  243. {
  244. NdisRawReadPortUchar(configIOBase, &IndexStore);
  245. NdisRawWritePortUchar(configIOBase, indexReg);
  246. NdisRawWritePortUchar(configIOBase+1, data);
  247. NdisRawWritePortUchar(configIOBase+1, data);
  248. NdisRawWritePortUchar(configIOBase, IndexStore);
  249. }
  250. }
  251. //////////////////////////////////////////////////////////////////////////
  252. // //
  253. // Function : Ir108ConfigRead //
  254. // //
  255. // Description: //
  256. // Read the data in the indexed register of the configuration I/O. //
  257. // //
  258. //////////////////////////////////////////////////////////////////////////
  259. UCHAR Ir108ConfigRead(PUCHAR configIOBase, UCHAR indexReg, BOOLEAN CSMode)
  260. {
  261. UCHAR data,IndexStore;
  262. if (CSMode)
  263. {
  264. NdisRawReadPortUchar(configIOBase+indexReg, &data);
  265. }
  266. else
  267. {
  268. NdisRawReadPortUchar(configIOBase, &IndexStore);
  269. NdisRawWritePortUchar(configIOBase, indexReg);
  270. NdisRawReadPortUchar(configIOBase+1, &data);
  271. NdisRawWritePortUchar(configIOBase, IndexStore);
  272. }
  273. return (data);
  274. }
  275. //////////////////////////////////////////////////////////////////////////
  276. // //
  277. // Function : NSC_DEMO_Init //
  278. // //
  279. // Description: //
  280. // Set up configuration registers for NSC evaluation board. //
  281. // //
  282. // NOTE: //
  283. // Assumes configuration registers are at I/O addr 0x398. //
  284. // This function configures the demo board to make the SIR UART appear //
  285. // at <comBase>. //
  286. // //
  287. // Called By: //
  288. // OpenCom //
  289. //////////////////////////////////////////////////////////////////////////
  290. BOOLEAN NSC_DEMO_Init(IrDevice *thisDev)
  291. {
  292. UCHAR val;
  293. UCHAR FifoClear;
  294. BOOLEAN CSMode = FALSE;
  295. switch(thisDev->CardType){
  296. case PUMA108:
  297. CSMode = TRUE;
  298. thisDev->portInfo.ConfigIoBaseAddr = thisDev->portInfo.ioBase + CS_MODE_CONFIG_OFFSET;
  299. case PC87108:
  300. // Look for id at startup.
  301. if (!CSMode)
  302. {
  303. NdisRawReadPortUchar(thisDev->portInfo.ConfigIoBaseAddr, &val);
  304. if (val != 0x5A){
  305. if (val == (UCHAR)0xff){
  306. DBGERR(("didn't see PC87108 id (0x5A); got ffh."));
  307. return FALSE;
  308. }
  309. else {
  310. // ID only appears once, so in case we're resetting,
  311. // don't fail if we don't see it.
  312. DBGOUT(("WARNING: didn't see PC87108 id (0x5A); got %xh.",
  313. (UINT)val));
  314. }
  315. }
  316. }
  317. if (CSMode)
  318. {
  319. // base address ignored.
  320. val = 0;
  321. }
  322. else
  323. {
  324. // Select the base address for the UART
  325. switch ((DWORD_PTR)thisDev->portInfo.ioBase){
  326. case 0x3E8: val = 0; break;
  327. case 0x2E8: val = 1; break;
  328. case 0x3F8: val = 2; break;
  329. case 0x2F8: val = 3; break;
  330. default: return FALSE;
  331. }
  332. }
  333. val |= 0x04; // enable register banks
  334. val |= 0x10; // Set the interrupt line to Totempole output.
  335. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, BAIC_REG, val, CSMode);
  336. // Select interrupt level according to base address,
  337. // following COM port mapping.
  338. // Also select MIR/FIR DMA channels for rcv and xmit.
  339. //
  340. switch (thisDev->portInfo.irq){
  341. case 3: val = 1; break;
  342. case 4: val = 2; break;
  343. case 5: val = 3; break;
  344. case 7: val = 4; break;
  345. case 9: val = 5; break;
  346. case 11: val = 6; break;
  347. case 15: val = 7; break;
  348. default: return FALSE;
  349. }
  350. switch (thisDev->portInfo.DMAChannel){
  351. case 0: val |= 0x08; break;
  352. case 1: val |= 0x10; break;
  353. case 3: val |= 0x18; break;
  354. default:
  355. DBGERR(("Bad rcv dma channel in NSC_DEMO_Init"));
  356. return FALSE;
  357. }
  358. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, CSRT_REG, val, CSMode);
  359. // Select device-enable and normal-operating-mode.
  360. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, MCTL_REG, (UCHAR)3, CSMode);
  361. break;
  362. /*
  363. case PC87307:
  364. //
  365. // Select Logical Device 5
  366. //
  367. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x7, 0x5);
  368. // Disable IO check
  369. //
  370. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x31,0x0);
  371. // Config Base address low and high.
  372. //
  373. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  374. 0x61,(UCHAR)(thisDev->portInfo.ioBase));
  375. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  376. 0x60,(UCHAR)(thisDev->portInfo.ioBase >> 8));
  377. // Set IRQ
  378. //
  379. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  380. 0x70,(UCHAR)thisDev->portInfo.irq);
  381. // Enable Bank Select
  382. //
  383. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0xF0,0x82);
  384. // Enable UIR
  385. //
  386. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x30,0x1);
  387. break;
  388. */
  389. case PC87308:
  390. // Select Logical Device 5
  391. //
  392. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x7, 0x5, FALSE);
  393. // Disable IO check
  394. //
  395. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x31,0x0, FALSE);
  396. // Config Base address low and high.
  397. //
  398. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  399. 0x61,(UCHAR)(thisDev->portInfo.ioBasePhys), FALSE);
  400. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  401. 0x60,(UCHAR)(thisDev->portInfo.ioBasePhys >> 8), FALSE);
  402. // Set IRQ
  403. //
  404. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  405. 0x70,(UCHAR)thisDev->portInfo.irq, FALSE);
  406. // Select DMA Channel
  407. //
  408. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,
  409. 0x74,thisDev->portInfo.DMAChannel, FALSE);
  410. // DeSelect TXDMA Channel
  411. //
  412. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x75,0x4, FALSE);
  413. // Enable Bank Select
  414. //
  415. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0xF0,0x82, FALSE);
  416. // Enable UIR
  417. //
  418. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr,0x30,0x1, FALSE);
  419. break;
  420. case PC87338:
  421. // Select Plug and Play mode.
  422. val = Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr, 0x1B, FALSE);
  423. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x1B,
  424. (UCHAR)(val | 0x08), FALSE);
  425. // Write the new Plug and Play UART IOBASE register.
  426. //
  427. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x46,
  428. (UCHAR)((thisDev->portInfo.ioBasePhys>>2) & 0xfe), FALSE);
  429. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x47,
  430. (UCHAR)((thisDev->portInfo.ioBasePhys>>8) & 0xfc), FALSE);
  431. // Enable 14 Mhz clock + Clk Multiplier
  432. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x51, 0x04, FALSE);
  433. // Get Interrup line and shift it four bits;
  434. //
  435. val = thisDev->portInfo.irq << 4;
  436. // Read the Current Plug and Play Configuration 1 register.
  437. //
  438. val |= Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr,0x1C, FALSE);
  439. // Write the New Plug and Play Configuration 1 register.
  440. //
  441. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x1C, val, FALSE);
  442. // Setup 338 DMA.
  443. //
  444. switch (thisDev->portInfo.DMAChannel){
  445. case 0: val = 0x01; break;
  446. case 1: val = 0x02; break;
  447. case 2: val = 0x03; break;
  448. case 3:
  449. // Read the Current Plug and Play Configuration 3 register.
  450. //
  451. val = Ir108ConfigRead(
  452. thisDev->portInfo.ConfigIoBaseAddr,0x50, FALSE) | 0x01;
  453. // Write the new Plug and Play Configuration 3 register.
  454. //
  455. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x50,
  456. val, FALSE);
  457. // Read the Current Plug and Play Configuration 3 register.
  458. //
  459. val = Ir108ConfigRead(
  460. thisDev->portInfo.ConfigIoBaseAddr,0x4C, FALSE) | 0x80;
  461. // Write the new Plug and Play Configuration 3 register.
  462. //
  463. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x4C,
  464. val, FALSE);
  465. val = 0x04;
  466. break;
  467. default:
  468. DBGERR(("Bad rcv dma channel in NSC_DEMO_Init"));
  469. return FALSE;
  470. }
  471. // Write the new Plug and Play Configuration 3 register.
  472. //
  473. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x4F, val, FALSE);
  474. // Read the Current SuperI/O Configuration Register 2 register.
  475. //
  476. val = Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr,0x40, FALSE);
  477. // Set up UIR/UART2 for Normal Power Mode and Bank select enable.
  478. //
  479. val |= 0xE0;
  480. // Write the New SuperI/O Configuration Register 2 register.
  481. //
  482. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x40, val, FALSE);
  483. // Read the Current SuperI/O Configuration Register 3 register.
  484. //
  485. val = Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr,0x50, FALSE);
  486. // Set up UIR/UART2 IRX line
  487. //
  488. val |= 0x0C;
  489. // Write the New SuperI/O Configuration Register 3 register.
  490. //
  491. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x50, val, FALSE);
  492. // Set the SIRQ1 int to DRQ3 ??? only for EB
  493. //val = Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr,0x4c) & 0x3f;
  494. //Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x4c, val | 0x80);
  495. // Read the Current Function Enable register.
  496. //
  497. val = Ir108ConfigRead(thisDev->portInfo.ConfigIoBaseAddr,0x00, FALSE);
  498. // Enable UIR/UART2.
  499. //
  500. val |= 0x04;
  501. // Write the New Function Enable register.
  502. //
  503. Ir108ConfigWrite(thisDev->portInfo.ConfigIoBaseAddr, 0x00, val, FALSE);
  504. break;
  505. } // End of Evaluation board configuration setction.
  506. thisDev->UIR_ModuleId = NSC_ReadBankReg(thisDev->portInfo.ioBase, 3, 0);
  507. if (thisDev->UIR_ModuleId<0x20)
  508. {
  509. // Older revs of the NSC hardware seem to handle 1MB really poorly.
  510. thisDev->AllowedSpeedMask &= ~NDIS_IRDA_SPEED_1152K;
  511. }
  512. // The UART doesn't appear until we clear and set the FIFO control
  513. // register.
  514. NdisRawWritePortUchar(thisDev->portInfo.ioBase+2, (UCHAR)0x00);
  515. NdisRawWritePortUchar(thisDev->portInfo.ioBase+2, (UCHAR)0x07);
  516. // Set FIR CRC to 32 bits.
  517. NSC_WriteBankReg(thisDev->portInfo.ioBase, 6, 0, 0x20);
  518. // Switch to bank 5
  519. // clear the status FIFO
  520. //
  521. NdisRawWritePortUchar(thisDev->portInfo.ioBase+3, (UCHAR)0xEC);
  522. FifoClear = 8;
  523. do {
  524. NdisRawReadPortUchar(thisDev->portInfo.ioBase+6, &val);
  525. NdisRawReadPortUchar(thisDev->portInfo.ioBase+7, &val);
  526. NdisRawReadPortUchar(thisDev->portInfo.ioBase+5, &val);
  527. FifoClear--;
  528. } while( (val & 0x80) && (FifoClear > 0) );
  529. // Test for newer silicon for support of Frame stop mode
  530. #if 0
  531. if (thisDev->UIR_Mid < 0x16)
  532. // Change Bit 1 to Default 1
  533. // 0x40 -> 0x42
  534. #endif
  535. NSC_WriteBankReg(thisDev->portInfo.ioBase, 5, 4, 0x40);
  536. #if 0 // Since we're not currently using the multi-packet send, we don't use frame stop mode.
  537. else
  538. //
  539. // Set FIFO threshold and TX_MS Tx frame end stop mode.
  540. //
  541. // Change Bit 1 to Default 1
  542. // 0x68 -> 0x6a
  543. NSC_WriteBankReg(thisDev->portInfo.ioBase, 5, 4, 0x60);
  544. #endif
  545. // Set SIR mode in IRCR1.
  546. // Enable SIR infrared mode in the Non-Extended mode of operation
  547. NSC_WriteBankReg(thisDev->portInfo.ioBase, 4, 2, 0x0C);
  548. // Set max xmit frame size.
  549. // Need to set value slightly larger so that counter never
  550. // reaches 0.
  551. //
  552. NSC_WriteBankReg(thisDev->portInfo.ioBase, 4, 4,
  553. (UCHAR)(MAX_NDIS_DATA_SIZE+1));
  554. NSC_WriteBankReg(thisDev->portInfo.ioBase, 4, 5,
  555. (UCHAR)((MAX_NDIS_DATA_SIZE+1) >> 8));
  556. // Set max rcv frame size.
  557. // Need to set value slightly larger so that counter never
  558. // reaches 0.
  559. //
  560. NSC_WriteBankReg(thisDev->portInfo.ioBase, 4, 6,
  561. (UCHAR)(MAX_RCV_DATA_SIZE+FAST_IR_FCS_SIZE));
  562. NSC_WriteBankReg(thisDev->portInfo.ioBase, 4, 7,
  563. (UCHAR)((MAX_RCV_DATA_SIZE+FAST_IR_FCS_SIZE) >> 8));
  564. // Set extended mode
  565. //
  566. NSC_WriteBankReg(thisDev->portInfo.ioBase, 2, 2, 0x03);
  567. // Set 32-bit FIFOs
  568. //
  569. NSC_WriteBankReg(thisDev->portInfo.ioBase, 2, 4, 0x05);
  570. // Enable and reset FIFO's and set the receive FIF0
  571. // equal to the receive DMA threshold. See if DMA
  572. // is fast enough for device.
  573. //
  574. NSC_WriteBankReg(thisDev->portInfo.ioBase, 0, 2, 0x07);
  575. // Restore to Non-Extended mode
  576. //
  577. NSC_WriteBankReg(thisDev->portInfo.ioBase, 2, 2, 0x02);
  578. thisDev->portInfo.hwCaps.supportedSpeedsMask = NSC_DEMO_IRDA_SPEEDS;
  579. thisDev->portInfo.hwCaps.turnAroundTime_usec = DEFAULT_TURNAROUND_usec;
  580. thisDev->portInfo.hwCaps.extraBOFsRequired = 0;
  581. // Initialize thedongle structure before calling
  582. // GetDongleCapabilities and SetDongleCapabilities for dongle 1.
  583. //
  584. thisDev->currentDongle = 1;
  585. thisDev->IrDongleResource.Signature = thisDev->DongleTypes[thisDev->currentDongle];
  586. thisDev->IrDongleResource.ComPort = thisDev->portInfo.ioBase;
  587. thisDev->IrDongleResource.ModeReq = SIR;
  588. thisDev->IrDongleResource.XcvrNum = thisDev->currentDongle;
  589. // IrDongle = GetDongleCapabilities(thisDev->IrDongleResource);
  590. SyncGetDongleCapabilities(&thisDev->interruptObj,&thisDev->IrDongleResource,&thisDev->Dingle[0]);
  591. // Initialize thedongle structure before calling
  592. // GetDongleCapabilities and SetDongleCapabilities for dongle 0.
  593. //
  594. thisDev->currentDongle = 0;
  595. thisDev->IrDongleResource.Signature = thisDev->DongleTypes[thisDev->currentDongle];
  596. thisDev->IrDongleResource.ComPort = thisDev->portInfo.ioBase;
  597. thisDev->IrDongleResource.ModeReq = SIR;
  598. thisDev->IrDongleResource.XcvrNum = 0;
  599. // IrDongle = GetDongleCapabilities(IrDongleResource);
  600. SyncGetDongleCapabilities(&thisDev->interruptObj,&thisDev->IrDongleResource,&thisDev->Dingle[0]);
  601. SyncSetDongleCapabilities(&thisDev->interruptObj,&thisDev->IrDongleResource,&thisDev->Dingle[0]);
  602. return TRUE;
  603. }
  604. #if 1
  605. //////////////////////////////////////////////////////////////////////////
  606. // //
  607. // Function: NSC_DEMO_Deinit //
  608. // //
  609. // DUMMY ROUTINE //
  610. //////////////////////////////////////////////////////////////////////////
  611. VOID NSC_DEMO_Deinit(PUCHAR comBase, UINT context)
  612. {
  613. }
  614. #endif
  615. //////////////////////////////////////////////////////////////////////////
  616. // //
  617. // Function: NSC_DEMO_SetSpeed //
  618. // //
  619. // Description: //
  620. // Set up the size of FCB, the timer, FIFO, DMA and the IR mode/dongle //
  621. // speed based on the negotiated speed. //
  622. // //
  623. //////////////////////////////////////////////////////////////////////////
  624. BOOLEAN NSC_DEMO_SetSpeed(
  625. IrDevice *thisDev,
  626. PUCHAR comBase,
  627. UINT bitsPerSec,
  628. UINT context)
  629. {
  630. NDIS_STATUS stat;
  631. UINT fcsSize;
  632. LOG("==>NSC_DEMO_SetSpeed %d",bitsPerSec);
  633. if (thisDev->FirReceiveDmaActive) {
  634. thisDev->FirReceiveDmaActive=FALSE;
  635. //
  636. // receive dma is running, stop it
  637. //
  638. CompleteDmaTransferFromDevice(
  639. &thisDev->DmaUtil
  640. );
  641. }
  642. // Make sure the previous packet completely sent out(Not in the TX FIFO)
  643. // and Txmitter is empty
  644. // before the bandwidth control
  645. while((SyncReadBankReg(&thisDev->interruptObj, comBase, 0, 5)& 0x60) != 0x60);
  646. //
  647. if (bitsPerSec > 115200){
  648. fcsSize = (bitsPerSec >= MIN_FIR_SPEED) ?
  649. FAST_IR_FCS_SIZE : MEDIUM_IR_FCS_SIZE;
  650. if(bitsPerSec >= MIN_FIR_SPEED)
  651. thisDev->IrDongleResource.ModeReq = FIR;
  652. else
  653. thisDev->IrDongleResource.ModeReq = MIR;
  654. SyncSetDongleCapabilities(&thisDev->interruptObj,&thisDev->IrDongleResource,&thisDev->Dingle[0]);
  655. // Set extended mode and set DMA fairness.
  656. //
  657. SyncWriteBankReg(&thisDev->interruptObj, comBase, 2, 2, 0x03);
  658. if (thisDev->UIR_ModuleId < 0x16){
  659. // Set Timer registers.
  660. //
  661. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 0, (UCHAR)0x2);
  662. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 1, (UCHAR)0x0);
  663. }
  664. else {
  665. // Set Timer registers timer has 8 times finer
  666. // resolution.
  667. //
  668. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 0, (UCHAR)(TIMER_PERIODS & 0xff));
  669. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 1, (UCHAR)(TIMER_PERIODS >> 8));
  670. }
  671. // Set max rcv frame size.
  672. // Need to set value slightly larger so that counter never reaches 0.
  673. //
  674. DBGERR(("Programming Max Receive Size registers with %d Bytes ",
  675. MAX_RCV_DATA_SIZE+fcsSize));
  676. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 6, (UCHAR)(MAX_RCV_DATA_SIZE+fcsSize));
  677. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 7,
  678. (UCHAR)((MAX_RCV_DATA_SIZE+fcsSize) >> 8));
  679. // Reset Timer Enable bit.
  680. //
  681. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 2, 0x00);
  682. // Set MIR/FIR mode and DMA enable
  683. //
  684. SyncWriteBankReg(&thisDev->interruptObj, comBase, 0, 4,
  685. (UCHAR)((bitsPerSec >= 4000000) ? 0xA4 : 0x84));
  686. DBGERR(("EXCR2= 0x%x",SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 2, 4)));
  687. // Set 32-bit FIFOs
  688. //
  689. SyncWriteBankReg(&thisDev->interruptObj, comBase, 2, 4, 0x05);
  690. DBGERR(("EXCR2= 0x%x",SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 2, 4)));
  691. //
  692. // We may start receiving immediately so setup the
  693. // receive DMA
  694. //
  695. #if 0
  696. // First, tear down any existing DMA
  697. if (thisDev->FirAdapterState==ADAPTER_RX) {
  698. thisDev->FirAdapterState=ADAPTER_NONE;
  699. CompleteDmaTransferFromDevice(
  700. &thisDev->DmaUtil
  701. );
  702. }
  703. FindLargestSpace(thisDev, &thisDev->rcvDmaOffset, &thisDev->rcvDmaSize);
  704. SetupRecv(thisDev);
  705. // Set the interrupt mask to interrupt on the
  706. // first packet received.
  707. //
  708. thisDev->IntMask = 0x04;
  709. DBGOUT(("RxDMA = ON"));
  710. #endif
  711. }
  712. else {
  713. // Set SIR mode in UART before setting the timing of transciever
  714. //
  715. // Set SIR mode
  716. //
  717. SyncWriteBankReg(&thisDev->interruptObj, comBase, 4, 2, 0x0C);
  718. // Must set SIR Pulse Width Register to 0 (3/16) as default
  719. // Bug in 338/108
  720. SyncWriteBankReg(&thisDev->interruptObj, comBase, 6, 2, 0x0);
  721. // Clear extended mode
  722. //
  723. SyncWriteBankReg(&thisDev->interruptObj, comBase, 2, 2, 0x00);
  724. thisDev->IrDongleResource.ModeReq = SIR;
  725. SyncSetDongleCapabilities(&thisDev->interruptObj,&thisDev->IrDongleResource,&thisDev->Dingle[0]);
  726. // Clear Line and Auxiluary status registers.
  727. //
  728. SyncReadBankReg(&thisDev->interruptObj, comBase, 0, 5);
  729. SyncReadBankReg(&thisDev->interruptObj, comBase, 0, 7);
  730. }
  731. LOG("<==NSC_DEMO_SetSpeed");
  732. return TRUE;
  733. }