aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-09 11:20:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:38:16 -0400
commit9d38d85de0270e3927bffab94973a9c78d1dc800 (patch)
tree31bc0111445ce78e2c373954d3b0fbce7cbb63ba /net/mac80211
parentaa9746af8fa26d28d442a7415c701eb5dfeb7a2a (diff)
cfg80211/mac80211: allow action frame TX/RX in IBSS
When in IBSS mode, currently action frame TX and RX cannot be used. Allow using it to talk to any peer, or for public action frames. Also, while at it, restructure the code in mac80211 to make it easier to add this for other interface types in the future. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c52
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c38
-rw-r--r--net/mac80211/rx.c3
4 files changed, 50 insertions, 48 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 952845e7072a..59f597d0c6a0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1555,9 +1555,55 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
1555 bool channel_type_valid, 1555 bool channel_type_valid,
1556 const u8 *buf, size_t len, u64 *cookie) 1556 const u8 *buf, size_t len, u64 *cookie)
1557{ 1557{
1558 return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan, 1558 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1559 channel_type, channel_type_valid, 1559 struct ieee80211_local *local = sdata->local;
1560 buf, len, cookie); 1560 struct sk_buff *skb;
1561 struct sta_info *sta;
1562 const struct ieee80211_mgmt *mgmt = (void *)buf;
1563 u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
1564 IEEE80211_TX_CTL_REQ_TX_STATUS;
1565
1566 /* Check that we are on the requested channel for transmission */
1567 if (chan != local->tmp_channel &&
1568 chan != local->oper_channel)
1569 return -EBUSY;
1570 if (channel_type_valid &&
1571 (channel_type != local->tmp_channel_type &&
1572 channel_type != local->_oper_channel_type))
1573 return -EBUSY;
1574
1575 switch (sdata->vif.type) {
1576 case NL80211_IFTYPE_ADHOC:
1577 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1578 break;
1579 rcu_read_lock();
1580 sta = sta_info_get(sdata, mgmt->da);
1581 rcu_read_unlock();
1582 if (!sta)
1583 return -ENOLINK;
1584 break;
1585 case NL80211_IFTYPE_STATION:
1586 if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
1587 flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1588 break;
1589 default:
1590 return -EOPNOTSUPP;
1591 }
1592
1593 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
1594 if (!skb)
1595 return -ENOMEM;
1596 skb_reserve(skb, local->hw.extra_tx_headroom);
1597
1598 memcpy(skb_put(skb, len), buf, len);
1599
1600 IEEE80211_SKB_CB(skb)->flags = flags;
1601
1602 skb->dev = sdata->dev;
1603 ieee80211_tx_skb(sdata, skb);
1604
1605 *cookie = (unsigned long) skb;
1606 return 0;
1561} 1607}
1562 1608
1563struct cfg80211_ops mac80211_config_ops = { 1609struct cfg80211_ops mac80211_config_ops = {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4d3883e20fc1..5782a537f74a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -986,11 +986,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
986int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, 986int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
987 struct cfg80211_disassoc_request *req, 987 struct cfg80211_disassoc_request *req,
988 void *cookie); 988 void *cookie);
989int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
990 struct ieee80211_channel *chan,
991 enum nl80211_channel_type channel_type,
992 bool channel_type_valid,
993 const u8 *buf, size_t len, u64 *cookie);
994ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, 989ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
995 struct sk_buff *skb); 990 struct sk_buff *skb);
996void ieee80211_send_pspoll(struct ieee80211_local *local, 991void ieee80211_send_pspoll(struct ieee80211_local *local,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2ab4e86d9929..1373b3dde8b4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2353,44 +2353,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2353 return 0; 2353 return 0;
2354} 2354}
2355 2355
2356int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2357 struct ieee80211_channel *chan,
2358 enum nl80211_channel_type channel_type,
2359 bool channel_type_valid,
2360 const u8 *buf, size_t len, u64 *cookie)
2361{
2362 struct ieee80211_local *local = sdata->local;
2363 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2364 struct sk_buff *skb;
2365
2366 /* Check that we are on the requested channel for transmission */
2367 if (chan != local->tmp_channel &&
2368 chan != local->oper_channel)
2369 return -EBUSY;
2370 if (channel_type_valid &&
2371 (channel_type != local->tmp_channel_type &&
2372 channel_type != local->_oper_channel_type))
2373 return -EBUSY;
2374
2375 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
2376 if (!skb)
2377 return -ENOMEM;
2378 skb_reserve(skb, local->hw.extra_tx_headroom);
2379
2380 memcpy(skb_put(skb, len), buf, len);
2381
2382 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
2383 IEEE80211_SKB_CB(skb)->flags |=
2384 IEEE80211_TX_INTFL_DONT_ENCRYPT;
2385 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
2386 IEEE80211_TX_CTL_REQ_TX_STATUS;
2387 skb->dev = sdata->dev;
2388 ieee80211_tx_skb(sdata, skb);
2389
2390 *cookie = (unsigned long) skb;
2391 return 0;
2392}
2393
2394void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, 2356void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2395 enum nl80211_cqm_rssi_threshold_event rssi_event, 2357 enum nl80211_cqm_rssi_threshold_event rssi_event,
2396 gfp_t gfp) 2358 gfp_t gfp)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6e7d6d48fe1e..3adcda502b7d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2045,8 +2045,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2045 */ 2045 */
2046 status = IEEE80211_SKB_RXCB(rx->skb); 2046 status = IEEE80211_SKB_RXCB(rx->skb);
2047 2047
2048 if (sdata->vif.type == NL80211_IFTYPE_STATION && 2048 if (cfg80211_rx_action(rx->sdata->dev, status->freq,
2049 cfg80211_rx_action(rx->sdata->dev, status->freq,
2050 rx->skb->data, rx->skb->len, 2049 rx->skb->data, rx->skb->len,
2051 GFP_ATOMIC)) 2050 GFP_ATOMIC))
2052 goto handled; 2051 goto handled;