OSDN Git Service

lib/vsprintf.c: remove %Z support
[uclinux-h8/linux.git] / drivers / net / wireless / broadcom / brcm80211 / brcmfmac / cfg80211.c
index 7ffc4ab..944b83c 100644 (file)
@@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[] = {
        .band                   = NL80211_BAND_2GHZ,            \
        .center_freq            = (_freq),                      \
        .hw_value               = (_channel),                   \
-       .flags                  = IEEE80211_CHAN_DISABLED,      \
        .max_antenna_gain       = 0,                            \
        .max_power              = 30,                           \
 }
@@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[] = {
        .band                   = NL80211_BAND_5GHZ,            \
        .center_freq            = 5000 + (5 * (_channel)),      \
        .hw_value               = (_channel),                   \
-       .flags                  = IEEE80211_CHAN_DISABLED,      \
        .max_antenna_gain       = 0,                            \
        .max_power              = 30,                           \
 }
@@ -328,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  * triples, returning a pointer to the substring whose first element
  * matches tag
  */
-const struct brcmf_tlv *
+static const struct brcmf_tlv *
 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
 {
        const struct brcmf_tlv *elt = buf;
@@ -3332,7 +3330,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
                goto out_err;
        }
 
-       data += sizeof(struct brcmf_pno_scanresults_le);
        netinfo_start = brcmf_get_netinfo_array(pfn_result);
 
        for (i = 0; i < result_count; i++) {
@@ -3480,8 +3477,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
                return -EINVAL;
        }
 
-       data += sizeof(struct brcmf_pno_scanresults_le);
-       netinfo = (struct brcmf_pno_net_info_le *)data;
+       netinfo = brcmf_get_netinfo_array(pfn_result);
        memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
        cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
        cfg->wowl.nd->n_channels = 1;
@@ -3971,7 +3967,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
                        pval |= AES_ENABLED;
                        break;
                default:
-                       brcmf_err("Ivalid unicast security info\n");
+                       brcmf_err("Invalid unicast security info\n");
                }
                offset++;
        }
@@ -4015,7 +4011,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
                        wpa_auth |= WPA2_AUTH_1X_SHA256;
                        break;
                default:
-                       brcmf_err("Ivalid key mgmt info\n");
+                       brcmf_err("Invalid key mgmt info\n");
                }
                offset++;
        }
@@ -4878,7 +4874,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                kfree(af_params);
        } else {
                brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
-               brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
+               brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
        }
 
 exit:
@@ -5071,6 +5067,29 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
        return ret;
 }
 
+static int
+brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
+                                 struct net_device *ndev,
+                                 struct cfg80211_connect_params *sme,
+                                 u32 changed)
+{
+       struct brcmf_if *ifp;
+       int err;
+
+       if (!(changed & UPDATE_ASSOC_IES))
+               return 0;
+
+       ifp = netdev_priv(ndev);
+       err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
+                                   sme->ie, sme->ie_len);
+       if (err)
+               brcmf_err("Set Assoc REQ IE Failed\n");
+       else
+               brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
+
+       return err;
+}
+
 #ifdef CONFIG_PM
 static int
 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
@@ -5138,6 +5157,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
        .crit_proto_start = brcmf_cfg80211_crit_proto_start,
        .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
        .tdls_oper = brcmf_cfg80211_tdls_oper,
+       .update_connect_params = brcmf_cfg80211_update_conn_params,
 };
 
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
@@ -5825,7 +5845,6 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
        u32 i, j;
        u32 total;
        u32 chaninfo;
-       u32 index;
 
        pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
 
@@ -5873,33 +5892,39 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
                    ch.bw == BRCMU_CHAN_BW_80)
                        continue;
 
