1 --- a/drivers/net/wireless/ath/ath5k/base.c
2 +++ b/drivers/net/wireless/ath/ath5k/base.c
3 @@ -2417,6 +2417,22 @@ ath5k_tx_complete_poll_work(struct work_
4 * Initialization routines *
5 \*************************/
7 +static const struct ieee80211_iface_limit if_limits[] = {
8 + { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) },
10 +#ifdef CONFIG_MAC80211_MESH
11 + BIT(NL80211_IFTYPE_MESH_POINT) |
13 + BIT(NL80211_IFTYPE_AP) },
16 +static const struct ieee80211_iface_combination if_comb = {
17 + .limits = if_limits,
18 + .n_limits = ARRAY_SIZE(if_limits),
19 + .max_interfaces = 2048,
20 + .num_different_channels = 1,
24 ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
26 @@ -2438,6 +2454,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const
27 BIT(NL80211_IFTYPE_ADHOC) |
28 BIT(NL80211_IFTYPE_MESH_POINT);
30 + hw->wiphy->iface_combinations = &if_comb;
31 + hw->wiphy->n_iface_combinations = 1;
33 /* SW support for IBSS_RSN is provided by mac80211 */
34 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
36 --- a/net/mac80211/agg-rx.c
37 +++ b/net/mac80211/agg-rx.c
38 @@ -200,6 +200,8 @@ static void ieee80211_send_addba_resp(st
39 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
40 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
41 memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
42 + else if (sdata->vif.type == NL80211_IFTYPE_WDS)
43 + memcpy(mgmt->bssid, da, ETH_ALEN);
45 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
46 IEEE80211_STYPE_ACTION);
47 --- a/net/mac80211/agg-tx.c
48 +++ b/net/mac80211/agg-tx.c
49 @@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
50 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
51 if (sdata->vif.type == NL80211_IFTYPE_AP ||
52 sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
53 - sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
54 + sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
55 + sdata->vif.type == NL80211_IFTYPE_WDS)
56 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
57 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
58 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
59 @@ -490,6 +491,7 @@ int ieee80211_start_tx_ba_session(struct
60 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
61 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
62 sdata->vif.type != NL80211_IFTYPE_AP &&
63 + sdata->vif.type != NL80211_IFTYPE_WDS &&
64 sdata->vif.type != NL80211_IFTYPE_ADHOC)
67 --- a/net/mac80211/debugfs_sta.c
68 +++ b/net/mac80211/debugfs_sta.c
69 @@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
70 test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
72 int res = scnprintf(buf, sizeof(buf),
73 - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
74 + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
75 TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
76 TEST(PS_DRIVER), TEST(AUTHORIZED),
78 - TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
79 + TEST(WME), TEST(CLEAR_PS_FILT),
80 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
81 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
82 TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
83 --- a/net/mac80211/iface.c
84 +++ b/net/mac80211/iface.c
85 @@ -284,7 +284,6 @@ static int ieee80211_do_open(struct net_
87 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
88 struct ieee80211_local *local = sdata->local;
89 - struct sta_info *sta;
92 u32 hw_reconf_flags = 0;
93 @@ -430,28 +429,6 @@ static int ieee80211_do_open(struct net_
95 set_bit(SDATA_STATE_RUNNING, &sdata->state);
97 - if (sdata->vif.type == NL80211_IFTYPE_WDS) {
98 - /* Create STA entry for the WDS peer */
99 - sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
103 - goto err_del_interface;
106 - sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
107 - sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
108 - sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
110 - res = sta_info_insert(sta);
112 - /* STA has been freed */
113 - goto err_del_interface;
116 - rate_control_rate_init(sta);
120 * set_multicast_list will be invoked by the networking core
121 * which will check whether any increments here were done in
122 @@ -848,6 +825,72 @@ static void ieee80211_if_setup(struct ne
123 dev->destructor = free_netdev;
126 +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
127 + struct sk_buff *skb)
129 + struct ieee80211_local *local = sdata->local;
130 + struct ieee80211_rx_status *rx_status;
131 + struct ieee802_11_elems elems;
132 + struct ieee80211_mgmt *mgmt;
133 + struct sta_info *sta;
138 + enum ieee80211_band band = local->hw.conf.channel->band;
139 + struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
141 + rx_status = IEEE80211_SKB_RXCB(skb);
142 + mgmt = (struct ieee80211_mgmt *) skb->data;
143 + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
145 + if (stype != IEEE80211_STYPE_BEACON)
148 + baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
149 + if (baselen > skb->len)
152 + ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
153 + skb->len - baselen, &elems);
155 + rates = ieee80211_sta_get_rates(local, &elems, band, NULL);
159 + sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
163 + sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
171 + sta->last_rx = jiffies;
172 + sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
174 + if (elems.ht_cap_elem)
175 + ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
176 + elems.ht_cap_elem, &sta->sta.ht_cap);
178 + if (elems.wmm_param)
179 + set_sta_flag(sta, WLAN_STA_WME);
182 + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
183 + sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
184 + sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
185 + rate_control_rate_init(sta);
186 + sta_info_insert_rcu(sta);
192 static void ieee80211_iface_work(struct work_struct *work)
194 struct ieee80211_sub_if_data *sdata =
195 @@ -952,6 +995,9 @@ static void ieee80211_iface_work(struct
197 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
199 + case NL80211_IFTYPE_WDS:
200 + ieee80211_wds_rx_queued_mgmt(sdata, skb);
203 WARN(1, "frame for unexpected interface type");
205 --- a/net/mac80211/rx.c
206 +++ b/net/mac80211/rx.c
207 @@ -2284,6 +2284,7 @@ ieee80211_rx_h_action(struct ieee80211_r
208 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
209 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
210 sdata->vif.type != NL80211_IFTYPE_AP &&
211 + sdata->vif.type != NL80211_IFTYPE_WDS &&
212 sdata->vif.type != NL80211_IFTYPE_ADHOC)
215 @@ -2498,14 +2499,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
217 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
218 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
219 - sdata->vif.type != NL80211_IFTYPE_STATION)
220 + sdata->vif.type != NL80211_IFTYPE_STATION &&
221 + sdata->vif.type != NL80211_IFTYPE_WDS)
222 return RX_DROP_MONITOR;
225 case cpu_to_le16(IEEE80211_STYPE_AUTH):
226 case cpu_to_le16(IEEE80211_STYPE_BEACON):
227 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
228 - /* process for all: mesh, mlme, ibss */
229 + /* process for all: mesh, mlme, ibss, wds */
231 case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
232 case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
233 @@ -2839,10 +2841,16 @@ static int prepare_for_handlers(struct i
236 case NL80211_IFTYPE_WDS:
237 - if (bssid || !ieee80211_is_data(hdr->frame_control))
239 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
242 + if (ieee80211_is_data(hdr->frame_control) ||
243 + ieee80211_is_action(hdr->frame_control)) {
244 + if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
246 + } else if (!ieee80211_is_beacon(hdr->frame_control))
251 /* should never get here */
252 --- a/net/mac80211/sta_info.h
253 +++ b/net/mac80211/sta_info.h
255 * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
257 * @WLAN_STA_WME: Station is a QoS-STA.
258 - * @WLAN_STA_WDS: Station is one of our WDS peers.
259 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
260 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
261 * frame to this station is transmitted.
262 @@ -64,7 +63,6 @@ enum ieee80211_sta_info_flags {
264 WLAN_STA_SHORT_PREAMBLE,
267 WLAN_STA_CLEAR_PS_FILT,