10 #include <linux/module.h>
14 #include <linux/netdevice.h>
15 #include <linux/slab.h>
17 #include <linux/wireless.h>
21 #include <linux/pci.h>
27 static char *
dev_info =
"hostap_plx";
37 static int ignore_cis;
49 #define PLX_MIN_ATTR_LEN 512
50 #define COR_SRESET 0x80
51 #define COR_LEVLREQ 0x40
52 #define COR_ENABLE_FUNC 0x01
54 #define PLX_PCIIPR 0x3d
56 #define PLX_INTCSR 0x4c
57 #define PLX_INTCSR_PCI_INTEN BIT(6)
58 #define PLX_CNTRL 0x50
59 #define PLX_CNTRL_SERIAL_EEPROM_PRESENT BIT(28)
62 #define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID }
65 PLXDEV(0x10b7, 0x7770,
"3Com AirConnect PCI 777A"),
66 PLXDEV(0x111a, 0x1023,
"Siemens SpeedStream SS1023"),
67 PLXDEV(0x126c, 0x8030,
"Nortel emobility"),
68 PLXDEV(0x1562, 0x0001,
"Symbol LA-4123"),
69 PLXDEV(0x1385, 0x4100,
"Netgear MA301"),
70 PLXDEV(0x15e8, 0x0130,
"National Datacomm NCP130 (PLX9052)"),
71 PLXDEV(0x15e8, 0x0131,
"National Datacomm NCP130 (TMD7160)"),
72 PLXDEV(0x1638, 0x1100,
"Eumitcom WL11000"),
73 PLXDEV(0x16ab, 0x1100,
"Global Sun Tech GL24110P"),
74 PLXDEV(0x16ab, 0x1101,
"Global Sun Tech GL24110P (?)"),
75 PLXDEV(0x16ab, 0x1102,
"Linksys WPC11 with WDT11"),
76 PLXDEV(0x16ab, 0x1103,
"Longshine 8031"),
77 PLXDEV(0x16ec, 0x3685,
"US Robotics USR2415"),
78 PLXDEV(0xec80, 0xec00,
"Belkin F5D6000"),
86 static struct prism2_plx_manfid {
88 } prism2_plx_known_manfids[] = {
107 #ifdef PRISM2_IO_DEBUG
111 struct hostap_interface *iface;
115 iface = netdev_priv(dev);
116 local = iface->local;
119 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
121 spin_unlock_irqrestore(&local->lock, flags);
126 struct hostap_interface *iface;
131 iface = netdev_priv(dev);
132 local = iface->local;
136 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
137 spin_unlock_irqrestore(&local->lock, flags);
143 struct hostap_interface *iface;
147 iface = netdev_priv(dev);
148 local = iface->local;
151 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
153 spin_unlock_irqrestore(&local->lock, flags);
158 struct hostap_interface *iface;
163 iface = netdev_priv(dev);
164 local = iface->local;
168 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
169 spin_unlock_irqrestore(&local->lock, flags);
173 static inline void hfa384x_outsw_debug(
struct net_device *
dev,
int a,
176 struct hostap_interface *iface;
180 iface = netdev_priv(dev);
181 local = iface->local;
184 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
186 spin_unlock_irqrestore(&local->lock, flags);
189 static inline void hfa384x_insw_debug(
struct net_device *
dev,
int a,
192 struct hostap_interface *iface;
196 iface = netdev_priv(dev);
197 local = iface->local;
200 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
202 spin_unlock_irqrestore(&local->lock, flags);
205 #define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
206 #define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
207 #define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
208 #define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
209 #define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
210 #define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
214 #define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
215 #define HFA384X_INB(a) inb(dev->base_addr + (a))
216 #define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
217 #define HFA384X_INW(a) inw(dev->base_addr + (a))
218 #define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
219 #define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
230 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
249 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
269 unsigned char corsave;
297 static void prism2_plx_genesis_reset(
local_info_t *local,
int hcr)
299 unsigned char corsave;
326 static struct prism2_helper_functions prism2_plx_funcs =
328 .card_present =
NULL,
329 .cor_sreset = prism2_plx_cor_sreset,
330 .genesis_reset = prism2_plx_genesis_reset,
331 .hw_type = HOSTAP_HW_PLX,
335 static int prism2_plx_check_cis(
void __iomem *attr_mem,
int attr_len,
336 unsigned int *cor_offset,
337 unsigned int *cor_index)
339 #define CISTPL_CONFIG 0x1A
340 #define CISTPL_MANFID 0x20
341 #define CISTPL_END 0xFF
342 #define CIS_MAX_LEN 256
345 unsigned int rmsz, rasz, manfid1, manfid2;
346 struct prism2_plx_manfid *manfid;
354 cis[i] =
readb(attr_mem + 2 * i);
356 dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]);
362 manfid1 = manfid2 = 0;
365 while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
366 if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN)
371 if (cis[pos + 1] < 2)
373 rmsz = (cis[pos + 2] & 0x3c) >> 2;
374 rasz = cis[pos + 2] & 0x03;
375 if (4 + rasz + rmsz > cis[pos + 1])
377 *cor_index = cis[pos + 3] & 0x3F;
379 for (i = 0; i <= rasz; i++)
380 *cor_offset += cis[pos + 4 + i] << (8 * i);
383 *cor_index, *cor_offset);
384 if (*cor_offset > attr_len) {
393 if (cis[pos + 1] < 4)
395 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
396 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
402 pos += cis[pos + 1] + 2;
405 if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END)
408 for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++)
409 if (manfid1 == manfid->manfid1 && manfid2 == manfid->manfid2) {
414 printk(
KERN_INFO "%s: unknown manfid 0x%04x, 0x%04x - assuming this is"
415 " not supported card\n",
dev_info, manfid1, manfid2);
425 "errors during CIS verification\n",
dev_info);
432 static int prism2_plx_probe(
struct pci_dev *pdev,
435 unsigned int pccard_ioaddr, plx_ioaddr;
436 unsigned long pccard_attr_mem;
437 unsigned int pccard_attr_len;
439 unsigned int cor_offset = 0, cor_index = 0;
443 struct hostap_interface *iface;
444 static int cards_found ;
445 int irq_registered = 0;
449 hw_priv = kzalloc(
sizeof(*hw_priv),
GFP_KERNEL);
457 tmd7160 = (pdev->
vendor == 0x15e8) && (pdev->
device == 0x0131);
467 "irq=%d, pccard_io=0x%x\n",
468 plx_ioaddr, pdev->
irq, pccard_ioaddr);
470 cor_offset = plx_ioaddr;
475 reg =
inb(plx_ioaddr);
490 attr_mem =
ioremap(pccard_attr_mem, pccard_attr_len);
491 if (attr_mem ==
NULL) {
498 "mem=0x%lx, plx_io=0x%x, irq=%d, pccard_io=0x%x\n",
499 pccard_attr_mem, plx_ioaddr, pdev->
irq, pccard_ioaddr);
501 if (prism2_plx_check_cis(attr_mem, pccard_attr_len,
502 &cor_offset, &cor_index)) {
504 "Prism2/2.5 card?\n");
513 attr_mem + cor_offset);
519 outl(reg | PLX_INTCSR_PCI_INTEN,
522 PLX_INTCSR_PCI_INTEN)) {
537 dev = prism2_init_local_data(&prism2_plx_funcs, cards_found,
541 iface = netdev_priv(dev);
542 local = iface->local;
543 local->hw_priv = hw_priv;
551 pci_set_drvdata(pdev, dev);
560 if (prism2_hw_config(dev, 1)) {
566 return hostap_hw_ready(dev);
569 if (irq_registered && dev)
576 prism2_free_local_data(dev);
585 static void prism2_plx_remove(
struct pci_dev *pdev)
588 struct hostap_interface *iface;
591 dev = pci_get_drvdata(pdev);
592 iface = netdev_priv(dev);
593 hw_priv = iface->local->hw_priv;
596 prism2_plx_cor_sreset(iface->local);
597 hfa384x_disable_interrupts(dev);
604 prism2_free_local_data(dev);
612 static struct pci_driver prism2_plx_driver = {
613 .name =
"hostap_plx",
614 .id_table = prism2_plx_id_table,
615 .probe = prism2_plx_probe,
616 .remove = prism2_plx_remove,