crda: fix circular dependency
[openwrt-10.03/.git] / package / mac80211 / patches / 540-ath9k_multiple_cards_fix.patch
1 --- a/drivers/net/wireless/ath/ath9k/init.c
2 +++ b/drivers/net/wireless/ath/ath9k/init.c
3 @@ -57,7 +57,7 @@ MODULE_PARM_DESC(blink, "Enable LED blin
4   * on 5 MHz steps, we support the channels which we know
5   * we have calibration data for all cards though to make
6   * this static */
7 -static struct ieee80211_channel ath9k_2ghz_chantable[] = {
8 +static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
9         CHAN2G(2412, 0), /* Channel 1 */
10         CHAN2G(2417, 1), /* Channel 2 */
11         CHAN2G(2422, 2), /* Channel 3 */
12 @@ -78,7 +78,7 @@ static struct ieee80211_channel ath9k_2g
13   * on 5 MHz steps, we support the channels which we know
14   * we have calibration data for all cards though to make
15   * this static */
16 -static struct ieee80211_channel ath9k_5ghz_chantable[] = {
17 +static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
18         /* _We_ call this UNII 1 */
19         CHAN5G(5180, 14), /* Channel 36 */
20         CHAN5G(5200, 15), /* Channel 40 */
21 @@ -478,10 +478,17 @@ err:
22         return -EIO;
23  }
24  
25 -static void ath9k_init_channels_rates(struct ath_softc *sc)
26 +static int ath9k_init_channels_rates(struct ath_softc *sc)
27  {
28 +       void *channels;
29 +
30         if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
31 -               sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
32 +               channels = kmemdup(ath9k_2ghz_chantable,
33 +                       sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
34 +               if (!channels)
35 +                   return -ENOMEM;
36 +
37 +               sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
38                 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
39                 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
40                         ARRAY_SIZE(ath9k_2ghz_chantable);
41 @@ -491,7 +498,15 @@ static void ath9k_init_channels_rates(st
42         }
43  
44         if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
45 -               sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
46 +               channels = kmemdup(ath9k_5ghz_chantable,
47 +                       sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
48 +               if (!channels) {
49 +                       if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
50 +                               kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
51 +                       return -ENOMEM;
52 +               }
53 +
54 +               sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
55                 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
56                 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
57                         ARRAY_SIZE(ath9k_5ghz_chantable);
58 @@ -500,6 +515,7 @@ static void ath9k_init_channels_rates(st
59                 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
60                         ARRAY_SIZE(ath9k_legacy_rates) - 4;
61         }
62 +       return 0;
63  }
64  
65  static void ath9k_init_misc(struct ath_softc *sc)
66 @@ -603,8 +619,11 @@ static int ath9k_init_softc(u16 devid, s
67         if (ret)
68                 goto err_btcoex;
69  
70 +       ret = ath9k_init_channels_rates(sc);
71 +       if (ret)
72 +               goto err_btcoex;
73 +
74         ath9k_init_crypto(sc);
75 -       ath9k_init_channels_rates(sc);
76         ath9k_init_misc(sc);
77  
78         return 0;
79 @@ -786,6 +805,12 @@ static void ath9k_deinit_softc(struct at
80  {
81         int i = 0;
82  
83 +       if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
84 +               kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
85 +
86 +       if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
87 +               kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
88 +
89          if ((sc->btcoex.no_stomp_timer) &&
90             sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
91                 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);