diff options
Diffstat (limited to 'package/madwifi/patches/410-ar231x_2.6.28.patch')
-rw-r--r-- | package/madwifi/patches/410-ar231x_2.6.28.patch | 281 |
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 0000000000..87177c3986 --- /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) + { |