Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / mac80211 / cfg.c
index a58c0b649ba137b09214c031bf3508b5fe2974eb..03fe6d1cff4214b0d9dde329a831ecb172ba3e42 100644 (file)
@@ -102,6 +102,18 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
        return 0;
 }
 
+static int ieee80211_start_p2p_device(struct wiphy *wiphy,
+                                     struct wireless_dev *wdev)
+{
+       return ieee80211_do_open(wdev, true);
+}
+
+static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
+                                     struct wireless_dev *wdev)
+{
+       ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
+}
+
 static int ieee80211_set_noack_map(struct wiphy *wiphy,
                                  struct net_device *dev,
                                  u16 noack_map)
@@ -330,7 +342,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
        if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
                struct ieee80211_supported_band *sband;
                sband = sta->local->hw.wiphy->bands[
-                               sta->local->hw.conf.channel->band];
+                               sta->local->oper_channel->band];
                rate->legacy = sband->bitrates[idx].bitrate;
        } else
                rate->mcs = idx;
@@ -725,25 +737,23 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
 static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
                                    const u8 *resp, size_t resp_len)
 {
-       struct sk_buff *new, *old;
+       struct probe_resp *new, *old;
 
        if (!resp || !resp_len)
                return 1;
 
        old = rtnl_dereference(sdata->u.ap.probe_resp);
 
-       new = dev_alloc_skb(resp_len);
+       new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
        if (!new)
                return -ENOMEM;
 
-       memcpy(skb_put(new, resp_len), resp, resp_len);
+       new->len = resp_len;
+       memcpy(new->data, resp, resp_len);
 
        rcu_assign_pointer(sdata->u.ap.probe_resp, new);
-       if (old) {
-               /* TODO: use call_rcu() */
-               synchronize_rcu();
-               dev_kfree_skb(old);
-       }
+       if (old)
+               kfree_rcu(old, rcu_head);
 
        return 0;
 }
@@ -950,7 +960,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
        /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
         * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
 
-       memset(msg->da, 0xff, ETH_ALEN);
+       eth_broadcast_addr(msg->da);
        memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
        msg->len = htons(6);
        msg->dsap = 0;
@@ -1285,9 +1295,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
        mutex_unlock(&local->sta_mtx);
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-           params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))
+           params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
                ieee80211_recalc_ps(local, -1);
-
+               ieee80211_recalc_ps_vif(sdata);
+       }
        return 0;
 }
 
@@ -1660,7 +1671,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
        }
 
        if (!sdata->vif.bss_conf.use_short_slot &&
-           sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
+           sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) {
                sdata->vif.bss_conf.use_short_slot = true;
                changed |= BSS_CHANGED_ERP_SLOT;
        }
@@ -1774,6 +1785,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
        case NL80211_IFTYPE_ADHOC:
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_P2P_DEVICE:
                break;
        case NL80211_IFTYPE_P2P_GO:
                if (sdata->local->ops->hw_scan)
@@ -1926,7 +1938,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
                                  enum nl80211_tx_power_setting type, int mbm)
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
-       struct ieee80211_channel *chan = local->hw.conf.channel;
+       struct ieee80211_channel *chan = local->oper_channel;
        u32 changes = 0;
 
        switch (type) {
@@ -2078,6 +2090,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
 
        ieee80211_recalc_ps(local, -1);
+       ieee80211_recalc_ps_vif(sdata);
 
        return 0;
 }
@@ -2460,6 +2473,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                if (!sdata->u.mgd.associated)
                        need_offchan = true;
                break;
+       case NL80211_IFTYPE_P2P_DEVICE:
+               need_offchan = true;
+               break;
        default:
                return -EOPNOTSUPP;
        }
@@ -2652,6 +2668,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
                               u16 status_code, struct sk_buff *skb)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_tdls_data *tf;
 
        tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
@@ -2671,8 +2688,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
                tf->u.setup_req.capability =
                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-               ieee80211_add_srates_ie(sdata, skb, false);
-               ieee80211_add_ext_srates_ie(sdata, skb, false);
+               ieee80211_add_srates_ie(sdata, skb, false,
+                                       local->oper_channel->band);
+               ieee80211_add_ext_srates_ie(sdata, skb, false,
+                                           local->oper_channel->band);
                ieee80211_tdls_add_ext_capab(skb);
                break;
        case WLAN_TDLS_SETUP_RESPONSE:
@@ -2685,8 +2704,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
                tf->u.setup_resp.capability =
                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-               ieee80211_add_srates_ie(sdata, skb, false);
-               ieee80211_add_ext_srates_ie(sdata, skb, false);
+               ieee80211_add_srates_ie(sdata, skb, false,
+                                       local->oper_channel->band);
+               ieee80211_add_ext_srates_ie(sdata, skb, false,
+                                           local->oper_channel->band);
                ieee80211_tdls_add_ext_capab(skb);
                break;
        case WLAN_TDLS_SETUP_CONFIRM:
@@ -2724,6 +2745,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
                           u16 status_code, struct sk_buff *skb)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_mgmt *mgmt;
 
        mgmt = (void *)skb_put(skb, 24);
@@ -2746,8 +2768,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
                mgmt->u.action.u.tdls_discover_resp.capability =
                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-               ieee80211_add_srates_ie(sdata, skb, false);
-               ieee80211_add_ext_srates_ie(sdata, skb, false);
+               ieee80211_add_srates_ie(sdata, skb, false,
+                                       local->oper_channel->band);
+               ieee80211_add_ext_srates_ie(sdata, skb, false,
+                                           local->oper_channel->band);
                ieee80211_tdls_add_ext_capab(skb);
                break;
        default:
@@ -3004,6 +3028,8 @@ struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
        .change_virtual_intf = ieee80211_change_iface,
+       .start_p2p_device = ieee80211_start_p2p_device,
+       .stop_p2p_device = ieee80211_stop_p2p_device,
        .add_key = ieee80211_add_key,
        .del_key = ieee80211_del_key,
        .get_key = ieee80211_get_key,