cs8900.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:11k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 1995-1998  Microsoft Corporation
  7. Module Name:
  8.     cs8900.c
  9. Abstract:
  10.     Card-specific functions for the NDIS 3.0 CS8900 driver.
  11.     
  12. Updates:
  13. 2003.10.24 jylee changes on interrupt registration for NDIS
  14. --*/
  15. #include "precomp.h"
  16. // CS8900 signature read from PacketPage Pointer port at reset
  17. #define CS8900_SIGNATURE                0x3000
  18. // CS8900 EISA number
  19. #define CS8900_EISA_NUMBER              0x630e
  20. // CS8900 product ID
  21. #define CS8900_PRDCT_ID                 0x0000
  22. #define CS8900_PRDCT_ID_MASK            0xe0ff
  23. #define PKTPG_EISA_NUMBER               0x0000
  24. #define PKTPG_PRDCT_ID_CODE             0x0002
  25. volatile unsigned char *EthCommand;
  26. volatile INTreg *v_pINTRegs;
  27. volatile IOPreg *v_pIOPRegs;
  28. volatile MEMreg *v_pMEMRegs;
  29. unsigned short GetD_SlowIO(unsigned long regaddrs)
  30. {
  31. return (*(volatile unsigned short *)regaddrs);
  32. }
  33. void SetD_SlowIO(unsigned long regaddrs, unsigned short regvalue)
  34. {
  35. *(volatile unsigned short *)regaddrs = regvalue;
  36. }
  37. //Read data from a PacketPage register.
  38. unsigned short CS8900ReadRegister(unsigned short offset)
  39. {
  40. writeIoPort(IO_PACKET_PAGE_POINTER, offset);
  41. return readIoPort(IO_PACKET_PAGE_DATA_0);
  42. }
  43. // Write data to a PacketPage register.
  44. void CS8900WriteRegister(unsigned short offset, unsigned short data)
  45. {
  46. writeIoPort(IO_PACKET_PAGE_POINTER, offset);
  47. writeIoPort(IO_PACKET_PAGE_DATA_0, data);
  48. }
  49. int findCS(void)
  50. {
  51. unsigned short sg;
  52. /* Check the signature. */
  53. if ((sg = readIoPort(IO_PACKET_PAGE_POINTER)) != CS8900_SIGNATURE)
  54. {
  55. DEBUGMSG(1, (TEXT("Signature Error %xn"), sg));
  56. // return FALSE;
  57. }
  58. /* Check the EISA registration number. */
  59. if (CS8900ReadRegister(PKTPG_EISA_NUMBER) != CS8900_EISA_NUMBER)
  60. {
  61. DEBUGMSG(1, (TEXT("Eisa Number Errorn")));
  62. return FALSE;
  63. }
  64. /* Check the Product ID. */
  65. if ((CS8900ReadRegister(PKTPG_PRDCT_ID_CODE) & CS8900_PRDCT_ID_MASK)
  66. != CS8900_PRDCT_ID)
  67. {
  68. DEBUGMSG(1, (TEXT("Product ID Errorn")));
  69. return FALSE;
  70. }
  71. DEBUGMSG(1, (TEXT("Product ID = %xn"), CS8900ReadRegister(PKTPG_PRDCT_ID_CODE)));
  72. return TRUE;
  73. }
  74. //Reset CS8900 chip.
  75. #define MAX_COUNT 0x100000
  76. int resetCS(void)
  77. {
  78. int i;
  79. unsigned short dummy;
  80.     /* Issue a reset command to the chip */
  81.     CS8900WriteRegister(PKTPG_SELF_CTL, SELF_CTL_RESET);
  82.     /* Delay for 125 micro-seconds */
  83. Sleep(10);
  84.     /* Transition SBHE to switch chip from 8-bit to 16-bit */
  85. #if 0
  86. *(volatile unsigned char *)&EthCommand[IO_PACKET_PAGE_POINTER];
  87. *(volatile unsigned char *)&EthCommand[IO_PACKET_PAGE_POINTER+1];
  88. *(volatile unsigned char *)&EthCommand[IO_PACKET_PAGE_POINTER];
  89. *(volatile unsigned char *)&EthCommand[IO_PACKET_PAGE_POINTER+1];
  90. #endif
  91.     /* Wait until initialization is done */
  92. Sleep(100);
  93. /* Wait until INITD bit of SelfST register is set. */
  94. i = 0;
  95. while (((dummy = CS8900ReadRegister(PKTPG_SELF_ST)) &
  96. SELF_ST_INITD) == 0)
  97. {
  98. if (++i > MAX_COUNT)
  99. {
  100. DEBUGMSG(1, (TEXT("resetCs8900 failed 1n")));
  101. return FALSE;
  102. }
  103. }
  104. /* Wait until SIBUSY bit of SelfST register is cleared. */
  105. i = 0;
  106. while (((dummy = CS8900ReadRegister(PKTPG_SELF_ST)) &
  107. SELF_ST_SIBUSY) != 0)
  108. {
  109. if (++i > MAX_COUNT)
  110. {
  111. DEBUGMSG(1, (TEXT("resetCs8900 failed 2n")));
  112. return FALSE;
  113. }
  114. }
  115. return TRUE;
  116. }
  117. void initIrq(void)
  118. {
  119. unsigned short rdata;
  120. // interrupt enabling....
  121. CS8900WriteRegister(PKTPG_INTERRUPT_NUMBER, INTERRUPT_NUMBER);
  122. rdata = CS8900ReadRegister(PKTPG_BUS_CTL) | BUS_CTL_ENABLE_IRQ;
  123. CS8900WriteRegister(PKTPG_BUS_CTL, rdata);
  124. rdata = CS8900ReadRegister(PKTPG_LINE_CTL) | LINE_CTL_RX_ON | LINE_CTL_TX_ON;
  125. CS8900WriteRegister(PKTPG_LINE_CTL, rdata);
  126. }
  127. //Initialize CS8900 chip.
  128. int initCS()
  129. {
  130. CS8900WriteRegister(PKTPG_LINE_CTL, LINE_CTL_10_BASE_T);
  131. CS8900WriteRegister(PKTPG_RX_CFG, RX_CFG_RX_OK_I_E);
  132. CS8900WriteRegister(PKTPG_RX_CTL,
  133. RX_CTL_RX_OK_A | RX_CTL_IND_ADDR_A |
  134. RX_CTL_BROADCAST_A);
  135. CS8900WriteRegister(PKTPG_TX_CFG, 0); 
  136. CS8900WriteRegister(PKTPG_BUF_CFG, 0); 
  137. CS8900WriteRegister(PKTPG_INDIVISUAL_ADDR, 0x3322);
  138. CS8900WriteRegister(PKTPG_INDIVISUAL_ADDR + 2, 0x5544);
  139. CS8900WriteRegister(PKTPG_INDIVISUAL_ADDR + 4, 0x0F66);
  140. initIrq();
  141. return TRUE;
  142. }
  143. int CSInit()
  144. {
  145. // Find CS8900 chip. 
  146. if (findCS() == FALSE)
  147. return FALSE;
  148. DEBUGMSG(1, (TEXT("Find CS8900 OKrn")));
  149. /* Reset CS8900 chip. */
  150. if (resetCS() == FALSE)
  151. return FALSE;
  152. DEBUGMSG(1, (TEXT("reset CS8900 OKrn")));
  153. /* Initialize CS8900 chip. */
  154. if (initCS() == FALSE)
  155. return FALSE;
  156. DEBUGMSG(1, (TEXT("CS8900 init OKrn")));
  157. return TRUE;
  158. }
  159. #pragma NDIS_PAGEABLE_FUNCTION(CS8900Initialize)
  160. BOOLEAN
  161. CS8900Initialize(
  162.     IN PCS8900_ADAPTER Adapter
  163.     )
  164. /*++
  165. Routine Description:
  166.     Initializes the card into a running state.
  167. Arguments:
  168.     Adapter - pointer to the adapter block.
  169. Return Value:
  170.     TRUE, if all goes well, else FALSE.
  171. --*/
  172. {
  173. DWORD rdata;
  174. EthCommand = (unsigned char *)ioPacketPage;
  175. if (CSInit() == FALSE)
  176. return FALSE;
  177. v_pIOPRegs = VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
  178. if (v_pIOPRegs == NULL) 
  179. {
  180.     DEBUGMSG (1,(TEXT("[CS8900] v_pIOPRegs is not allocatednr")));
  181. return FALSE;
  182. }
  183. if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
  184.     DEBUGMSG (1,(TEXT("[CS8900] v_pIOPRegs is not mappednr")));
  185. goto cs8900_fail;
  186. }
  187. DEBUGMSG (1,(TEXT("[CS8900] v_pIOPRegs is mapped to %xnr"), v_pIOPRegs));
  188. v_pINTRegs = VirtualAlloc(0, sizeof(INTreg), MEM_RESERVE, PAGE_NOACCESS);
  189. if (v_pINTRegs== NULL) 
  190. {
  191.     DEBUGMSG (1,(TEXT("[CS8900] v_pINTRegs is not allocatednr")));
  192. goto cs8900_fail;
  193. }
  194. if (!VirtualCopy((PVOID)v_pINTRegs, (PVOID)INT_BASE, sizeof(INTreg), PAGE_READWRITE|PAGE_NOCACHE)) {
  195.     DEBUGMSG (1,(TEXT("[CS8900] v_pINTRegs is not mappednr")));
  196. goto cs8900_fail;
  197. }
  198. DEBUGMSG (1,(TEXT("[CS8900] v_pINTRegs is mapped to %xnr"), v_pINTRegs));
  199. v_pMEMRegs = VirtualAlloc(0,sizeof(MEMreg), MEM_RESERVE,PAGE_NOACCESS);
  200. if(v_pMEMRegs == NULL) 
  201. {
  202.     DEBUGMSG (1,(TEXT("[CS8900] v_pMEMRegs is not allocatednr")));
  203. goto cs8900_fail;
  204. }
  205. if(!VirtualCopy((PVOID)v_pMEMRegs,(PVOID)MEMCTRL_BASE,sizeof(MEMreg), PAGE_READWRITE|PAGE_NOCACHE)) {
  206.     DEBUGMSG (1,(TEXT("[CS8900] v_pMEMRegs is not mappednr")));
  207.     goto cs8900_fail;
  208. }    
  209. DEBUGMSG (1,(TEXT("[CS8900] v_pMEMRegs is mapped to %xnr"), v_pMEMRegs));
  210.     // nGCS3=nUB/nLB(nSBHE),nWAIT,16-bit
  211.     v_pMEMRegs->rBWSCON = (v_pMEMRegs->rBWSCON&~(0xf<<12))|(0xd<<12);
  212.     // BANK3 access timing
  213. v_pMEMRegs->rBANKCON3=((CS8900_Tacs<<13)+(CS8900_Tcos<<11)+(CS8900_Tacc<<8)+(CS8900_Tcoh<<6)
  214. +(CS8900_Tah<<4)+(CS8900_Tacp<<2)+(CS8900_PMC));
  215. if (CSInit() == FALSE)
  216. goto cs8900_fail;
  217. rdata  = v_pIOPRegs->rGPGCON;
  218. rdata &= ~(3 << 2);
  219. rdata |=  (2 << 2);
  220. v_pIOPRegs->rGPGCON = rdata; /* External Interrupt #9 Enable */
  221. #if 1
  222. rdata  = v_pIOPRegs->rEXTINT1;
  223. rdata &= ~(7 << 4);
  224. rdata |=  (4 << 4);
  225. v_pIOPRegs->rEXTINT1 = rdata; /* High Level Triggered Mode */
  226. #else
  227. rdata  = v_pIOPRegs->rEXTINT1;
  228. rdata &= ~(7 << 4);
  229. rdata |=  (1 << 4);
  230. v_pIOPRegs->rEXTINT1 = rdata; /* Rising Edge Detect Mode */
  231. #endif
  232. DEBUGMSG(1, (TEXT("[CS8900] rGPGCON = %xrn"), v_pIOPRegs->rGPGCON));
  233. DEBUGMSG(1, (TEXT("[CS8900] rEXTINT1 = %xrn"), v_pIOPRegs->rEXTINT1));
  234. return TRUE;
  235. cs8900_fail:
  236.     if (v_pIOPRegs) {
  237.         VirtualFree((PVOID)v_pIOPRegs, 0, MEM_RELEASE);
  238.     }
  239.     if (v_pINTRegs) {
  240.         VirtualFree((PVOID)v_pINTRegs, 0, MEM_RELEASE);
  241.     }
  242.     if (v_pMEMRegs) {
  243.         VirtualFree((PVOID)v_pMEMRegs, 0, MEM_RELEASE);
  244.     }
  245. return FALSE;
  246. }
  247. #pragma NDIS_PAGEABLE_FUNCTION(CS8900ReadEthernetAddress)
  248. BOOLEAN CS8900ReadEthernetAddress(
  249.     IN PCS8900_ADAPTER Adapter
  250. )
  251. /*++
  252. Routine Description:
  253.     Reads in the Ethernet address from the CS8900 Chip...
  254. Arguments:
  255.     Adapter - pointer to the adapter block.
  256. Return Value:
  257.     The address is stored in Adapter->PermanentAddress, and StationAddress if it
  258.     is currently zero.
  259. --*/
  260. {
  261. Adapter->PermanentAddress[0] = 0x22;
  262. Adapter->PermanentAddress[1] = 0x33;
  263. Adapter->PermanentAddress[2] = 0x44;
  264. Adapter->PermanentAddress[3] = 0x55;
  265. Adapter->PermanentAddress[4] = 0x66;
  266. Adapter->PermanentAddress[5] = 0x0F;
  267.       
  268. DEBUGMSG(1,
  269.         (TEXT("CS8900: PermanentAddress [ %02x-%02x-%02x-%02x-%02x-%02x ]rn"),
  270.             Adapter->PermanentAddress[0],
  271.             Adapter->PermanentAddress[1],
  272.             Adapter->PermanentAddress[2],
  273.             Adapter->PermanentAddress[3],
  274.             Adapter->PermanentAddress[4],
  275.             Adapter->PermanentAddress[5]));
  276.     //
  277.     // Use the burned in address as the station address, unless the
  278.     // registry specified an override value.
  279.     //
  280.     if ((Adapter->StationAddress[0] == 0x00) &&
  281.         (Adapter->StationAddress[1] == 0x00) &&
  282.         (Adapter->StationAddress[2] == 0x00) &&
  283.         (Adapter->StationAddress[3] == 0x00) &&
  284.         (Adapter->StationAddress[4] == 0x00) &&
  285.         (Adapter->StationAddress[5] == 0x00)
  286.     )
  287.     {
  288.      DEBUGMSG(1, (TEXT("CS8900: StationAddress Modified!...rn")));
  289.         Adapter->StationAddress[0] = Adapter->PermanentAddress[0];
  290.         Adapter->StationAddress[1] = Adapter->PermanentAddress[1];
  291.         Adapter->StationAddress[2] = Adapter->PermanentAddress[2];
  292.         Adapter->StationAddress[3] = Adapter->PermanentAddress[3];
  293.         Adapter->StationAddress[4] = Adapter->PermanentAddress[4];
  294.         Adapter->StationAddress[5] = Adapter->PermanentAddress[5];
  295.     }
  296.     return(TRUE);
  297. }
  298. unsigned short CS8900RequestTransmit
  299. (
  300. UINT PacketLength
  301. )
  302. {
  303. // Request that the transmit be started after all data has been copied
  304. writeIoPort(IO_TX_CMD, TX_CMD_START_ALL);
  305. writeIoPort(IO_TX_LENGTH, (unsigned short)PacketLength);
  306. // Return the BusStatus register which indicates success of the request
  307. return CS8900ReadRegister(PKTPG_BUS_ST);
  308. }
  309. void CS8900CopyTxFrame
  310. (
  311. PCHAR pPacket,
  312. UINT PacketLength
  313.     )
  314. {
  315. UINT  i;
  316. PWORD pMsg;
  317. WORD PacketType, PacketOper;
  318. pMsg = (PWORD)pPacket;
  319. PacketType = *(pMsg + 6);
  320. PacketOper = *(pMsg + 10);
  321. if (PacketType == 0x0608)
  322. {
  323. if (PacketOper == 0x0100)
  324. DEBUGMSG(1, (TEXT("[CS8900] Send ARP Request Packetrn")));
  325. else if (PacketOper == 0x0200)
  326. DEBUGMSG(1, (TEXT("[CS8900] Send ARP Response Packetrn")));
  327. else if (PacketOper == 0x0300)
  328. DEBUGMSG(1, (TEXT("[CS8900] Send RARP Request Packetrn")));
  329. else if (PacketOper == 0x0400)
  330. DEBUGMSG(1, (TEXT("[CS8900] Send RARP Response Packetrn")));
  331. else
  332. DEBUGMSG(1, (TEXT("[CS8900] Send Unknown ARP Packetrn")));
  333. }
  334. else if (PacketType == 0x0008)
  335. DEBUGMSG(1, (TEXT("[CS8900] Send IP Packetrn")));
  336. for (i = 0 ; i < (PacketLength + 1) / 2; i++)
  337. {
  338. writeIoPort(IO_RX_TX_DATA_0, *pMsg);
  339. pMsg++;
  340. }
  341. }