diff options
Diffstat (limited to 'net/mac80211/ieee80211_iface.c')
-rw-r--r-- | net/mac80211/ieee80211_iface.c | 37 |
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; |