add preliminary 2.6.32 support
[openwrt.git] / package / madwifi / patches / 410-ar231x_2.6.28.patch
1 --- a/ath/if_ath_ahb.c
2 +++ b/ath/if_ath_ahb.c
3 @@ -33,20 +33,15 @@
4  #include "if_ath_ahb.h"
5  #include "ah_soc.h"
6  
7 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
8 -#error "Kernel versions older than 2.6.19 are not supported!"
9 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
10 +#include <ar231x_platform.h>
11  #endif
12  
13  struct ath_ahb_softc {
14         struct ath_softc        aps_sc;
15 -#ifdef CONFIG_PM
16 -       u32 aps_pmstate[16];
17 -#endif
18 +       struct ar531x_config aps_config;
19  };
20  
21 -static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
22 -static u_int8_t num_activesc = 0;
23 -
24  /*
25   * Module glue.
26   */
27 @@ -101,13 +96,13 @@ ahb_enable_wmac(u_int16_t devid, u_int16
28                 while (REG_READ(AR5315_PCI_MAC_PCICFG) & AR5315_PCI_MAC_PCICFG_SPWR_DN);
29         } else {
30                 switch (wlanNum) {
31 -               case AR531X_WLAN0_NUM:
32 +               case 0:
33                         reset = (AR531X_RESET_WLAN0 |
34                                 AR531X_RESET_WARM_WLAN0_MAC |
35                                 AR531X_RESET_WARM_WLAN0_BB);
36                         enable = AR531X_ENABLE_WLAN0;
37                         break;
38 -               case AR531X_WLAN1_NUM:
39 +               case 1:
40                         reset = (AR531X_RESET_WLAN1 |
41                                 AR531X_RESET_WARM_WLAN1_MAC |
42                                 AR531X_RESET_WARM_WLAN1_BB);
43 @@ -144,10 +139,10 @@ ahb_disable_wmac(u_int16_t devid, u_int1
44                 *en &= ~AR5315_ARB_WLAN;
45         } else {
46                 switch (wlanNum) {
47 -               case AR531X_WLAN0_NUM:
48 +               case 0:
49                         enable = AR531X_ENABLE_WLAN0;
50                         break;
51 -               case AR531X_WLAN1_NUM:
52 +               case 1:
53                         enable = AR531X_ENABLE_WLAN1;
54                         break;
55                 default:
56 @@ -159,29 +154,6 @@ ahb_disable_wmac(u_int16_t devid, u_int1
57  }
58  
59  
60 -static int
61 -exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
62 -{
63 -       struct ath_ahb_softc *sc = sclist[wlanNum];
64 -       struct net_device *dev;
65 -       u_int16_t devid;
66 -
67 -       if (sc == NULL)
68 -               return -ENODEV; /* XXX: correct return value? */
69 -
70 -       dev = sc->aps_sc.sc_dev;
71 -       ath_detach(dev);
72 -       if (dev->irq)
73 -               free_irq(dev->irq, dev);
74 -       devid = sc->aps_sc.devid;
75 -       config->tag = (void *)((unsigned long) devid);
76 -
77 -       ahb_disable_wmac(devid, wlanNum);
78 -       free_netdev(dev);
79 -       sclist[wlanNum] = NULL;
80 -       return 0;
81 -}
82 -
83  static const char ubnt[] = "Ubiquiti Networks";
84  /* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
85  static const struct ath_hw_detect cards[] = {
86 @@ -201,6 +173,114 @@ static const struct ath_hw_detect cards[
87         { ubnt, "Bullet5",             PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
88  };
89  
90 +static void
91 +ahb_hw_detect(struct ath_ahb_softc *sc, const char *radio)
92 +{
93 +       u16 *radio_data = (u16 *) radio;
94 +       if (radio_data) {
95 +               u16 vendor, id, subvendor, subid;
96 +               vendor = radio_data[1];
97 +               id = radio_data[0];
98 +               subvendor = radio_data[8];
99 +               subid = radio_data[7];
100 +               ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
101 +       }
102 +}
103 +
104 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
105 +
106 +static int ahb_wmac_probe(struct platform_device *pdev)
107 +{
108 +       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
109 +       struct ath_ahb_softc *sc;
110 +       struct net_device *dev;
111 +       struct resource *res;
112 +       const char *athname;
113 +       int err;
114 +
115 +       ahb_enable_wmac(bcfg->devid, pdev->id);
116 +       dev = alloc_netdev(sizeof(struct ath_ahb_softc), "wifi%d", ether_setup);
117 +       if (!dev)
118 +               return -ENOMEM;
119 +
120 +       sc = dev->priv;
121 +       sc->aps_sc.sc_dev = dev;
122 +
123 +       dev->irq = platform_get_irq(pdev, 0);
124 +       if (dev->irq <= 0) {
125 +               printk("%s: Cannot find IRQ resource\n", dev->name);
126 +               goto error;
127 +       }
128 +
129 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
130 +       if (!res) {
131 +               printk("%s: Cannot find MMIO resource\n", dev->name);
132 +               goto error;
133 +       }
134 +
135 +       dev->mem_start = KSEG1ADDR(res->start);
136 +       dev->mem_end = KSEG1ADDR(res->end);
137 +       sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
138 +       sc->aps_sc.sc_bdev = NULL;
139 +
140 +       /* bus information for the HAL */
141 +       sc->aps_config.board = (const struct ar531x_boarddata *) bcfg->config;
142 +       sc->aps_config.radio = bcfg->radio;
143 +       sc->aps_config.unit = pdev->id;
144 +       sc->aps_config.tag = NULL;
145 +
146 +       err = ath_attach(bcfg->devid, dev, &sc->aps_config);
147 +       if (err != 0) {
148 +               printk("%s: ath_attach failed: %d\n", dev->name, err);
149 +               goto error;
150 +       }
151 +
152 +       athname = ath_hal_probe(ATHEROS_VENDOR_ID, bcfg->devid);
153 +       printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
154 +               dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
155 +
156 +       if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
157 +               printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
158 +               goto error;
159 +       }
160 +
161 +       sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
162 +       sc->aps_sc.sc_ledpin = bcfg->config->sysLedGpio;
163 +       sc->aps_sc.sc_invalid = 0;
164 +       ahb_hw_detect(sc, bcfg->radio);
165 +       platform_set_drvdata(pdev, dev);
166 +       return 0;
167 +
168 +error_dev:
169 +       free_irq(dev->irq, dev);
170 +error:
171 +       free_netdev(dev);
172 +
173 +       return -ENODEV;
174 +}
175 +
176 +
177 +static int ahb_wmac_remove(struct platform_device *pdev)
178 +{
179 +       struct ar231x_board_config *bcfg = pdev->dev.platform_data;
180 +       struct net_device *dev;
181 +
182 +       dev = platform_get_drvdata(pdev);
183 +       ath_detach(dev);
184 +
185 +       if (dev->irq)
186 +               free_irq(dev->irq, dev);
187 +
188 +       ahb_disable_wmac(bcfg->devid, pdev->id);
189 +       free_netdev(dev);
190 +
191 +       return 0;
192 +}
193 +
194 +#else
195 +
196 +static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
197 +
198  static int
199  init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
200  {
201 @@ -253,7 +333,7 @@ init_ath_wmac(u_int16_t devid, u_int16_t
202         sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
203         sc->aps_sc.sc_bdev = NULL;
204  
205 -       if (request_irq(dev->irq, ath_intr, IRQF_SHARED, dev->name, dev)) {
206 +       if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
207                 printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
208                 goto bad3;
209         }
210 @@ -263,21 +343,12 @@ init_ath_wmac(u_int16_t devid, u_int16_t
211         athname = ath_hal_probe(ATHEROS_VENDOR_ID, devid);
212         printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
213                 dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
214 -       num_activesc++;
215         /* Ready to process interrupts */
216  
217         sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
218         sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
219         sc->aps_sc.sc_invalid = 0;
220 -       radio_data = (u16 *) config->radio;
221 -       if (radio_data) {
222 -               u16 vendor, id, subvendor, subid;
223 -               vendor = radio_data[1];
224 -               id = radio_data[0];
225 -               subvendor = radio_data[8];
226 -               subid = radio_data[7];
227 -               ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
228 -       }
229 +       ahb_hw_detect(sc, config->radio);
230  
231         return 0;
232  
233 @@ -292,6 +363,29 @@ init_ath_wmac(u_int16_t devid, u_int16_t
234         return -ENODEV;
235  }
236  
237 +static int
238 +exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
239 +{
240 +       struct ath_ahb_softc *sc = sclist[wlanNum];
241 +       struct net_device *dev;
242 +       u_int16_t devid;
243 +
244 +       if (sc == NULL)
245 +               return -ENODEV; /* XXX: correct return value? */
246 +
247 +       dev = sc->aps_sc.sc_dev;
248 +       ath_detach(dev);
249 +       if (dev->irq)
250 +               free_irq(dev->irq, dev);
251 +       devid = sc->aps_sc.devid;
252 +       config->tag = (void *)((unsigned long) devid);
253 +
254 +       ahb_disable_wmac(devid, wlanNum);
255 +       free_netdev(dev);
256 +       sclist[wlanNum] = NULL;
257 +       return 0;
258 +}
259 +
260  static int ahb_wmac_probe(struct platform_device *pdev)
261  {
262         u_int16_t devid;
263 @@ -312,11 +406,18 @@ static int ahb_wmac_remove(struct platfo
264         return 0;
265  }
266  
267 +#endif
268 +
269  static struct platform_driver ahb_wmac_driver = {
270 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
271 +       .driver.name = "ar231x-wmac",
272 +#else
273         .driver.name = "ar531x-wmac",
274 +#endif
275         .probe = ahb_wmac_probe,
276         .remove = ahb_wmac_remove
277  };
278 +
279  int
280  ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void __user *addr)
281  {