aironet4500_card.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:24k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  Aironet 4500 PCI-ISA-i365 driver
  3.  *
  4.  * Elmer Joandi, Januar 1999
  5.  * Copyright GPL
  6.  *
  7.  *
  8.  * Revision 0.1 ,started  30.12.1998
  9.  *
  10.  * Revision 0.2, Feb 27, 2000
  11.  * Jeff Garzik - softnet, cleanups
  12.  *
  13.  */
  14. #ifdef MODULE
  15. static const char *awc_version =
  16. "aironet4500_cards.c v0.2  Feb 27, 2000  Elmer Joandi, elmer@ylenurme.ee.n";
  17. #endif
  18. #include <linux/version.h>
  19. #include <linux/config.h>
  20. #include <linux/module.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/ptrace.h>
  24. #include <linux/slab.h>
  25. #include <linux/string.h>
  26. #include <linux/timer.h>
  27. #include <linux/interrupt.h>
  28. #include <linux/in.h>
  29. #include <asm/io.h>
  30. #include <asm/system.h>
  31. #include <asm/bitops.h>
  32. #include <linux/netdevice.h>
  33. #include <linux/etherdevice.h>
  34. #include <linux/skbuff.h>
  35. #include <linux/if_arp.h>
  36. #include <linux/ioport.h>
  37. #include <linux/delay.h>
  38. #include <linux/init.h>
  39. #include "aironet4500.h"
  40. #define PCI_VENDOR_ID_AIRONET  0x14b9
  41. #define PCI_DEVICE_AIRONET_4800_1 0x1
  42. #define PCI_DEVICE_AIRONET_4800 0x4500
  43. #define PCI_DEVICE_AIRONET_4500 0x4800
  44. #define AIRONET4X00_IO_SIZE  0x40
  45. #define AIRONET4X00_CIS_SIZE 0x300
  46. #define AIRONET4X00_MEM_SIZE 0x300
  47. #define AIRONET4500_PCI  1
  48. #define AIRONET4500_PNP 2
  49. #define AIRONET4500_ISA 3
  50. #define AIRONET4500_365 4
  51. #ifdef CONFIG_AIRONET4500_PCI
  52. #include <linux/pci.h>
  53. static struct pci_device_id aironet4500_card_pci_tbl[] __devinitdata = {
  54. { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4800_1, PCI_ANY_ID, PCI_ANY_ID, },
  55. { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4800, PCI_ANY_ID, PCI_ANY_ID, },
  56. { PCI_VENDOR_ID_AIRONET, PCI_DEVICE_AIRONET_4500, PCI_ANY_ID, PCI_ANY_ID, },
  57. { } /* Terminating entry */
  58. };
  59. MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl);
  60. MODULE_LICENSE("GPL");
  61. static int reverse_probe;
  62. static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev,
  63.   int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ;
  64. int awc4500_pci_probe(struct net_device *dev)
  65. {
  66. int cards_found = 0;
  67. static int pci_index; /* Static, for multiple probe calls. */
  68. u8 pci_irq_line = 0;
  69. // int p;
  70. unsigned char awc_pci_dev, awc_pci_bus;
  71. if (!pci_present()) 
  72. return -1;
  73. for (;pci_index < 0xff; pci_index++) {
  74. u16 vendor, device, pci_command, new_command;
  75. u32 pci_memaddr;
  76. u32 pci_ioaddr;
  77. u32 pci_cisaddr;
  78. struct pci_dev *pdev;
  79. if (pcibios_find_class (PCI_CLASS_NETWORK_OTHER << 8,
  80.  reverse_probe ? 0xfe - pci_index : pci_index,
  81.  &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){
  82. if (reverse_probe){
  83. continue;
  84. } else {
  85. break;
  86. }
  87. }
  88. pdev = pci_find_slot(awc_pci_bus, awc_pci_dev);
  89. if (!pdev)
  90. continue;
  91. if (pci_enable_device(pdev))
  92. continue;
  93. vendor = pdev->vendor;
  94. device = pdev->device;
  95.         pci_irq_line = pdev->irq;
  96. pci_memaddr = pci_resource_start (pdev, 0);
  97.                 pci_cisaddr = pci_resource_start (pdev, 1);
  98. pci_ioaddr = pci_resource_start (pdev, 2);
  99. // printk("n pci capabilities %x and ptr %x n",pci_caps,pci_caps_ptr);
  100. /* Remove I/O space marker in bit 0. */
  101. if (vendor != PCI_VENDOR_ID_AIRONET)
  102. continue;
  103. if (device != PCI_DEVICE_AIRONET_4800_1 && 
  104. device != PCI_DEVICE_AIRONET_4800 &&
  105. device != PCI_DEVICE_AIRONET_4500 )
  106.                         continue;
  107. // if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||
  108. // check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||
  109. // check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {
  110. // printk(KERN_ERR "aironet4X00 mem addrs not available for maping n");
  111. // continue;
  112. // }
  113. if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
  114. continue;
  115. // request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
  116. // request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
  117. mdelay(10);
  118. pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
  119. new_command = pci_command | PCI_COMMAND_SERR;
  120. if (pci_command != new_command)
  121. pci_write_config_word(pdev, PCI_COMMAND, new_command);
  122. /* if (device == PCI_DEVICE_AIRONET_4800)
  123. pci_write_config_dword(pdev, 0x40, 0x00000000);
  124. udelay(1000);
  125. */
  126. if (device == PCI_DEVICE_AIRONET_4800)
  127. pci_write_config_dword(pdev, 0x40, 0x40000000);
  128. if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){
  129. printk(KERN_ERR "awc4800 pci init failed n");
  130. break;
  131. }
  132. dev = 0;
  133. cards_found++;
  134. }
  135. return cards_found ? 0 : -ENODEV;
  136. }
  137. static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev,
  138.   int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) {
  139. int i, allocd_dev = 0;
  140. if (!dev) {
  141. dev = init_etherdev(NULL, 0);
  142. if (!dev)
  143. return -ENOMEM;
  144. allocd_dev = 1;
  145. }
  146. dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
  147.         if (!dev->priv) {
  148.                 if (allocd_dev) {
  149.                         unregister_netdev(dev);
  150.                         kfree(dev);
  151.                 }
  152.                 return -ENOMEM;
  153.         }       
  154. memset(dev->priv,0,sizeof(struct awc_private));
  155. if (!dev->priv) {
  156. printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follown");
  157. if (allocd_dev) {
  158. unregister_netdev(dev);
  159. kfree(dev);
  160. }
  161. return -ENOMEM;
  162. };
  163. // ether_setup(dev);
  164. // dev->tx_queue_len = tx_queue_len;
  165. dev->hard_start_xmit =  &awc_start_xmit;
  166. // dev->set_config =  &awc_config_misiganes,aga mitte awc_config;
  167. dev->get_stats =  &awc_get_stats;
  168. // dev->set_multicast_list =  &awc_set_multicast_list;
  169. dev->change_mtu = awc_change_mtu;
  170. dev->init = &awc_init;
  171. dev->open = &awc_open;
  172. dev->stop = &awc_close;
  173.      dev->base_addr = ioaddr;
  174.      dev->irq = pci_irq_line;
  175. dev->tx_timeout = &awc_tx_timeout;
  176. dev->watchdog_timeo = AWC_TX_TIMEOUT;
  177. i = request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
  178. if (i) {
  179. kfree(dev->priv);
  180. dev->priv = NULL;
  181. if (allocd_dev) {
  182. unregister_netdev(dev);
  183. kfree(dev);
  184. }
  185. return i;
  186. }
  187. awc_private_init( dev);
  188. awc_init(dev);
  189. i=0;
  190. while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
  191. if (!aironet4500_devices[i]){
  192. aironet4500_devices[i]=dev;
  193. ((struct awc_private *)
  194. aironet4500_devices[i]->priv)->card_type = AIRONET4500_PCI;
  195. if (awc_proc_set_fun)
  196. awc_proc_set_fun(i);
  197. }
  198. // if (register_netdev(dev) != 0) {
  199. // printk(KERN_NOTICE "awc_cs: register_netdev() failedn");
  200. // goto failed;
  201. // }
  202. return 0; 
  203. //  failed:
  204. //   return -1;
  205. }
  206. #ifdef MODULE
  207. static void awc_pci_release(void) {
  208. // long flags;
  209. int i=0;
  210. DEBUG(0, "awc_detach n");
  211. i=0;
  212. while ( i < MAX_AWCS) {
  213. if (!aironet4500_devices[i])
  214.                         {i++; continue;};
  215. if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PCI)
  216.                   {i++;      continue;}
  217. if (awc_proc_unset_fun)
  218. awc_proc_unset_fun(i);
  219. release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
  220. // release_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
  221. // release_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
  222. unregister_netdev(aironet4500_devices[i]);
  223. free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
  224. kfree(aironet4500_devices[i]->priv);
  225. kfree(aironet4500_devices[i]);
  226. aironet4500_devices[i]=0;
  227. i++;
  228. }
  229. #endif //MODULE
  230. #endif /* CONFIG_AIRONET4500_PCI */
  231. #ifdef CONFIG_AIRONET4500_PNP
  232. #include <linux/isapnp.h>
  233. #define AIRONET4X00_IO_SIZE  0x40
  234. #define isapnp_logdev pci_dev
  235. #define isapnp_dev    pci_bus
  236. #define isapnp_find_device isapnp_find_card
  237. #define isapnp_find_logdev isapnp_find_dev
  238. #define PNP_BUS bus
  239. #define PNP_BUS_NUMBER number
  240. #define PNP_DEV_NUMBER devfn
  241. int awc4500_pnp_hw_reset(struct net_device *dev){
  242. struct isapnp_logdev *logdev;
  243. DEBUG(0, "awc_pnp_reset n");
  244. if (!dev->priv ) {
  245. printk("awc4500 no dev->priv in hw_resetn");
  246. return -1;
  247. };
  248. logdev = ((struct isapnp_logdev *) ((struct awc_private *)dev->priv)->bus);
  249. if (!logdev ) {
  250. printk("awc4500 no pnp logdev in hw_resetn");
  251. return -1;
  252. };
  253. if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
  254. printk("isapnp cfg failed at release n");
  255. isapnp_deactivate(logdev->PNP_DEV_NUMBER);
  256. isapnp_cfg_end();
  257. udelay(100);
  258. if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
  259. printk("%s cfg begin failed in hw_reset for csn %x devnum %x n",
  260. dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
  261. return -EAGAIN;
  262. }
  263. isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */
  264. isapnp_cfg_end();
  265. return 0;
  266. }
  267. int awc4500_pnp_probe(struct net_device *dev)
  268. {
  269. int isa_index = 0;
  270. int isa_irq_line = 0;
  271. int isa_ioaddr = 0;
  272. int card = 0;
  273. int i=0;
  274. struct isapnp_dev * pnp_dev ;
  275. struct isapnp_logdev *logdev;
  276. while (1) {
  277. pnp_dev = isapnp_find_device(
  278. ISAPNP_VENDOR('A','W','L'), 
  279. ISAPNP_DEVICE(1),
  280. 0);
  281. if (!pnp_dev) break;  
  282. isa_index++;
  283. logdev = isapnp_find_logdev(pnp_dev, ISAPNP_VENDOR('A','W','L'),
  284.     ISAPNP_FUNCTION(1),
  285.     0);
  286. if (!logdev){
  287. printk("No logical device found on Aironet board n");
  288. return -ENODEV;
  289. }
  290. if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
  291. printk("cfg begin failed for csn %x devnum %x n",
  292. logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
  293. return -EAGAIN;
  294. }
  295. isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */
  296. isapnp_cfg_end();
  297. isa_irq_line = logdev->irq;
  298. isa_ioaddr = logdev->resource[0].start;
  299. request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
  300. if (!dev) {
  301. dev = init_etherdev(NULL, 0);
  302. if (!dev) {
  303. release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
  304. isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER,
  305.  logdev->PNP_DEV_NUMBER);
  306. isapnp_deactivate(logdev->PNP_DEV_NUMBER);
  307. isapnp_cfg_end();
  308. return -ENOMEM;
  309. }
  310. }
  311. dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
  312. memset(dev->priv,0,sizeof(struct awc_private));
  313. if (!dev->priv) {
  314. printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follown");
  315. return -1;
  316. };
  317. ((struct awc_private *)dev->priv)->bus =  logdev;
  318. // ether_setup(dev);
  319. // dev->tx_queue_len = tx_queue_len;
  320. dev->hard_start_xmit =  &awc_start_xmit;
  321. // dev->set_config =  &awc_config_misiganes,aga mitte awc_config;
  322. dev->get_stats =  &awc_get_stats;
  323. // dev->set_multicast_list =  &awc_set_multicast_list;
  324. dev->change_mtu = awc_change_mtu;
  325. dev->init = &awc_init;
  326. dev->open = &awc_open;
  327. dev->stop = &awc_close;
  328.      dev->base_addr = isa_ioaddr;
  329.      dev->irq = isa_irq_line;
  330. dev->tx_timeout = &awc_tx_timeout;
  331. dev->watchdog_timeo = AWC_TX_TIMEOUT;
  332. netif_start_queue (dev);
  333. request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
  334. awc_private_init( dev);
  335. ((struct awc_private *)dev->priv)->bus =  logdev;
  336. cli();
  337. if ( awc_init(dev) ){
  338. printk("card not found at irq %x io %lxn",dev->irq, dev->base_addr);
  339. if (card==0){
  340. sti();
  341. return -1;
  342. }
  343. sti();
  344. break;
  345. }
  346. udelay(10);
  347. sti();
  348. i=0;
  349. while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
  350. if (!aironet4500_devices[i] && i < MAX_AWCS-1 ){
  351. aironet4500_devices[i]=dev;
  352. ((struct awc_private *)
  353. aironet4500_devices[i]->priv)->card_type = AIRONET4500_PNP;
  354. if (awc_proc_set_fun)
  355. awc_proc_set_fun(i);
  356. } else { 
  357. printk(KERN_CRIT "Out of resources (MAX_AWCS) n");
  358. return -1;
  359. }
  360. card++;
  361. }
  362. if (card == 0) return -ENODEV;
  363. return 0;
  364. }
  365. #ifdef MODULE
  366. static void awc_pnp_release(void) {
  367. // long flags;
  368. int i=0;
  369. struct isapnp_logdev *logdev;
  370. DEBUG(0, "awc_detach n");
  371. i=0;
  372. while ( i < MAX_AWCS) {
  373. if (!aironet4500_devices[i])
  374.                   {i++;      continue;}
  375. if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_PNP)
  376.                   {i++;      continue;}
  377. logdev = ((struct isapnp_logdev *) ((struct awc_private *)aironet4500_devices[i]->priv)->bus);
  378. if (!logdev ) 
  379. printk("awc4500 no pnp logdev in pnp_releasen");
  380. if (awc_proc_unset_fun)
  381. awc_proc_unset_fun(i);
  382. if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
  383. printk("isapnp cfg failed at release n");
  384. isapnp_deactivate(logdev->PNP_DEV_NUMBER);
  385. isapnp_cfg_end();
  386. release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
  387. // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
  388. // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
  389. unregister_netdev(aironet4500_devices[i]);
  390. free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
  391. kfree(aironet4500_devices[i]->priv);
  392. kfree(aironet4500_devices[i]);
  393. aironet4500_devices[i]=0;
  394. i++;
  395. }
  396. static struct isapnp_device_id id_table[] = {
  397. { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
  398. ISAPNP_VENDOR('A','W','L'), ISAPNP_DEVICE(1), 0 },
  399. {0}
  400. };
  401. MODULE_DEVICE_TABLE(isapnp, id_table);
  402. #endif //MODULE
  403. #endif /* CONFIG_AIRONET4500_PNP */
  404. #ifdef  CONFIG_AIRONET4500_ISA 
  405. static int irq[] = {0,0,0,0,0};
  406. static int io[] = {0,0,0,0,0};
  407. /* 
  408. EXPORT_SYMBOL(irq);
  409. EXPORT_SYMBOL(io);
  410. */
  411. MODULE_PARM(irq,"i");
  412. MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required");
  413. MODULE_PARM(io,"i");
  414. MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required");
  415. int awc4500_isa_probe(struct net_device *dev)
  416. {
  417. // int cards_found = 0;
  418. // static int isa_index; /* Static, for multiple probe calls. */
  419. int isa_irq_line = 0;
  420. int isa_ioaddr = 0;
  421. // int p;
  422. int card = 0;
  423. int i=0;
  424. if (! io[0] || ! irq[0]){
  425. // printk("       Both irq and io params must be supplied  for ISA mode !!!n");
  426. return -ENODEV;
  427. }
  428. printk(KERN_WARNING "     Aironet ISA Card in non-PNP(ISA) mode sometimes feels bad on interrupt n");
  429. printk(KERN_WARNING "     Use aironet4500_pnp if any problems(i.e. card malfunctioning). n");
  430. printk(KERN_WARNING "     Note that this isa probe is not friendly... must give exact parameters n");
  431. while (irq[card] != 0){
  432. isa_ioaddr = io[card];
  433. isa_irq_line = irq[card];
  434. request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
  435. if (!dev) {
  436. dev = init_etherdev(NULL, 0);
  437. if (!dev) {
  438. release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
  439. return (card == 0) ? -ENOMEM : 0;
  440. }
  441. }
  442. dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
  443. memset(dev->priv,0,sizeof(struct awc_private));
  444. if (!dev->priv) {
  445. printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follown");
  446. return -1;
  447. };
  448. // ether_setup(dev);
  449. // dev->tx_queue_len = tx_queue_len;
  450. dev->hard_start_xmit =  &awc_start_xmit;
  451. // dev->set_config =  &awc_config_misiganes,aga mitte awc_config;
  452. dev->get_stats =  &awc_get_stats;
  453. // dev->set_multicast_list =  &awc_set_multicast_list;
  454. dev->change_mtu = awc_change_mtu;
  455. dev->init = &awc_init;
  456. dev->open = &awc_open;
  457. dev->stop = &awc_close;
  458.      dev->base_addr = isa_ioaddr;
  459.      dev->irq = isa_irq_line;
  460. dev->tx_timeout = &awc_tx_timeout;
  461. dev->watchdog_timeo = AWC_TX_TIMEOUT;
  462. request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev);
  463. awc_private_init( dev);
  464. if ( awc_init(dev) ){
  465. printk("card not found at irq %x mem %xn",irq[card],io[card]);
  466. if (card==0)
  467. return -1;
  468. break;
  469. }
  470. i=0;
  471. while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
  472. if (!aironet4500_devices[i]){
  473. aironet4500_devices[i]=dev;
  474. ((struct awc_private *)
  475. aironet4500_devices[i]->priv)->card_type = AIRONET4500_ISA;
  476. if (awc_proc_set_fun)
  477. awc_proc_set_fun(i);
  478. }
  479. card++;
  480. }
  481. if (card == 0 ) {
  482. return -ENODEV;
  483. };
  484. return 0;
  485. }
  486. #ifdef MODULE
  487. static void awc_isa_release(void) {
  488. // long flags;
  489. int i=0;
  490. DEBUG(0, "awc_detach n");
  491. i=0;
  492. while ( i < MAX_AWCS) {
  493. if (!aironet4500_devices[i])
  494.                   {i++;      continue;}
  495. if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_ISA)
  496.                   {i++;      continue;}
  497. if (awc_proc_unset_fun)
  498. awc_proc_unset_fun(i);
  499. release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
  500. // release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
  501. // release_region(isa_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
  502. unregister_netdev(aironet4500_devices[i]);
  503. free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]);
  504. kfree(aironet4500_devices[i]->priv);
  505. kfree(aironet4500_devices[i]);
  506. aironet4500_devices[i]=0;
  507. i++;
  508. }
  509.            
  510. #endif //MODULE   
  511. #endif /* CONFIG_AIRONET4500_ISA */
  512. #ifdef  CONFIG_AIRONET4500_I365 
  513. #define port_range 0x40
  514. int awc_i365_offset_ports[] = {0x3e0,0x3e0,0x3e2,0x3e2};
  515. int awc_i365_data_ports [] = {0x3e1,0x3e1,0x3e3,0x3e3};
  516. int awc_i365_irq[] = {5,5,11,12};
  517. int awc_i365_io[] = {0x140,0x100,0x400,0x440};
  518. int awc_i365_sockets = 0;
  519. struct i365_socket {
  520. int offset_port ;
  521. int data_port;
  522. int socket;
  523. int irq; 
  524. int io;
  525. int manufacturer;
  526. int product;
  527. };
  528. inline u8 i365_in (struct i365_socket * s, int offset) { 
  529. outb(offset  + (s->socket % 2)* 0x40, s->offset_port);
  530. return inb(s->data_port); 
  531. };
  532. inline void i365_out (struct i365_socket * s, int offset,int data){
  533. outb(offset + (s->socket % 2)* 0x40 ,s->offset_port);
  534. outb((data & 0xff),s->data_port) ;
  535. };
  536. void awc_i365_card_release(struct i365_socket * s){
  537. i365_out(s, 0x5, 0);  // clearing ints
  538. i365_out(s, 0x6, 0x20);  // mem 16 bits
  539. i365_out(s, 0x7, 0);  // clear IO
  540. i365_out(s, 0x3, 0); // gen ctrl reset + mem mode
  541. i365_out(s, 0x2, 0); // reset power
  542. i365_out(s, 0x2, i365_in(s, 0x2) & 0x7f ); // cardenable off
  543. i365_out(s, 0x2, 0); // remove power
  544. };
  545. int awc_i365_probe_once(struct i365_socket * s ){
  546. int caps=i365_in(s, 0);
  547. int ret;
  548. unsigned long jiff;
  549. // short rev = 0x3000;
  550. unsigned char cis [0x3e3];
  551. unsigned char * mem = phys_to_virt(0xd000);
  552. int i;
  553. int port ;
  554. DEBUG(1," i365 control ID %x n", caps);
  555. if (caps & 0xC){
  556. return 1;
  557. };
  558. ret = i365_in(s, 0x1);
  559. if ((ret & 0xC0) != 0xC0){
  560. printk("card in socket %d port %x not in known state, %x n",
  561. s->socket, s->offset_port, ret );
  562. return -1;
  563. };
  564. awc_i365_card_release(s);
  565. mdelay(100);
  566. i365_out(s, 0x2, 0x10 );  // power enable
  567. mdelay(200);
  568. i365_out(s, 0x2, 0x10 | 0x01 | 0x04 | 0x80); //power enable
  569. mdelay(250);
  570. if (!s->irq)
  571. s->irq = 11;
  572. i365_out(s, 0x3, 0x40 | 0x20 | s->irq);
  573. jiff = jiffies;
  574. while (jiffies-jiff < HZ ) 
  575. if (i365_in(s,0x1) & 0x20)
  576. break;
  577. if (! (i365_in(s,0x1) & 0x20) ){
  578. printk("irq enable timeout on socket %x n", s->socket);
  579. return -1;
  580. };
  581. i365_out(s,0x10,0xd0);
  582. i365_out(s,0x11,0x0);
  583. i365_out(s,0x12,0xd0);
  584. i365_out(s,0x13,0x0);
  585. i365_out(s,0x14,0x30 );
  586. i365_out(s,0x15,0x3f | 0x40); // enab mem reg bit
  587. i365_out(s,0x06,0x01); // enab mem 
  588. mdelay(10);
  589. cis[0] = 0x45;
  590. // memcpy_toio( 0xd3e0, &(cis[0]),0x1);
  591. // mem[0x3e0] = 0x0;
  592. // mem[0] = 0x45;
  593. mem[0x3e0] = 0x45;
  594. mdelay(10);
  595. memcpy_fromio(cis,0xD000, 0x3e0);
  596. for (i = 0; i <= 0x3e2; i++)
  597. printk("%02x", mem[i]);
  598. for (i = 0; i <= 0x3e2; i++)
  599. printk("%c", mem[i]);
  600. i=0;
  601. while (i < 0x3e0){
  602. if (cis[i] == 0xff)
  603. break;
  604. if (cis[i] != 0x20 ){
  605. i = i + 2 + cis[i+1];
  606. continue;
  607. }else {
  608. s->manufacturer = cis[i+2] | (cis[i+3]<<8);
  609. s->product = cis[i+4] | (cis[i+5]<<8);
  610. break;
  611. };
  612. i++;
  613. };
  614. DEBUG(1,"socket %x manufacturer %x product %x n",
  615. s->socket, s->manufacturer,s->product);
  616. i365_out(s,0x07, 0x1 | 0x2);  // enable io 16bit
  617. mdelay(1);
  618. port = s->io;
  619. i365_out(s,0x08, port & 0xff);
  620. i365_out(s,0x09, (port & 0xff00)/ 0x100);
  621. i365_out(s,0x0A, (port+port_range) & 0xff);
  622. i365_out(s,0x0B, ((port+port_range) & 0xff00) /0x100);
  623. i365_out(s,0x06, 0x40);  // enable io window
  624. mdelay(1);
  625. i365_out(s,0x3e0,0x45);
  626. outw(0x10, s->io);
  627. jiff = jiffies;
  628. while (!(inw(s->io + 0x30) & 0x10)){
  629. if (jiffies - jiff > HZ ){
  630. printk("timed out waitin for command ack n");
  631. break;
  632. }
  633. };
  634. outw(0x10, s->io + 0x34);
  635. mdelay(10);
  636. return 0;
  637. };
  638. static int awc_i365_init(struct i365_socket * s) {
  639. struct net_device * dev;
  640. int i;
  641. dev = init_etherdev(0, sizeof(struct awc_private) );
  642. // dev->tx_queue_len = tx_queue_len;
  643. ether_setup(dev);
  644. dev->hard_start_xmit =  &awc_start_xmit;
  645. // dev->set_config =  &awc_config_misiganes,aga mitte awc_config;
  646. dev->get_stats =  &awc_get_stats;
  647. dev->set_multicast_list =  &awc_set_multicast_list;
  648. dev->init = &awc_init;
  649. dev->open = &awc_open;
  650. dev->stop = &awc_close;
  651.      dev->irq = s->irq;
  652.      dev->base_addr = s->io;
  653. dev->tx_timeout = &awc_tx_timeout;
  654. dev->watchdog_timeo = AWC_TX_TIMEOUT;
  655. awc_private_init( dev);
  656. i=0;
  657. while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
  658. if (!aironet4500_devices[i]){
  659. aironet4500_devices[i]=dev;
  660. ((struct awc_private *)
  661. aironet4500_devices[i]->priv)->card_type = AIRONET4500_365;
  662. if (awc_proc_set_fun)
  663. awc_proc_set_fun(i);
  664. }
  665. if (register_netdev(dev) != 0) {
  666. printk(KERN_NOTICE "awc_cs: register_netdev() failedn");
  667. goto failed;
  668. }
  669. return 0;
  670.  
  671.   failed:
  672.    return -1;
  673. }
  674. static void awc_i365_release(void) {
  675. // long flags;
  676. int i=0;
  677. DEBUG(0, "awc_detach n");
  678. i=0;
  679. while ( i < MAX_AWCS) {
  680. if (!aironet4500_devices[i])
  681.          {i++; continue;}
  682. if (((struct awc_private *)aironet4500_devices[i]->priv)->card_type != AIRONET4500_365)
  683.                   {i++;      continue;}
  684. if (awc_proc_unset_fun)
  685. awc_proc_unset_fun(i);
  686. unregister_netdev(aironet4500_devices[i]);
  687. //kfree(aironet4500_devices[i]->priv);
  688. kfree(aironet4500_devices[i]);
  689. aironet4500_devices[i]=0;
  690. i++;
  691. }
  692.         
  693.         
  694. int awc_i365_probe(void) {
  695. int i = 1;
  696. int k = 0;
  697. int ret = 0;
  698. int found=0;
  699. struct i365_socket s;
  700. /* Always emit the version, before any failure. */
  701. if (!awc_i365_sockets) {
  702. printk(" awc i82635 4x00: use bitfiel opts awc_i365_sockets=0x3 <- (1|2) to probe sockets 0 and 1n");
  703. return -1;
  704. };
  705. while (k < 4){
  706. if (i & awc_i365_sockets){
  707. s.offset_port  = awc_i365_offset_ports[k];
  708. s.data_port = awc_i365_data_ports[k];
  709. s.socket = k;
  710. s.manufacturer = 0;
  711. s.product = 0;
  712. s.irq = awc_i365_irq[k];
  713. s.io = awc_i365_io[k];
  714. ret = awc_i365_probe_once(&s);
  715. if (!ret){
  716. if (awc_i365_init(&s))
  717. goto failed;
  718. else found++;
  719. } else if (ret == -1)
  720. goto failed;
  721. };
  722. k++;
  723. i *=2;
  724. };
  725. if (!found){
  726. printk("no aironet 4x00 cards foundn");
  727. return -1;
  728. }
  729. return 0;
  730. failed: 
  731. awc_i365_release();
  732. return -1;
  733. }
  734. #endif /* CONFIG_AIRONET4500_I365 */
  735. #ifdef MODULE        
  736. int init_module(void)
  737. {
  738. int found = 0;
  739. printk("%sn ", awc_version);
  740. #ifdef CONFIG_AIRONET4500_PCI
  741. if (awc4500_pci_probe(NULL) == -ENODEV){
  742. // printk("PCI 4X00 aironet cards not foundn");
  743. } else {
  744. found++;
  745. // printk("PCI 4X00 found some cards n");
  746. }
  747. #endif
  748. #ifdef CONFIG_AIRONET4500_PNP
  749. if (awc4500_pnp_probe(NULL) == -ENODEV){
  750. // printk("PNP 4X00 aironet cards not foundn");
  751. } else {
  752. found++;
  753. // printk("PNP 4X00 found some cards n");
  754. }
  755. #endif
  756. #ifdef CONFIG_AIRONET4500_365
  757. if ( awc_i365_probe() == -1) {
  758. // printk("PCMCIA 4X00 aironet cards not found for i365(without card services) initializationn");
  759. } else {
  760.  found++ ;
  761. //  printk("PCMCIA 4X00 found some cards, take care, this code is not supposed to work yet n");
  762. }
  763. #endif
  764. #ifdef CONFIG_AIRONET4500_ISA
  765. if (awc4500_isa_probe(NULL) == -ENODEV){
  766. // printk("ISA 4X00 aironet ISA-bus non-PNP-mode cards not foundn");
  767. } else {
  768. found++;
  769. // printk("ISA 4X00 found some cards n");
  770. }
  771. #endif
  772. if (!found) {
  773. printk(KERN_ERR "No Aironet 4X00 cards were found. Note that for ISA n cards you should use either automatic PNP mode or n ISA mode with both io and irq param n Aironet is also afraid of: being second PNP controller(by slot), having anything(brandname bios weirdnesses) in range 0x100-0x180 and maybe around  0xd0000n If you PNP type card does not get found, try non-PNP switch before complainig. n");
  774. return -1;
  775. }
  776. return 0;
  777. }
  778. void cleanup_module(void)
  779. {
  780. DEBUG(0, "awc_cs: unloading %c ",'n');
  781. #ifdef CONFIG_AIRONET4500_PCI
  782. awc_pci_release();
  783. #endif
  784. #ifdef CONFIG_AIRONET4500_PNP
  785. awc_pnp_release();
  786. #endif
  787. #ifdef CONFIG_AIRONET4500_365
  788. awc_i365_release();
  789. #endif
  790. #ifdef CONFIG_AIRONET4500_ISA
  791. awc_isa_release();
  792. #endif
  793. }
  794. #endif