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.

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