cdbe335ca5fe4e7d4a2916c84ff520d849f75e54
[openwrt.git] / package / acx / patches / 003-native_vlynq.patch
1 Binary files acx-20071003/.pci.c.swp and acx-20071003.new/.pci.c.swp differ
2 diff -urN acx-20071003/acx_struct.h acx-20071003.new/acx_struct.h
3 --- acx-20071003/acx_struct.h 2007-10-03 17:42:18.000000000 +0200
4 +++ acx-20071003.new/acx_struct.h 2008-01-04 02:06:43.000000000 +0100
5 @@ -1440,7 +1440,13 @@
6
7 const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */
8
9 +#ifdef CONFIG_PCI
10 struct pci_dev *pdev;
11 +#endif
12 +#ifdef CONFIG_VLYNQ
13 + struct vlynq_device *vdev;
14 +#endif
15 + struct device *bus_dev;
16
17 unsigned long membase;
18 unsigned long membase2;
19 diff -urN acx-20071003/pci.c acx-20071003.new/pci.c
20 --- acx-20071003/pci.c 2008-01-04 02:05:00.000000000 +0100
21 +++ acx-20071003.new/pci.c 2008-01-04 03:10:42.000000000 +0100
22 @@ -59,12 +59,17 @@
23 #include <linux/pm.h>
24 #include <linux/vmalloc.h>
25 #include <linux/dma-mapping.h>
26 +#ifdef CONFIG_VLYNQ
27 +#include <linux/vlynq.h>
28 +#endif
29 +
30
31 #include "acx.h"
32
33
34 /***********************************************************************
35 */
36 +#ifdef CONFIG_PCI
37 #define PCI_TYPE (PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE)
38 #define PCI_ACX100_REGION1 0x01
39 #define PCI_ACX100_REGION1_SIZE 0x1000 /* Memory size - 4K bytes */
40 @@ -102,7 +107,7 @@
41 #define PCI_POWER_ERROR -1
42 #endif
43
44 -
45 +#endif
46 /***********************************************************************
47 */
48 static void acxpci_i_tx_timeout(struct net_device *ndev);
49 @@ -653,11 +658,11 @@
50 snprintf(filename, sizeof(filename), "tiacx1%02dc%02X",
51 IS_ACX111(adev)*11, adev->radio_type);
52
53 - fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size);
54 + fw_image = acx_s_read_fw(adev->bus_dev, filename, &file_size);
55 if (!fw_image) {
56 adev->need_radio_fw = 1;
57 filename[sizeof("tiacx1NN")-1] = '\0';
58 - fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size);
59 + fw_image = acx_s_read_fw(adev->bus_dev, filename, &file_size);
60 if (!fw_image) {
61 FN_EXIT1(NOT_OK);
62 return NOT_OK;
63 @@ -716,7 +721,7 @@
64 snprintf(filename, sizeof(filename), "tiacx1%02dr%02X",
65 IS_ACX111(adev)*11,
66 adev->radio_type);
67 - radio_image = acx_s_read_fw(&adev->pdev->dev, filename, &size);
68 + radio_image = acx_s_read_fw(adev->bus_dev, filename, &size);
69 if (!radio_image) {
70 printk("acx: can't load radio module '%s'\n", filename);
71 goto fail;
72 @@ -933,7 +938,9 @@
73
74 ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1;
75 if (!ecpu_ctrl) {
76 +#ifdef CONFIG_PCI
77 acxpci_l_reset_mac(adev);
78 +#endif
79 ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1;
80 }
81
82 @@ -1473,6 +1480,7 @@
83 static void
84 dummy_netdev_init(struct net_device *ndev) {}
85
86 +#ifdef CONFIG_PCI
87 static int __devinit
88 acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
89 {
90 @@ -1606,6 +1614,7 @@
91 ** just _presume_ that we're under sem (instead of actually taking it): */
92 /* acx_sem_lock(adev); */
93 adev->pdev = pdev;
94 + adev->bus_dev = &pdev->dev;
95 adev->ndev = ndev;
96 adev->dev_type = DEVTYPE_PCI;
97 adev->chip_type = chip_type;
98 @@ -1956,7 +1965,7 @@
99 return OK;
100 }
101 #endif /* CONFIG_PM */
102 -
103 +#endif /* CONFIG_PCI */
104
105 /***********************************************************************
106 ** acxpci_s_up
107 @@ -2051,7 +2060,7 @@
108 /* then wait until interrupts have finished executing on other CPUs */
109 acx_lock(adev, flags);
110 disable_acx_irq(adev);
111 - synchronize_irq(adev->pdev->irq);
112 + synchronize_irq(adev->irq);
113 acx_unlock(adev, flags);
114
115 /* we really don't want to have an asynchronous tasklet disturb us
116 @@ -3573,9 +3582,8 @@
117 {
118 void *ptr;
119
120 - ptr = dma_alloc_coherent(adev->pdev ? &adev->pdev->dev : NULL,
121 - size, phy, GFP_KERNEL);
122 -
123 + ptr = dma_alloc_coherent(adev->bus_dev, size, phy, GFP_KERNEL);
124 +
125 if (ptr) {
126 log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n",
127 msg, (int)size, ptr, (unsigned long long)*phy);
128 @@ -4137,6 +4145,379 @@
129 }
130
131
132 +#ifdef CONFIG_VLYNQ
133 +struct vlynq_reg_config {
134 + u32 offset;
135 + u32 value;
136 +};
137 +
138 +struct vlynq_known {
139 + u32 chip_id;
140 + char name[32];
141 + struct vlynq_mapping rx_mapping[4];
142 + int irq;
143 + int irq_type;
144 + int num_regs;
145 + struct vlynq_reg_config regs[10];
146 +};
147 +
148 +#define CHIP_TNETW1130 0x00000009
149 +#define CHIP_TNETW1350 0x00000029
150 +static struct vlynq_known known_devices[] = {
151 + {
152 + .chip_id = CHIP_TNETW1130, .name = "TI TNETW1130",
153 + .rx_mapping = {
154 + { .size = 0x22000, .offset = 0xf0000000 },
155 + { .size = 0x40000, .offset = 0xc0000000 },
156 + { .size = 0x0, .offset = 0x0 },
157 + { .size = 0x0, .offset = 0x0 },
158 + },
159 + .irq = 0,
160 + .irq_type = IRQ_TYPE_EDGE_RISING,
161 + .num_regs = 5,
162 + .regs = {
163 + {
164 + .offset = 0x790,
165 + .value = (0xd0000000 - PHYS_OFFSET)
166 + },
167 + {
168 + .offset = 0x794,
169 + .value = (0xd0000000 - PHYS_OFFSET)
170 + },
171 + { .offset = 0x740, .value = 0 },
172 + { .offset = 0x744, .value = 0x00010000 },
173 + { .offset = 0x764, .value = 0x00010000 },
174 + },
175 + },
176 + {
177 + .chip_id = CHIP_TNETW1350, .name = "TI TNETW1350",
178 + .rx_mapping = {
179 + { .size = 0x100000, .offset = 0x00300000 },
180 + { .size = 0x80000, .offset = 0x00000000 },
181 + { .size = 0x0, .offset = 0x0 },
182 + { .size = 0x0, .offset = 0x0 },
183 + },
184 + .irq = 0,
185 + .irq_type = IRQ_TYPE_EDGE_RISING,
186 + .num_regs = 5,
187 + .regs = {
188 + {
189 + .offset = 0x790,
190 + .value = (0x60000000 - PHYS_OFFSET)
191 + },
192 + {
193 + .offset = 0x794,
194 + .value = (0x60000000 - PHYS_OFFSET)
195 + },
196 + { .offset = 0x740, .value = 0 },
197 + { .offset = 0x744, .value = 0x00010000 },
198 + { .offset = 0x764, .value = 0x00010000 },
199 + },
200 + },
201 +};
202 +
203 +static struct vlynq_device_id acx_vlynq_id[] = {
204 + { CHIP_TNETW1130, vlynq_div_auto, 0 },
205 + { CHIP_TNETW1350, vlynq_div_auto, 1 },
206 + { 0, 0, 0 },
207 +};
208 +
209 +static __devinit int vlynq_probe(struct vlynq_device *vdev,
210 + struct vlynq_device_id *id)
211 +{
212 + int result = -EIO, i;
213 + u32 addr;
214 + acx_device_t *adev = NULL;
215 + struct net_device *ndev = NULL;
216 + acx111_ie_configoption_t co;
217 + struct vlynq_mapping mapping[4] = { { 0, }, };
218 + struct vlynq_known *match = NULL;
219 + int err;
220 +
221 + FN_ENTER;
222 + result = vlynq_enable_device(vdev);
223 + if (result)
224 + return result;
225 +
226 + match = &known_devices[id->driver_data];
227 +
228 + if (!match) {
229 + result = -ENODEV;
230 + goto fail;
231 + }
232 +
233 + mapping[0].offset = ARCH_PFN_OFFSET << PAGE_SHIFT;
234 + mapping[0].size = 0x02000000;
235 + vlynq_set_local_mapping(vdev, vdev->mem_start, mapping);
236 + vlynq_set_remote_mapping(vdev, 0, match->rx_mapping);
237 +
238 + set_irq_type(vlynq_virq_to_irq(vdev, match->irq), match->irq_type);
239 +
240 + addr = (u32)ioremap(vdev->mem_start, 0x1000);
241 + if (!addr) {
242 + printk(KERN_ERR "%s: failed to remap io memory\n",
243 + vdev->dev.bus_id);
244 + result = -ENXIO;
245 + goto fail;
246 + }
247 +
248 + for (i = 0; i < match->num_regs; i++)
249 + iowrite32(match->regs[i].value,
250 + (u32 *)(addr + match->regs[i].offset));
251 +
252 + iounmap((void *)addr);
253 +
254 + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init);
255 + /* (NB: memsets to 0 entire area) */
256 + if (!ndev) {
257 + printk("acx: no memory for netdevice struct\n");
258 + goto fail_alloc_netdev;
259 + }
260 + ether_setup(ndev);
261 + ndev->open = &acxpci_e_open;
262 + ndev->stop = &acxpci_e_close;
263 + ndev->hard_start_xmit = &acx_i_start_xmit;
264 + ndev->get_stats = &acx_e_get_stats;
265 +#if IW_HANDLER_VERSION <= 5
266 + ndev->get_wireless_stats = &acx_e_get_wireless_stats;
267 +#endif
268 + ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def;
269 + ndev->set_multicast_list = &acxpci_i_set_multicast_list;
270 + ndev->tx_timeout = &acxpci_i_tx_timeout;
271 + ndev->change_mtu = &acx_e_change_mtu;
272 + ndev->watchdog_timeo = 4 * HZ;
273 +
274 + adev = ndev2adev(ndev);
275 +
276 + memset(adev, 0, sizeof(*adev));
277 + /** Set up our private interface **/
278 + spin_lock_init(&adev->lock); /* initial state: unlocked */
279 + /* We do not start with downed sem: we want PARANOID_LOCKING to work */
280 + sema_init(&adev->sem, 1);
281 + /* since nobody can see new netdev yet, we can as well
282 + ** just _presume_ that we're under sem (instead of actually taking it): */
283 + /* acx_sem_lock(adev); */
284 + adev->ndev = ndev;
285 + adev->vdev = vdev;
286 + adev->bus_dev = &vdev->dev;
287 + adev->dev_type = DEVTYPE_PCI;
288 +
289 +/** Finished with private interface **/
290 +
291 + vlynq_set_drvdata(vdev, ndev);
292 + if (!request_mem_region(vdev->mem_start, vdev->mem_end - vdev->mem_start, "acx")) {
293 + printk("acx: cannot reserve VLYNQ memory region\n");
294 + goto fail_request_mem_region;
295 + }
296 + adev->iobase = ioremap(vdev->mem_start, vdev->mem_end - vdev->mem_start);
297 + if (!adev->iobase) {
298 + printk("acx: ioremap() FAILED\n");
299 + goto fail_ioremap;
300 + }
301 + adev->iobase2 = adev->iobase + match->rx_mapping[0].size;
302 + adev->chip_type = CHIPTYPE_ACX111;
303 + adev->chip_name = match->name;
304 + adev->io = IO_ACX111;
305 + ndev->irq = vlynq_virq_to_irq(vdev, match->irq);
306 + ndev->base_addr = adev->iobase;
307 +
308 + printk("acx: found %s-based wireless network card at %s, irq:%d, "
309 + "phymem:0x%x, mem:0x%p\n",
310 + match->name, vdev->dev.bus_id, ndev->irq,
311 + vdev->mem_start, adev->iobase);
312 + log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug);
313 +
314 + if (0 == ndev->irq) {
315 + printk("acx: can't use IRQ 0\n");
316 + goto fail_irq;
317 + }
318 +
319 + /* to find crashes due to weird driver access
320 + * to unconfigured interface (ifup) */
321 + adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead;
322 +#ifdef NONESSENTIAL_FEATURES
323 + acx_show_card_eeprom_id(adev);
324 +#endif /* NONESSENTIAL_FEATURES */
325 +
326 +#ifdef SET_MODULE_OWNER
327 + SET_MODULE_OWNER(ndev);
328 +#endif
329 + SET_NETDEV_DEV(ndev, adev->bus_dev);
330 +
331 + log(L_IRQ|L_INIT, "using IRQ %d\n", ndev->irq);
332 +
333 +
334 + /* ok, pci setup is finished, now start initializing the card */
335 +
336 + /* NB: read_reg() reads may return bogus data before reset_dev(),
337 + * since the firmware which directly controls large parts of the I/O
338 + * registers isn't initialized yet.
339 + * acx100 seems to be more affected than acx111 */
340 + if (OK != acxpci_s_reset_dev(adev))
341 + goto fail_reset;
342 +
343 + if (OK != acx_s_init_mac(adev))
344 + goto fail_init_mac;
345 +
346 + acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS);
347 +/* TODO: merge them into one function, they are called just once and are the same for pci & usb */
348 + if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version))
349 + goto fail_read_eeprom_version;
350 +
351 + acx_s_parse_configoption(adev, &co);
352 + acx_s_set_defaults(adev);
353 + acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */
354 + acx_display_hardware_details(adev);
355 +
356 + /* Register the card, AFTER everything else has been set up,
357 + * since otherwise an ioctl could step on our feet due to
358 + * firmware operations happening in parallel or uninitialized data */
359 +
360 +
361 + acx_proc_register_entries(ndev);
362 +
363 + /* Now we have our device, so make sure the kernel doesn't try
364 + * to send packets even though we're not associated to a network yet */
365 + acx_stop_queue(ndev, "on probe");
366 + acx_carrier_off(ndev, "on probe");
367 +
368 + /* after register_netdev() userspace may start working with dev
369 + * (in particular, on other CPUs), we only need to up the sem */
370 + /* acx_sem_unlock(adev); */
371 +
372 + printk("acx " ACX_RELEASE ": net device %s, driver compiled "
373 + "against wireless extensions %d and Linux %s\n",
374 + ndev->name, WIRELESS_EXT, UTS_RELEASE);
375 +
376 + log(L_IRQ | L_INIT, "using IRQ %d\n", ndev->irq);
377 +
378 +/** done with board specific setup **/
379 + err = register_netdev(ndev);
380 + if (OK != err) {
381 + printk("acx: register_netdev() FAILED: %d\n", err);
382 + goto fail_register_netdev;
383 + }
384 +
385 +#if CMD_DISCOVERY
386 + great_inquisitor(adev);
387 +#endif
388 +
389 + result = OK;
390 + goto done;
391 +
392 + /* error paths: undo everything in reverse order... */
393 +
394 +
395 + acxpci_s_delete_dma_regions(adev);
396 +
397 + fail_init_mac:
398 + fail_read_eeprom_version:
399 + fail_reset:
400 + free_netdev(ndev);
401 +
402 + fail_alloc_netdev:
403 + fail_irq:
404 +
405 + iounmap(adev->iobase);
406 + fail_ioremap:
407 +
408 + release_mem_region(vdev->mem_start, vdev->mem_end - vdev->mem_start);
409 + fail_request_mem_region:
410 + fail_register_netdev:
411 + fail:
412 + vlynq_disable_device(vdev);
413 + done:
414 + FN_EXIT1(result);
415 + return result;
416 +}
417 +
418 +static void vlynq_remove(struct vlynq_device *vdev)
419 +{
420 + struct net_device *ndev = vlynq_get_drvdata(vdev);;
421 + acx_device_t *adev;
422 + unsigned long flags;
423 + FN_ENTER;
424 +
425 + if (!ndev) {
426 + log(L_DEBUG, "%s: card is unused. Skipping any release code\n",
427 + __func__);
428 + goto end;
429 + }
430 +
431 + acx_lock(adev, flags);
432 + adev = ndev2adev(ndev);
433 + acx_unlock(adev, flags);
434 +
435 + /* If device wasn't hot unplugged... */
436 + if (adev_present(adev)) {
437 +
438 + acx_sem_lock(adev);
439 +
440 + /* disable both Tx and Rx to shut radio down properly */
441 + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0);
442 + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0);
443 + acx_lock(adev, flags);
444 + /* disable power LED to save power :-) */
445 + log(L_INIT, "switching off power LED to save power\n");
446 + acxpci_l_power_led(adev, 0);
447 + /* stop our eCPU */
448 + acx_unlock(adev, flags);
449 +
450 + acx_sem_unlock(adev);
451 + }
452 +
453 + /* unregister the device to not let the kernel
454 + * (e.g. ioctls) access a half-deconfigured device
455 + * NB: this will cause acxpci_e_close() to be called,
456 + * thus we shouldn't call it under sem! */
457 + log(L_INIT, "removing device %s\n", ndev->name);
458 + unregister_netdev(ndev);
459 +
460 + /* unregister_netdev ensures that no references to us left.
461 + * For paranoid reasons we continue to follow the rules */
462 + acx_sem_lock(adev);
463 +
464 +
465 + if (adev->dev_state_mask & ACX_STATE_IFACE_UP) {
466 + acxpci_s_down(ndev);
467 + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP);
468 + }
469 +
470 + acx_proc_unregister_entries(ndev);
471 +
472 + /* finally, clean up PCI bus state */
473 + acxpci_s_delete_dma_regions(adev);
474 + if (adev->iobase)
475 + iounmap(adev->iobase);
476 + if (adev->iobase2)
477 + iounmap(adev->iobase2);
478 + release_mem_region(vdev->mem_start, vdev->mem_end - vdev->mem_start);
479 +
480 + /* remove dev registration */
481 +
482 + acx_sem_unlock(adev);
483 + vlynq_disable_device(vdev);
484 +
485 + /* Free netdev (quite late,
486 + * since otherwise we might get caught off-guard
487 + * by a netdev timeout handler execution
488 + * expecting to see a working dev...) */
489 + free_netdev(ndev);
490 +
491 + end:
492 + FN_EXIT0;
493 +}
494 +
495 +static struct vlynq_driver vlynq_acx = {
496 + .name = "acx_vlynq",
497 + .id_table = acx_vlynq_id,
498 + .probe = vlynq_probe,
499 + .remove = __devexit_p(vlynq_remove),
500 +};
501 +#endif
502 +
503 +
504 +#ifdef CONFIG_PCI
505 /***********************************************************************
506 ** Data for init_module/cleanup_module
507 */
508 @@ -4192,7 +4573,7 @@
509 .resume = acxpci_e_resume
510 #endif /* CONFIG_PM */
511 };
512 -
513 +#endif /* CONFIG_PCI */
514
515 /***********************************************************************
516 ** acxpci_e_init_module
517 @@ -4202,7 +4583,7 @@
518 int __init
519 acxpci_e_init_module(void)
520 {
521 - int res;
522 + int res = 0;
523
524 FN_ENTER;
525
526 @@ -4222,11 +4603,15 @@
527 #endif
528 log(L_INIT,
529 "acx: " ENDIANNESS_STRING
530 - "acx: PCI module " ACX_RELEASE " initialized, "
531 + "acx: PCI/VLYNQ module " ACX_RELEASE " initialized, "
532 "waiting for cards to probe...\n"
533 );
534 -
535 +#ifdef CONFIG_PCI
536 res = pci_register_driver(&acxpci_drv_id);
537 +#endif
538 +#ifdef CONFIG_VLYNQ
539 + res = vlynq_register_driver(&vlynq_acx);
540 +#endif
541 FN_EXIT1(res);
542 return res;
543 }
544 @@ -4242,8 +4627,13 @@
545 acxpci_e_cleanup_module(void)
546 {
547 FN_ENTER;
548 +#ifdef CONFIG_VLYNQ
549 + vlynq_unregister_driver(&vlynq_acx);
550 +#endif
551
552 +#ifdef CONFIG_PCI
553 pci_unregister_driver(&acxpci_drv_id);
554 +#endif
555
556 FN_EXIT0;
557 }
This page took 0.074679 seconds and 3 git commands to generate.