aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211_iface.c')
-rw-r--r--net/mac80211/ieee80211_iface.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 2ba24ef319da..369ee4f52a29 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee80211_local *local)
127 if (ret) 127 if (ret)
128 goto fail; 128 goto fail;
129 129
130 /*
131 * Called even when register_netdevice fails, it would
132 * oops if assigned before initialising the rest.
133 */
134 ndev->uninit = ieee80211_if_reinit;
135
130 ieee80211_debugfs_add_netdev(nsdata); 136 ieee80211_debugfs_add_netdev(nsdata);
131 137
132 if (local->open_count > 0) 138 if (local->open_count > 0)
@@ -155,12 +161,27 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
155 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 161 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
156 int oldtype = sdata->type; 162 int oldtype = sdata->type;
157 163
158 dev->hard_start_xmit = ieee80211_subif_start_xmit; 164 /*
159 165 * We need to call this function on the master interface
166 * which already has a hard_start_xmit routine assigned
167 * which must not be changed.
168 */
169 if (!dev->hard_start_xmit)
170 dev->hard_start_xmit = ieee80211_subif_start_xmit;
171
172 /*
173 * Called even when register_netdevice fails, it would
174 * oops if assigned before initialising the rest.
175 */
176 dev->uninit = ieee80211_if_reinit;
177
178 /* most have no BSS pointer */
179 sdata->bss = NULL;
160 sdata->type = type; 180 sdata->type = type;
181
161 switch (type) { 182 switch (type) {
162 case IEEE80211_IF_TYPE_WDS: 183 case IEEE80211_IF_TYPE_WDS:
163 sdata->bss = NULL; 184 /* nothing special */
164 break; 185 break;
165 case IEEE80211_IF_TYPE_VLAN: 186 case IEEE80211_IF_TYPE_VLAN:
166 sdata->u.vlan.ap = NULL; 187 sdata->u.vlan.ap = NULL;
@@ -213,6 +234,7 @@ void ieee80211_if_reinit(struct net_device *dev)
213 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 234 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
214 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 235 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
215 struct sta_info *sta; 236 struct sta_info *sta;
237 struct sk_buff *skb;
216 238
217 ASSERT_RTNL(); 239 ASSERT_RTNL();
218 240
@@ -246,12 +268,9 @@ void ieee80211_if_reinit(struct net_device *dev)
246 kfree(sdata->u.ap.beacon_tail); 268 kfree(sdata->u.ap.beacon_tail);
247 kfree(sdata->u.ap.generic_elem); 269 kfree(sdata->u.ap.generic_elem);
248 270
249 if (dev != local->mdev) { 271 while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
250 struct sk_buff *skb; 272 local->total_ps_buffered--;
251 while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { 273 dev_kfree_skb(skb);
252 local->total_ps_buffered--;
253 dev_kfree_skb(skb);
254 }
255 } 274 }
256 275
257 break; 276 break;