aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2015-01-28 05:12:03 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-01-29 03:20:15 -0500
commitcf0523350c6f12bdffb06c7000326edb296ec450 (patch)
tree49ca6819ec53fa2a68b3dc21faf4cb5e146c2dd7 /drivers/net/wireless/mwifiex
parent1247cc1f43905441821faa56d9a815e852afe235 (diff)
mwifiex: manage virtual interface limits efficiently
Currently interface limits are checked by seeing if bss_mode for particular priv is set. If bss_mode is not set, interface creation is allowed. This patch adds framework to initializes maximum virtual interfaces supported during load time and check current number of interfaces created agains allowed interface limit during new virtual interface creation. Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Cathy Luo <cluo@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c80
-rw-r--r--drivers/net/wireless/mwifiex/decl.h10
-rw-r--r--drivers/net/wireless/mwifiex/init.c3
-rw-r--r--drivers/net/wireless/mwifiex/main.h21
4 files changed, 102 insertions, 12 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 85f5019306b5..a0221b5eff93 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2185,13 +2185,20 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2185 case NL80211_IFTYPE_UNSPECIFIED: 2185 case NL80211_IFTYPE_UNSPECIFIED:
2186 case NL80211_IFTYPE_STATION: 2186 case NL80211_IFTYPE_STATION:
2187 case NL80211_IFTYPE_ADHOC: 2187 case NL80211_IFTYPE_ADHOC:
2188 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; 2188 if (adapter->curr_iface_comb.sta_intf ==
2189 if (priv->bss_mode) { 2189 adapter->iface_limit.sta_intf) {
2190 wiphy_err(wiphy, 2190 wiphy_err(wiphy,
2191 "cannot create multiple sta/adhoc ifaces\n"); 2191 "cannot create multiple sta/adhoc ifaces\n");
2192 return ERR_PTR(-EINVAL); 2192 return ERR_PTR(-EINVAL);
2193 } 2193 }
2194 2194
2195 priv = mwifiex_get_unused_priv(adapter);
2196 if (!priv) {
2197 wiphy_err(wiphy,
2198 "could not get free private struct\n");
2199 return ERR_PTR(-EFAULT);
2200 }
2201
2195 priv->wdev.wiphy = wiphy; 2202 priv->wdev.wiphy = wiphy;
2196 priv->wdev.iftype = NL80211_IFTYPE_STATION; 2203 priv->wdev.iftype = NL80211_IFTYPE_STATION;
2197 2204
@@ -2208,13 +2215,20 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2208 2215
2209 break; 2216 break;
2210 case NL80211_IFTYPE_AP: 2217 case NL80211_IFTYPE_AP:
2211 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; 2218 if (adapter->curr_iface_comb.uap_intf ==
2212 2219 adapter->iface_limit.uap_intf) {
2213 if (priv->bss_mode) { 2220 wiphy_err(wiphy,
2214 wiphy_err(wiphy, "Can't create multiple AP interfaces"); 2221 "cannot create multiple AP ifaces\n");
2215 return ERR_PTR(-EINVAL); 2222 return ERR_PTR(-EINVAL);
2216 } 2223 }
2217 2224
2225 priv = mwifiex_get_unused_priv(adapter);
2226 if (!priv) {
2227 wiphy_err(wiphy,
2228 "could not get free private struct\n");
2229 return ERR_PTR(-EFAULT);
2230 }
2231
2218 priv->wdev.wiphy = wiphy; 2232 priv->wdev.wiphy = wiphy;
2219 priv->wdev.iftype = NL80211_IFTYPE_AP; 2233 priv->wdev.iftype = NL80211_IFTYPE_AP;
2220 2234
@@ -2228,15 +2242,21 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2228 2242
2229 break; 2243 break;
2230 case NL80211_IFTYPE_P2P_CLIENT: 2244 case NL80211_IFTYPE_P2P_CLIENT:
2231 priv = adapter->priv[MWIFIEX_BSS_TYPE_P2P]; 2245 if (adapter->curr_iface_comb.p2p_intf ==
2232 2246 adapter->iface_limit.p2p_intf) {
2233 if (priv->bss_mode) { 2247 wiphy_err(wiphy,
2234 wiphy_err(wiphy, "Can't create multiple P2P ifaces"); 2248 "cannot create multiple P2P ifaces\n");
2235 return ERR_PTR(-EINVAL); 2249 return ERR_PTR(-EINVAL);
2236 } 2250 }
2237 2251
2238 priv->wdev.wiphy = wiphy; 2252 priv = mwifiex_get_unused_priv(adapter);
2253 if (!priv) {
2254 wiphy_err(wiphy,
2255 "could not get free private struct\n");
2256 return ERR_PTR(-EFAULT);
2257 }
2239 2258
2259 priv->wdev.wiphy = wiphy;
2240 /* At start-up, wpa_supplicant tries to change the interface 2260 /* At start-up, wpa_supplicant tries to change the interface
2241 * to NL80211_IFTYPE_STATION if it is not managed mode. 2261 * to NL80211_IFTYPE_STATION if it is not managed mode.
2242 */ 2262 */
@@ -2329,6 +2349,23 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2329 mwifiex_dev_debugfs_init(priv); 2349 mwifiex_dev_debugfs_init(priv);
2330#endif 2350#endif
2331 2351
2352 switch (type) {
2353 case NL80211_IFTYPE_UNSPECIFIED:
2354 case NL80211_IFTYPE_STATION:
2355 case NL80211_IFTYPE_ADHOC:
2356 adapter->curr_iface_comb.sta_intf++;
2357 break;
2358 case NL80211_IFTYPE_AP:
2359 adapter->curr_iface_comb.uap_intf++;
2360 break;
2361 case NL80211_IFTYPE_P2P_CLIENT:
2362 adapter->curr_iface_comb.p2p_intf++;
2363 break;
2364 default:
2365 wiphy_err(wiphy, "type not supported\n");
2366 return ERR_PTR(-EINVAL);
2367 }
2368
2332 return &priv->wdev; 2369 return &priv->wdev;
2333} 2370}
2334EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); 2371EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
@@ -2339,12 +2376,13 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2339int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) 2376int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2340{ 2377{
2341 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 2378 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
2379 struct mwifiex_adapter *adapter = priv->adapter;
2342 2380
2343#ifdef CONFIG_DEBUG_FS 2381#ifdef CONFIG_DEBUG_FS
2344 mwifiex_dev_debugfs_remove(priv); 2382 mwifiex_dev_debugfs_remove(priv);
2345#endif 2383#endif
2346 2384
2347 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); 2385 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
2348 2386
2349 if (netif_carrier_ok(priv->netdev)) 2387 if (netif_carrier_ok(priv->netdev))
2350 netif_carrier_off(priv->netdev); 2388 netif_carrier_off(priv->netdev);
@@ -2359,6 +2397,24 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2359 2397
2360 priv->media_connected = false; 2398 priv->media_connected = false;
2361 2399
2400 switch (priv->bss_mode) {
2401 case NL80211_IFTYPE_UNSPECIFIED:
2402 case NL80211_IFTYPE_STATION:
2403 case NL80211_IFTYPE_ADHOC:
2404 adapter->curr_iface_comb.sta_intf++;
2405 break;
2406 case NL80211_IFTYPE_AP:
2407 adapter->curr_iface_comb.uap_intf++;
2408 break;
2409 case NL80211_IFTYPE_P2P_CLIENT:
2410 case NL80211_IFTYPE_P2P_GO:
2411 adapter->curr_iface_comb.p2p_intf++;
2412 break;
2413 default:
2414 dev_err(adapter->dev, "del_virtual_intf: type not supported\n");
2415 break;
2416 }
2417
2362 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2418 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2363 2419
2364 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA || 2420 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 7aa988e1dc7a..4481ac40c3eb 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -104,6 +104,10 @@
104/* Rate index for OFDM 0 */ 104/* Rate index for OFDM 0 */
105#define MWIFIEX_RATE_INDEX_OFDM0 4 105#define MWIFIEX_RATE_INDEX_OFDM0 4
106 106
107#define MWIFIEX_MAX_STA_NUM 1
108#define MWIFIEX_MAX_UAP_NUM 1
109#define MWIFIEX_MAX_P2P_NUM 1
110
107enum mwifiex_bss_type { 111enum mwifiex_bss_type {
108 MWIFIEX_BSS_TYPE_STA = 0, 112 MWIFIEX_BSS_TYPE_STA = 0,
109 MWIFIEX_BSS_TYPE_UAP = 1, 113 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -232,4 +236,10 @@ struct mwifiex_histogram_data {
232 atomic_t num_samples; 236 atomic_t num_samples;
233}; 237};
234 238
239struct mwifiex_iface_comb {
240 u8 sta_intf;
241 u8 uap_intf;
242 u8 p2p_intf;
243};
244
235#endif /* !_MWIFIEX_DECL_H_ */ 245#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2975b5154c39..1d1c3c8e516e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -298,6 +298,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
298 adapter->key_api_major_ver = 0; 298 adapter->key_api_major_ver = 0;
299 adapter->key_api_minor_ver = 0; 299 adapter->key_api_minor_ver = 0;
300 memset(adapter->perm_addr, 0xff, ETH_ALEN); 300 memset(adapter->perm_addr, 0xff, ETH_ALEN);
301 adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM;
302 adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM;
303 adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM;
301 304
302 setup_timer(&adapter->wakeup_timer, wakeup_timer_fn, 305 setup_timer(&adapter->wakeup_timer, wakeup_timer_fn,
303 (unsigned long)adapter); 306 (unsigned long)adapter);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 9686bd8603c8..78304a714512 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -730,6 +730,8 @@ struct mwifiex_if_ops {
730 730
731struct mwifiex_adapter { 731struct mwifiex_adapter {
732 u8 iface_type; 732 u8 iface_type;
733 struct mwifiex_iface_comb iface_limit;
734 struct mwifiex_iface_comb curr_iface_comb;
733 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; 735 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
734 u8 priv_num; 736 u8 priv_num;
735 const struct firmware *firmware; 737 const struct firmware *firmware;
@@ -1150,6 +1152,25 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
1150} 1152}
1151 1153
1152/* 1154/*
1155 * This function returns the first available unused private structure pointer.
1156 */
1157static inline struct mwifiex_private *
1158mwifiex_get_unused_priv(struct mwifiex_adapter *adapter)
1159{
1160 int i;
1161
1162 for (i = 0; i < adapter->priv_num; i++) {
1163 if (adapter->priv[i]) {
1164 if (adapter->priv[i]->bss_mode ==
1165 NL80211_IFTYPE_UNSPECIFIED)
1166 break;
1167 }
1168 }
1169
1170 return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
1171}
1172
1173/*
1153 * This function returns the driver private structure of a network device. 1174 * This function returns the driver private structure of a network device.
1154 */ 1175 */
1155static inline struct mwifiex_private * 1176static inline struct mwifiex_private *