mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 18:19:02 +00:00
26099a3c23
SVN-Revision: 16224
282 lines
7.3 KiB
Diff
282 lines
7.3 KiB
Diff
--- 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";
|
|
/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
|
|
static const struct ath_hw_detect cards[] = {
|
|
@@ -201,6 +173,114 @@ static const struct ath_hw_detect cards[
|
|
{ ubnt, "Bullet5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
|
|
};
|
|
|
|
+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)
|
|
{
|
|
@@ -253,7 +333,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;
|
|
}
|
|
@@ -263,21 +343,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;
|
|
|
|
@@ -292,6 +363,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;
|
|
@@ -312,11 +406,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)
|
|
{
|