aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
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/cfg.c
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/cfg.c')
-rw-r--r--net/mac80211/cfg.c52
1 files changed, 49 insertions, 3 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 = {