-               channel = band->channels;
-               index = band->n_channels;
+               channel = NULL;
                for (j = 0; j < band->n_channels; j++) {
-                       if (channel[j].hw_value == ch.control_ch_num) {
-                               index = j;
+                       if (band->channels[j].hw_value == ch.control_ch_num) {
+                               channel = &band->channels[j];
                                break;
                        }
                }
-               channel[index].center_freq =
-                       ieee80211_channel_to_frequency(ch.control_ch_num,
-                                                      band->band);
-               channel[index].hw_value = ch.control_ch_num;
+               if (!channel) {
+                       /* It seems firmware supports some channel we never
+                        * considered. Something new in IEEE standard?
+                        */
+                       brcmf_err("Ignoring unexpected firmware channel %d\n",
+                                 ch.control_ch_num);
+                       continue;
+               }
+
+               if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
+                       continue;
 
                /* assuming the chanspecs order is HT20,
                 * HT40 upper, HT40 lower, and VHT80.
                 */
                if (ch.bw == BRCMU_CHAN_BW_80) {
-                       channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
+                       channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
                } else if (ch.bw == BRCMU_CHAN_BW_40) {
-                       brcmf_update_bw40_channel_flag(&channel[index], &ch);
+                       brcmf_update_bw40_channel_flag(channel, &ch);
                } else {
                        /* enable the channel and disable other bandwidths
                         * for now as mentioned order assure they are enabled
                         * for subsequent chanspecs.
                         */
-                       channel[index].flags = IEEE80211_CHAN_NO_HT40 |
-                                              IEEE80211_CHAN_NO_80MHZ;
+                       channel->flags = IEEE80211_CHAN_NO_HT40 |
+                                        IEEE80211_CHAN_NO_80MHZ;
                        ch.bw = BRCMU_CHAN_BW_20;
                        cfg->d11inf.encchspec(&ch);
                        chaninfo = ch.chspec;
@@ -5907,11 +5932,11 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
                                                       &chaninfo);
                        if (!err) {
                                if (chaninfo & WL_CHAN_RADAR)
-                                       channel[index].flags |=
+                                       channel->flags |=
                                                (IEEE80211_CHAN_RADAR |
                                                 IEEE80211_CHAN_NO_IR);
                                if (chaninfo & WL_CHAN_PASSIVE)
-                                       channel[index].flags |=
+                                       channel->flags |=
                                                IEEE80211_CHAN_NO_IR;
                        }
                }
@@ -6341,7 +6366,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
 }
 
 #ifdef CONFIG_PM
-static struct wiphy_wowlan_support brcmf_wowlan_support = {
+static const struct wiphy_wowlan_support brcmf_wowlan_support = {
        .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
        .n_patterns = BRCMF_WOWL_MAXPATTERNS,
        .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
@@ -6354,19 +6379,29 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
 {
 #ifdef CONFIG_PM
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+       struct wiphy_wowlan_support *wowl;
+
+       wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
+                      GFP_KERNEL);
+       if (!wowl) {
+               brcmf_err("only support basic wowlan features\n");
+               wiphy->wowlan = &brcmf_wowlan_support;
+               return;
+       }
 
        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
-                       brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
+                       wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
+                       wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
                        init_waitqueue_head(&cfg->wowl.nd_data_wait);
                }
        }
        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
-               brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
-               brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
+               wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
+               wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
        }
 
-       wiphy->wowlan = &brcmf_wowlan_support;
+       wiphy->wowlan = wowl;
 #endif
 }
 
@@ -6477,8 +6512,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
                        wiphy->bands[NL80211_BAND_5GHZ] = band;
                }
        }
-       err = brcmf_setup_wiphybands(wiphy);
-       return err;
+
+       wiphy_read_of_freq_limits(wiphy);
+
+       return 0;
 }
 
 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
@@ -6748,6 +6785,10 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
                kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
                kfree(wiphy->bands[NL80211_BAND_5GHZ]);
        }
+#if IS_ENABLED(CONFIG_PM)
+       if (wiphy->wowlan != &brcmf_wowlan_support)
+               kfree(wiphy->wowlan);
+#endif
        wiphy_free(wiphy);
 }
 
@@ -6843,6 +6884,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
                goto priv_out;
        }
 
+       err = brcmf_setup_wiphybands(wiphy);
+       if (err) {
+               brcmf_err("Setting wiphy bands failed (%d)\n", err);
+               goto wiphy_unreg_out;
+       }
+
        /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
         * setup 40MHz in 2GHz band and enable OBSS scanning.
         */