Staging: w35und: fix config build warnings
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / wlan-ng / prism2_pci.c
blobafe32dfbf6b1481288b48199be2efcc0952ca95f
1 #define WLAN_HOSTIF WLAN_PCI
2 #include "hfa384x.c"
3 #include "prism2mgmt.c"
4 #include "prism2mib.c"
5 #include "prism2sta.c"
7 #define PCI_SIZE 0x1000 /* Memory size - 4K bytes */
9 /* ISL3874A 11Mb/s WLAN controller */
10 #define PCIVENDOR_INTERSIL 0x1260UL
11 #define PCIDEVICE_ISL3874 0x3873UL /* [MSM] yeah I know...the ID says
12 3873. Trust me, it's a 3874. */
14 /* Samsung SWL-2210P 11Mb/s WLAN controller (uses ISL3874A) */
15 #define PCIVENDOR_SAMSUNG 0x167dUL
16 #define PCIDEVICE_SWL_2210P 0xa000UL
18 #define PCIVENDOR_NETGEAR 0x1385UL /* for MA311 */
20 /* PCI Class & Sub-Class code, Network-'Other controller' */
21 #define PCI_CLASS_NETWORK_OTHERS 0x280
24 /*----------------------------------------------------------------
25 * prism2sta_probe_pci
27 * Probe routine called when a PCI device w/ matching ID is found.
28 * The ISL3874 implementation uses the following map:
29 * BAR0: Prism2.x registers memory mapped, size=4k
30 * Here's the sequence:
31 * - Allocate the PCI resources.
32 * - Read the PCMCIA attribute memory to make sure we have a WLAN card
33 * - Reset the MAC
34 * - Initialize the netdev and wlan data
35 * - Initialize the MAC
37 * Arguments:
38 * pdev ptr to pci device structure containing info about
39 * pci configuration.
40 * id ptr to the device id entry that matched this device.
42 * Returns:
43 * zero - success
44 * negative - failed
46 * Side effects:
49 * Call context:
50 * process thread
52 ----------------------------------------------------------------*/
53 static int __devinit
54 prism2sta_probe_pci(
55 struct pci_dev *pdev,
56 const struct pci_device_id *id)
58 int result;
59 phys_t phymem = 0;
60 void __iomem *mem = NULL;
61 wlandevice_t *wlandev = NULL;
62 hfa384x_t *hw = NULL;
64 DBFENTER;
66 /* Enable the pci device */
67 if (pci_enable_device(pdev)) {
68 WLAN_LOG_ERROR("%s: pci_enable_device() failed.\n", dev_info);
69 result = -EIO;
70 goto fail;
73 /* Figure out our resources */
74 phymem = pci_resource_start(pdev, 0);
76 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
77 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
78 result = -EIO;
79 goto fail;
82 mem = ioremap(phymem, PCI_SIZE);
83 if ( mem == 0 ) {
84 WLAN_LOG_ERROR("%s: ioremap() failed.\n", dev_info);
85 result = -EIO;
86 goto fail;
89 /* Log the device */
90 WLAN_LOG_INFO("A Prism2.5 PCI device found, "
91 "phymem:0x%llx, irq:%d, mem:0x%p\n",
92 (unsigned long long)phymem, pdev->irq, mem);
94 if ((wlandev = create_wlan()) == NULL) {
95 WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
96 result = -EIO;
97 goto fail;
99 hw = wlandev->priv;
101 if ( wlan_setup(wlandev) != 0 ) {
102 WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
103 result = -EIO;
104 goto fail;
107 /* Setup netdevice's ability to report resources
108 * Note: the netdevice was allocated by wlan_setup()
110 wlandev->netdev->irq = pdev->irq;
111 wlandev->netdev->mem_start = (unsigned long) mem;
112 wlandev->netdev->mem_end = wlandev->netdev->mem_start +
113 pci_resource_len(pdev, 0);
115 /* Initialize the hw data */
116 hfa384x_create(hw, wlandev->netdev->irq, 0, mem);
117 hw->wlandev = wlandev;
119 /* Register the wlandev, this gets us a name and registers the
120 * linux netdevice.
122 SET_MODULE_OWNER(wlandev->netdev);
123 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
124 SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
125 #endif
126 if ( register_wlandev(wlandev) != 0 ) {
127 WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
128 result = -EIO;
129 goto fail;
132 #if 0
133 /* TODO: Move this and an irq test into an hfa384x_testif() routine.
135 outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
136 reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
137 if ( reg != PRISM2STA_MAGIC ) {
138 WLAN_LOG_ERROR("MAC register access test failed!\n");
139 result = -EIO;
140 goto fail;
142 #endif
144 /* Do a chip-level reset on the MAC */
145 if (prism2_doreset) {
146 result = hfa384x_corereset(hw,
147 prism2_reset_holdtime,
148 prism2_reset_settletime, 0);
149 if (result != 0) {
150 WLAN_LOG_ERROR(
151 "%s: hfa384x_corereset() failed.\n",
152 dev_info);
153 unregister_wlandev(wlandev);
154 hfa384x_destroy(hw);
155 result = -EIO;
156 goto fail;
160 pci_set_drvdata(pdev, wlandev);
162 /* Shouldn't actually hook up the IRQ until we
163 * _know_ things are alright. A test routine would help.
165 request_irq(wlandev->netdev->irq, hfa384x_interrupt,
166 SA_SHIRQ, wlandev->name, wlandev);
168 wlandev->msdstate = WLAN_MSD_HWPRESENT;
170 result = 0;
171 goto done;
173 fail:
174 pci_set_drvdata(pdev, NULL);
175 if (wlandev) kfree(wlandev);
176 if (hw) kfree(hw);
177 if (mem) iounmap(mem);
178 pci_release_regions(pdev);
179 pci_disable_device(pdev);
181 done:
182 DBFEXIT;
183 return result;
186 static void __devexit prism2sta_remove_pci(struct pci_dev *pdev)
188 wlandevice_t *wlandev;
189 hfa384x_t *hw;
191 wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
192 hw = wlandev->priv;
194 p80211netdev_hwremoved(wlandev);
196 /* reset hardware */
197 prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
199 if (pdev->irq)
200 free_irq(pdev->irq, wlandev);
202 unregister_wlandev(wlandev);
204 /* free local stuff */
205 if (hw) {
206 hfa384x_destroy(hw);
207 kfree(hw);
210 iounmap((void __iomem *)wlandev->netdev->mem_start);
211 wlan_unsetup(wlandev);
213 pci_release_regions(pdev);
214 pci_disable_device(pdev);
215 pci_set_drvdata(pdev, NULL);
217 kfree(wlandev);
221 static struct pci_device_id pci_id_tbl[] = {
223 PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,
224 PCI_ANY_ID, PCI_ANY_ID,
225 0, 0,
226 /* Driver data, we just put the name here */
227 (unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"
230 PCIVENDOR_INTERSIL, 0x3872,
231 PCI_ANY_ID, PCI_ANY_ID,
232 0, 0,
233 /* Driver data, we just put the name here */
234 (unsigned long)"Intersil Prism2.5 ISL3872 11Mb/s WLAN Controller"
237 PCIVENDOR_SAMSUNG, PCIDEVICE_SWL_2210P,
238 PCI_ANY_ID, PCI_ANY_ID,
239 0, 0,
240 /* Driver data, we just put the name here */
241 (unsigned long)"Samsung MagicLAN SWL-2210P 11Mb/s WLAN Controller"
243 { /* for NetGear MA311 */
244 PCIVENDOR_NETGEAR, 0x3872,
245 PCI_ANY_ID, PCI_ANY_ID,
246 0, 0,
247 /* Driver data, we just put the name here */
248 (unsigned long)"Netgear MA311 WLAN Controller"
251 0, 0, 0, 0, 0, 0, 0
255 MODULE_DEVICE_TABLE(pci, pci_id_tbl);
257 /* Function declared here because of ptr reference below */
258 static int __devinit prism2sta_probe_pci(struct pci_dev *pdev,
259 const struct pci_device_id *id);
260 static void __devexit prism2sta_remove_pci(struct pci_dev *pdev);
262 static struct pci_driver prism2_pci_drv_id = {
263 .name = "prism2_pci",
264 .id_table = pci_id_tbl,
265 .probe = prism2sta_probe_pci,
266 .remove = prism2sta_remove_pci,
267 #ifdef CONFIG_PM
268 .suspend = prism2sta_suspend_pci,
269 .resume = prism2sta_resume_pci,
270 #endif
273 #ifdef MODULE
275 static int __init prism2pci_init(void)
277 WLAN_LOG_NOTICE("%s Loaded\n", version);
278 return pci_module_init(&prism2_pci_drv_id);
281 static void __exit prism2pci_cleanup(void)
283 pci_unregister_driver(&prism2_pci_drv_id);
286 module_init(prism2pci_init);
287 module_exit(prism2pci_cleanup);
289 #endif
291 int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
293 int result = 0;
294 unsigned long timeout;
295 UINT16 reg;
296 DBFENTER;
298 /* Assert reset and wait awhile
299 * (note: these delays are _really_ long, but they appear to be
300 * necessary.)
302 hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR);
303 timeout = jiffies + HZ/4;
304 while(time_before(jiffies, timeout)) udelay(5);
306 if (genesis) {
307 hfa384x_setreg(hw, genesis, HFA384x_PCIHCR);
308 timeout = jiffies + HZ/4;
309 while(time_before(jiffies, timeout)) udelay(5);
312 /* Clear the reset and wait some more
314 hfa384x_setreg(hw, 0x45, HFA384x_PCICOR);
315 timeout = jiffies + HZ/2;
316 while(time_before(jiffies, timeout)) udelay(5);
318 /* Wait for f/w to complete initialization (CMD:BUSY == 0)
320 timeout = jiffies + 2*HZ;
321 reg = hfa384x_getreg(hw, HFA384x_CMD);
322 while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
323 reg = hfa384x_getreg(hw, HFA384x_CMD);
324 udelay(10);
326 if (HFA384x_CMD_ISBUSY(reg)) {
327 WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n");
328 result=1;
330 DBFEXIT;
331 return result;