summaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/410-ar231x_2.6.28.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/madwifi/patches/410-ar231x_2.6.28.patch')
-rw-r--r--package/madwifi/patches/410-ar231x_2.6.28.patch281
1 files changed, 281 insertions, 0 deletions
diff --git a/package/madwifi/patches/410-ar231x_2.6.28.patch b/package/madwifi/patches/410-ar231x_2.6.28.patch
new file mode 100644
index 000000000..87177c398
--- /dev/null
+++ b/package/madwifi/patches/410-ar231x_2.6.28.patch
@@ -0,0 +1,281 @@
+--- a/ath/if_ath_ahb.c
++++ b/ath/if_ath_ahb.c
+@@ -33,20 +33,15 @@
+ #include "if_ath_ahb.h"
+ #include "ah_soc.h"
+
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+-#error "Kernel versions older than 2.6.19 are not supported!"
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
++#include <ar231x_platform.h>
+ #endif
+
+ struct ath_ahb_softc {
+ struct ath_softc aps_sc;
+-#ifdef CONFIG_PM
+- u32 aps_pmstate[16];
+-#endif
++ struct ar531x_config aps_config;
+ };
+
+-static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
+-static u_int8_t num_activesc = 0;
+-
+ /*
+ * Module glue.
+ */
+@@ -101,13 +96,13 @@ ahb_enable_wmac(u_int16_t devid, u_int16
+ while (REG_READ(AR5315_PCI_MAC_PCICFG) & AR5315_PCI_MAC_PCICFG_SPWR_DN);
+ } else {
+ switch (wlanNum) {
+- case AR531X_WLAN0_NUM:
++ case 0:
+ reset = (AR531X_RESET_WLAN0 |
+ AR531X_RESET_WARM_WLAN0_MAC |
+ AR531X_RESET_WARM_WLAN0_BB);
+ enable = AR531X_ENABLE_WLAN0;
+ break;
+- case AR531X_WLAN1_NUM:
++ case 1:
+ reset = (AR531X_RESET_WLAN1 |
+ AR531X_RESET_WARM_WLAN1_MAC |
+ AR531X_RESET_WARM_WLAN1_BB);
+@@ -144,10 +139,10 @@ ahb_disable_wmac(u_int16_t devid, u_int1
+ *en &= ~AR5315_ARB_WLAN;
+ } else {
+ switch (wlanNum) {
+- case AR531X_WLAN0_NUM:
++ case 0:
+ enable = AR531X_ENABLE_WLAN0;
+ break;
+- case AR531X_WLAN1_NUM:
++ case 1:
+ enable = AR531X_ENABLE_WLAN1;
+ break;
+ default:
+@@ -159,29 +154,6 @@ ahb_disable_wmac(u_int16_t devid, u_int1
+ }
+
+
+-static int
+-exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
+-{
+- struct ath_ahb_softc *sc = sclist[wlanNum];
+- struct net_device *dev;
+- u_int16_t devid;
+-
+- if (sc == NULL)
+- return -ENODEV; /* XXX: correct return value? */
+-
+- dev = sc->aps_sc.sc_dev;
+- ath_detach(dev);
+- if (dev->irq)
+- free_irq(dev->irq, dev);
+- devid = sc->aps_sc.devid;
+- config->tag = (void *)((unsigned long) devid);
+-
+- ahb_disable_wmac(devid, wlanNum);
+- free_netdev(dev);
+- sclist[wlanNum] = NULL;
+- return 0;
+-}
+-
+ static const char ubnt[] = "Ubiquiti Networks";
+ static const struct ath_hw_detect cards[] = {
+ {
+@@ -266,6 +238,114 @@ static const struct ath_hw_detect cards[
+ },
+ };
+
++static void
++ahb_hw_detect(struct ath_ahb_softc *sc, const char *radio)
++{
++ u16 *radio_data = (u16 *) radio;
++ if (radio_data) {
++ u16 vendor, id, subvendor, subid;
++ vendor = radio_data[1];
++ id = radio_data[0];
++ subvendor = radio_data[8];
++ subid = radio_data[7];
++ ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
++ }
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
++
++static int ahb_wmac_probe(struct platform_device *pdev)
++{
++ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
++ struct ath_ahb_softc *sc;
++ struct net_device *dev;
++ struct resource *res;
++ const char *athname;
++ int err;
++
++ ahb_enable_wmac(bcfg->devid, pdev->id);
++ dev = alloc_netdev(sizeof(struct ath_ahb_softc), "wifi%d", ether_setup);
++ if (!dev)
++ return -ENOMEM;
++
++ sc = dev->priv;
++ sc->aps_sc.sc_dev = dev;
++
++ dev->irq = platform_get_irq(pdev, 0);
++ if (dev->irq <= 0) {
++ printk("%s: Cannot find IRQ resource\n", dev->name);
++ goto error;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ printk("%s: Cannot find MMIO resource\n", dev->name);
++ goto error;
++ }
++
++ dev->mem_start = KSEG1ADDR(res->start);
++ dev->mem_end = KSEG1ADDR(res->end);
++ sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
++ sc->aps_sc.sc_bdev = NULL;
++
++ /* bus information for the HAL */
++ sc->aps_config.board = (const struct ar531x_boarddata *) bcfg->config;
++ sc->aps_config.radio = bcfg->radio;
++ sc->aps_config.unit = pdev->id;
++ sc->aps_config.tag = NULL;
++
++ err = ath_attach(bcfg->devid, dev, &sc->aps_config);
++ if (err != 0) {
++ printk("%s: ath_attach failed: %d\n", dev->name, err);
++ goto error;
++ }
++
++ athname = ath_hal_probe(ATHEROS_VENDOR_ID, bcfg->devid);
++ printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
++ dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
++
++ if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
++ printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
++ goto error;
++ }
++
++ sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
++ sc->aps_sc.sc_ledpin = bcfg->config->sysLedGpio;
++ sc->aps_sc.sc_invalid = 0;
++ ahb_hw_detect(sc, bcfg->radio);
++ platform_set_drvdata(pdev, dev);
++ return 0;
++
++error_dev:
++ free_irq(dev->irq, dev);
++error:
++ free_netdev(dev);
++
++ return -ENODEV;
++}
++
++
++static int ahb_wmac_remove(struct platform_device *pdev)
++{
++ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
++ struct net_device *dev;
++
++ dev = platform_get_drvdata(pdev);
++ ath_detach(dev);
++
++ if (dev->irq)
++ free_irq(dev->irq, dev);
++
++ ahb_disable_wmac(bcfg->devid, pdev->id);
++ free_netdev(dev);
++
++ return 0;
++}
++
++#else
++
++static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
++
+ static int
+ init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
+ {
+@@ -318,7 +398,7 @@ init_ath_wmac(u_int16_t devid, u_int16_t
+ sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
+ sc->aps_sc.sc_bdev = NULL;
+
+- if (request_irq(dev->irq, ath_intr, IRQF_SHARED, dev->name, dev)) {
++ if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
+ printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
+ goto bad3;
+ }
+@@ -328,21 +408,12 @@ init_ath_wmac(u_int16_t devid, u_int16_t
+ athname = ath_hal_probe(ATHEROS_VENDOR_ID, devid);
+ printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
+ dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
+- num_activesc++;
+ /* Ready to process interrupts */
+
+ sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
+ sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
+ sc->aps_sc.sc_invalid = 0;
+- radio_data = (u16 *) config->radio;
+- if (radio_data) {
+- u16 vendor, id, subvendor, subid;
+- vendor = radio_data[1];
+- id = radio_data[0];
+- subvendor = radio_data[8];
+- subid = radio_data[7];
+- ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
+- }
++ ahb_hw_detect(sc, config->radio);
+
+ return 0;
+
+@@ -357,6 +428,29 @@ init_ath_wmac(u_int16_t devid, u_int16_t
+ return -ENODEV;
+ }
+
++static int
++exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
++{
++ struct ath_ahb_softc *sc = sclist[wlanNum];
++ struct net_device *dev;
++ u_int16_t devid;
++
++ if (sc == NULL)
++ return -ENODEV; /* XXX: correct return value? */
++
++ dev = sc->aps_sc.sc_dev;
++ ath_detach(dev);
++ if (dev->irq)
++ free_irq(dev->irq, dev);
++ devid = sc->aps_sc.devid;
++ config->tag = (void *)((unsigned long) devid);
++
++ ahb_disable_wmac(devid, wlanNum);
++ free_netdev(dev);
++ sclist[wlanNum] = NULL;
++ return 0;
++}
++
+ static int ahb_wmac_probe(struct platform_device *pdev)
+ {
+ u_int16_t devid;
+@@ -377,11 +471,18 @@ static int ahb_wmac_remove(struct platfo
+ return 0;
+ }
+
++#endif
++
+ static struct platform_driver ahb_wmac_driver = {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
++ .driver.name = "ar231x-wmac",
++#else
+ .driver.name = "ar531x-wmac",
++#endif
+ .probe = ahb_wmac_probe,
+ .remove = ahb_wmac_remove
+ };
++
+ int
+ ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void __user *addr)
+ {