ath9k: fix handling of tx headroom for padding
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch
1 From: Pontus Fuchs <pontusf@broadcom.com>
2 Date: Thu, 11 Jun 2015 00:12:18 +0200
3 Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations
4  dynamically
5
6 Switch from using semi hard coded interface combinations. This makes
7 it easier to announce what the firmware actually supports. This fixes
8 the case where brcmfmac announces p2p but the firmware doesn't
9 support it.
10
11 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
12 Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
13 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
14 Signed-off-by: Pontus Fuchs <pontusf@broadcom.com>
15 Signed-off-by: Arend van Spriel <arend@broadcom.com>
16 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
17 ---
18
19 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
20 +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
21 @@ -52,8 +52,6 @@
22  #define BRCMF_PNO_SCAN_COMPLETE                1
23  #define BRCMF_PNO_SCAN_INCOMPLETE      0
24  
25 -#define BRCMF_IFACE_MAX_CNT            3
26 -
27  #define WPA_OUI                                "\x00\x50\xF2"  /* WPA OUI */
28  #define WPA_OUI_TYPE                   1
29  #define RSN_OUI                                "\x00\x0F\xAC"  /* RSN OUI */
30 @@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct
31         return 0;
32  }
33  
34 -static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = {
35 -       {
36 -               .max = 1,
37 -               .types = BIT(NL80211_IFTYPE_STATION) |
38 -                        BIT(NL80211_IFTYPE_ADHOC)
39 -       },
40 -       {
41 -               .max = 4,
42 -               .types = BIT(NL80211_IFTYPE_AP)
43 -       },
44 -       {
45 -               .max = 1,
46 -               .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
47 -                        BIT(NL80211_IFTYPE_P2P_GO)
48 -       },
49 -       {
50 -               .max = 1,
51 -               .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
52 -       }
53 -};
54 -
55 -static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = {
56 -       {
57 -               .max = 2,
58 -               .types = BIT(NL80211_IFTYPE_STATION) |
59 -                        BIT(NL80211_IFTYPE_ADHOC) |
60 -                        BIT(NL80211_IFTYPE_AP)
61 -       },
62 -       {
63 -               .max = 1,
64 -               .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
65 -                        BIT(NL80211_IFTYPE_P2P_GO)
66 -       },
67 -       {
68 -               .max = 1,
69 -               .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
70 -       }
71 -};
72 -static struct ieee80211_iface_combination brcmf_iface_combos[] = {
73 -       {
74 -                .max_interfaces = BRCMF_IFACE_MAX_CNT,
75 -                .num_different_channels = 1,
76 -                .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss),
77 -                .limits = brcmf_iface_limits_sbss,
78 -       }
79 -};
80 -
81  static const struct ieee80211_txrx_stypes
82  brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
83         [NL80211_IFTYPE_STATION] = {
84 @@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
85         }
86  };
87  
88 +static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
89 +{
90 +       struct ieee80211_iface_combination *combo = NULL;
91 +       struct ieee80211_iface_limit *limits = NULL;
92 +       int i = 0, max_iface_cnt;
93 +
94 +       combo = kzalloc(sizeof(*combo), GFP_KERNEL);
95 +       if (!combo)
96 +               goto err;
97 +
98 +       limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
99 +       if (!limits)
100 +               goto err;
101 +
102 +       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
103 +                                BIT(NL80211_IFTYPE_ADHOC) |
104 +                                BIT(NL80211_IFTYPE_AP);
105 +
106 +       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
107 +               combo->num_different_channels = 2;
108 +       else
109 +               combo->num_different_channels = 1;
110 +
111 +       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
112 +               limits[i].max = 1;
113 +               limits[i++].types = BIT(NL80211_IFTYPE_STATION);
114 +               limits[i].max = 4;
115 +               limits[i++].types = BIT(NL80211_IFTYPE_AP);
116 +               max_iface_cnt = 5;
117 +       } else {
118 +               limits[i].max = 2;
119 +               limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
120 +                                   BIT(NL80211_IFTYPE_AP);
121 +               max_iface_cnt = 2;
122 +       }
123 +
124 +       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
125 +               wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
126 +                                         BIT(NL80211_IFTYPE_P2P_GO) |
127 +                                         BIT(NL80211_IFTYPE_P2P_DEVICE);
128 +               limits[i].max = 1;
129 +               limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
130 +                                   BIT(NL80211_IFTYPE_P2P_GO);
131 +               limits[i].max = 1;
132 +               limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
133 +               max_iface_cnt += 2;
134 +       }
135 +       combo->max_interfaces = max_iface_cnt;
136 +       combo->limits = limits;
137 +       combo->n_limits = i;
138 +
139 +       wiphy->iface_combinations = combo;
140 +       wiphy->n_iface_combinations = 1;
141 +       return 0;
142 +
143 +err:
144 +       kfree(limits);
145 +       kfree(combo);
146 +       return -ENOMEM;
147 +}
148 +
149  static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
150  {
151         /* scheduled scan settings */
152 @@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru
153  static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
154  {
155         struct ieee80211_supported_band *band;
156 -       struct ieee80211_iface_combination ifc_combo;
157         __le32 bandlist[3];
158         u32 n_bands;
159         int err, i;
160 @@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph
161         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
162         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
163         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
164 -       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
165 -                                BIT(NL80211_IFTYPE_ADHOC) |
166 -                                BIT(NL80211_IFTYPE_AP) |
167 -                                BIT(NL80211_IFTYPE_P2P_CLIENT) |
168 -                                BIT(NL80211_IFTYPE_P2P_GO) |
169 -                                BIT(NL80211_IFTYPE_P2P_DEVICE);
170 -       /* need VSDB firmware feature for concurrent channels */
171 -       ifc_combo = brcmf_iface_combos[0];
172 -       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
173 -               ifc_combo.num_different_channels = 2;
174 -       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
175 -               ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss),
176 -               ifc_combo.limits = brcmf_iface_limits_mbss;
177 -       }
178 -       wiphy->iface_combinations = kmemdup(&ifc_combo,
179 -                                           sizeof(ifc_combo),
180 -                                           GFP_KERNEL);
181 -       wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
182 +
183 +       err = brcmf_setup_ifmodes(wiphy, ifp);
184 +       if (err)
185 +               return err;
186 +
187         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
188         wiphy->cipher_suites = __wl_cipher_suites;
189         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
190 @@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph
191         if (!wiphy)
192                 return;
193  
194 +       if (wiphy->iface_combinations)
195 +               kfree(wiphy->iface_combinations->limits);
196         kfree(wiphy->iface_combinations);
197         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
198                 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);