void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_chan_def chandef) { u8 config_bands = 0; bss_cfg->channel = ieee80211_frequency_to_channel( chandef.chan->center_freq); /* Set appropriate bands */ if (chandef.chan->band == IEEE80211_BAND_2GHZ) { bss_cfg->band_cfg = BAND_CONFIG_BG; config_bands = BAND_B | BAND_G; if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT) config_bands |= BAND_GN; } else { bss_cfg->band_cfg = BAND_CONFIG_A; config_bands = BAND_A; if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT) config_bands |= BAND_AN; if (chandef.width > NL80211_CHAN_WIDTH_40) config_bands |= BAND_AAC; } }
int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, struct ieee80211_channel *chan, unsigned int duration) { struct host_cmd_ds_remain_on_chan roc_cfg; u8 sc; memset(&roc_cfg, 0, sizeof(roc_cfg)); roc_cfg.action = cpu_to_le16(action); if (action == HostCmd_ACT_GEN_SET) { roc_cfg.band_cfg = chan->band; sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT); roc_cfg.band_cfg |= (sc << 2); roc_cfg.channel = ieee80211_frequency_to_channel(chan->center_freq); roc_cfg.duration = cpu_to_le32(duration); } if (mwifiex_send_cmd(priv, HostCmd_CMD_REMAIN_ON_CHAN, action, 0, &roc_cfg, true)) { dev_err(priv->adapter->dev, "failed to remain on channel\n"); return -1; } return roc_cfg.status; }
/** * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz * @channel: Any channel valid for the requested phymode * In addition to setting the staging RXON, priv->phymode is also set. * * NOTE: Does not commit to the hardware; it sets appropriate bit fields * in the staging RXON flag structure based on the phymode */ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) { enum ieee80211_band band = ch->band; u16 channel = ieee80211_frequency_to_channel(ch->center_freq); if (!iwl_get_channel_info(priv, band, channel)) { IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", channel, band); return -EINVAL; } if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && (priv->band == band)) return 0; priv->staging_rxon.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; else priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; priv->band = band; IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); return 0; }
/* ======================================================================== Routine Description: Set channel. Arguments: pWiphy - Wireless hardware description pChan - Channel information ChannelType - Channel type Return Value: 0 - success -x - fail Note: For iw utility: set channel, set freq enum nl80211_channel_type { NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40MINUS, NL80211_CHAN_HT40PLUS }; ======================================================================== */ static int CFG80211_OpsChannelSet( IN struct wiphy *pWiphy, IN struct net_device *pDev, IN struct ieee80211_channel *pChan, IN enum nl80211_channel_type ChannelType) { struct rtmp_adapter *pAd; CFG80211_CB *p80211CB; CMD_RTPRIV_IOCTL_80211_CHAN ChanInfo; u32 ChanId; struct net_device *dev = NULL; CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__)); MAC80211_PAD_GET(pAd, pWiphy); RTMP_DRIVER_NET_DEV_GET(pAd, &dev); /* get channel number */ ChanId = ieee80211_frequency_to_channel(pChan->center_freq); CFG80211DBG(RT_DEBUG_ERROR, ("80211> Channel = %d\n", ChanId)); CFG80211DBG(RT_DEBUG_ERROR, ("80211> ChannelType = %d\n", ChannelType)); /* init */ memset(&ChanInfo, 0, sizeof(ChanInfo)); ChanInfo.ChanId = ChanId; p80211CB = NULL; RTMP_DRIVER_80211_CB_GET(pAd, &p80211CB); if (p80211CB == NULL) { CFG80211DBG(RT_DEBUG_ERROR, ("80211> p80211CB == NULL!\n")); return 0; } if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_STATION) ChanInfo.IfType = RT_CMD_80211_IFTYPE_STATION; else if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_ADHOC) ChanInfo.IfType = RT_CMD_80211_IFTYPE_ADHOC; else if (p80211CB->pCfg80211_Wdev->iftype == NL80211_IFTYPE_MONITOR) ChanInfo.IfType = RT_CMD_80211_IFTYPE_MONITOR; if (ChannelType == NL80211_CHAN_NO_HT) ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_NOHT; else if (ChannelType == NL80211_CHAN_HT20) ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT20; else if (ChannelType == NL80211_CHAN_HT40MINUS) ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT40MINUS; else if (ChannelType == NL80211_CHAN_HT40PLUS) ChanInfo.ChanType = RT_CMD_80211_CHANTYPE_HT40PLUS; ChanInfo.MonFilterFlag = p80211CB->MonFilterFlag; /* set channel */ RTMP_DRIVER_80211_CHAN_SET(pAd, &ChanInfo); return 0; } /* End of CFG80211_OpsChannelSet */
/* * This function sets the RF channel. * * This function creates multiple IOCTL requests, populates them accordingly * and issues them to set the band/channel and frequency. */ static int mwifiex_set_rf_channel(struct mwifiex_private *priv, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { struct mwifiex_chan_freq_power cfp; struct mwifiex_ds_band_cfg band_cfg; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; if (chan) { memset(&band_cfg, 0, sizeof(band_cfg)); /* Set appropriate bands */ if (chan->band == IEEE80211_BAND_2GHZ) config_bands = BAND_B | BAND_G | BAND_GN; else config_bands = BAND_AN | BAND_A; if (priv->bss_mode == NL80211_IFTYPE_STATION || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) { band_cfg.config_bands = config_bands; } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { band_cfg.config_bands = config_bands; band_cfg.adhoc_start_band = config_bands; } band_cfg.sec_chan_offset = mwifiex_cfg80211_channel_type_to_mwifiex_channels (channel_type); if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) return -EFAULT; mwifiex_send_domain_info_cmd_fw(wiphy); } wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " "mode %d\n", config_bands, band_cfg.sec_chan_offset, priv->bss_mode); if (!chan) return 0; memset(&cfp, 0, sizeof(cfp)); cfp.freq = chan->center_freq; cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); if (mwifiex_bss_set_channel(priv, &cfp)) return -EFAULT; return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); }
static int r92su_ibss_build_ie(struct r92su *r92su, u8 **ie, u32 *ie_len_left, struct cfg80211_ibss_params *params) { struct ieee80211_supported_band *sband; unsigned int i, rates_len = 0; u8 supp_rates[16]; u8 ibss_params[2] = { }; u8 chan; sband = &r92su->band_2GHZ; chan = ieee80211_frequency_to_channel(params->chandef. chan->center_freq); rates_len = min_t(unsigned int, sband->n_bitrates, sizeof(supp_rates)); for (i = 0; i < rates_len; i++) { supp_rates[i] = sband->bitrates[i].bitrate / 5; if (params->basic_rates & BIT(i)) supp_rates[i] |= 0x80; } if (!r92su_add_ie(r92su, WLAN_EID_SSID, ie, ie_len_left, params->ssid, params->ssid_len)) return -EINVAL; if (!r92su_add_ie(r92su, WLAN_EID_SUPP_RATES, ie, ie_len_left, supp_rates, min(rates_len, 8u))) return -EINVAL; if (!r92su_add_ie(r92su, WLAN_EID_DS_PARAMS, ie, ie_len_left, &chan, sizeof(chan))) return -EINVAL; if (!r92su_add_ie(r92su, WLAN_EID_IBSS_PARAMS, ie, ie_len_left, ibss_params, sizeof(ibss_params))) return -EINVAL; if (rates_len > 8) { if (!r92su_add_ie(r92su, WLAN_EID_EXT_SUPP_RATES, ie, ie_len_left, &supp_rates[8], rates_len - 8)) return -EINVAL; } if (!r92su_ht_update(r92su, ie, ie_len_left)) return -EINVAL; if (!r92su_add_ies(r92su, ie, ie_len_left, params->ie, params->ie_len)) return -ENOSPC; return 0; }
void get_current_channel(int mon) { int freq, ch; /* get current channel & map to our channel array */ freq = wext_get_freq(mon, conf.ifname); if (freq == 0) return; ch = ieee80211_frequency_to_channel(freq); ch = find_channel_index(ch); if (ch >= 0) conf.current_channel = ch; DEBUG("***%d\n", conf.current_channel); }
static void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; u32 chan = sa2400_chan[channel - 1]; write_sa2400(dev, 7, txpw); sa2400_write_phy_antenna(dev, channel); write_sa2400(dev, 0, chan); write_sa2400(dev, 1, 0xbb50); write_sa2400(dev, 2, 0x80); write_sa2400(dev, 3, 0); }
static int agnx_config(struct ieee80211_hw *dev, u32 changed) { struct agnx_priv *priv = dev->priv; struct ieee80211_conf *conf = &dev->conf; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); AGNX_TRACE; spin_lock(&priv->lock); /* FIXME need priv lock? */ if (channel != priv->channel) { priv->channel = channel; agnx_set_channel(priv, priv->channel); } spin_unlock(&priv->lock); return 0; }
static void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; int channel = conf ? ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1; unsigned int chan_idx = channel - 1; u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; u32 chan = max2820_chan[chan_idx]; /* While philips SA2400 drive the PA bias from * sa2400, for MAXIM we do this directly from BB */ rtl8180_write_phy(dev, 3, txpw); max2820_write_phy_antenna(dev, channel); write_max2820(dev, 3, chan); }
static struct p54_channel_entry *p54_update_channel_param(struct p54_channel_list *list, u16 freq, u16 data) { int i; struct p54_channel_entry *entry = NULL; /* * usually all lists in the eeprom are mostly sorted. * so it's very likely that the entry we are looking for * is right at the end of the list */ for (i = list->entries; i >= 0; i--) { if (freq == list->channels[i].freq) { entry = &list->channels[i]; break; } } if ((i < 0) && (list->entries < list->max_entries)) { /* entry does not exist yet. Initialize a new one. */ int band = p54_get_band_from_freq(freq); /* * filter out frequencies which don't belong into * any supported band. */ if (band >= 0) { i = list->entries++; list->band_channel_num[band]++; entry = &list->channels[i]; entry->freq = freq; entry->band = band; entry->index = ieee80211_frequency_to_channel(freq); entry->max_power = 0; entry->data = 0; } } if (entry) entry->data |= data; return entry; }
/* This function appends 11h info to a buffer while joining an * infrastructure BSS */ static void mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer, struct mwifiex_bssdescriptor *bss_desc) { struct mwifiex_ie_types_header *ie_header; struct mwifiex_ie_types_pwr_capability *cap; struct mwifiex_ie_types_local_pwr_constraint *constraint; struct ieee80211_supported_band *sband; u8 radio_type; int i; if (!buffer || !(*buffer)) return; radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); sband = priv->wdev.wiphy->bands[radio_type]; cap = (struct mwifiex_ie_types_pwr_capability *)*buffer; cap->header.type = cpu_to_le16(WLAN_EID_PWR_CAPABILITY); cap->header.len = cpu_to_le16(2); cap->min_pwr = 0; cap->max_pwr = 0; *buffer += sizeof(*cap); constraint = (struct mwifiex_ie_types_local_pwr_constraint *)*buffer; constraint->header.type = cpu_to_le16(WLAN_EID_PWR_CONSTRAINT); constraint->header.len = cpu_to_le16(2); constraint->chan = bss_desc->channel; constraint->constraint = bss_desc->local_constraint; *buffer += sizeof(*constraint); ie_header = (struct mwifiex_ie_types_header *)*buffer; ie_header->type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); ie_header->len = cpu_to_le16(2 * sband->n_channels + 2); *buffer += sizeof(*ie_header); *(*buffer)++ = WLAN_EID_SUPPORTED_CHANNELS; *(*buffer)++ = 2 * sband->n_channels; for (i = 0; i < sband->n_channels; i++) { *(*buffer)++ = ieee80211_frequency_to_channel( sband->channels[i].center_freq); *(*buffer)++ = 1; /* one channel in the subband */ } }
static void grf5101_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; u32 chan = channel - 1; /* set TX power */ write_grf5101(dev, 0x15, 0x0); write_grf5101(dev, 0x06, txpw); write_grf5101(dev, 0x15, 0x10); write_grf5101(dev, 0x15, 0x0); /* set frequency */ write_grf5101(dev, 0x07, 0x0); write_grf5101(dev, 0x0B, chan); write_grf5101(dev, 0x07, 0x1000); grf5101_write_phy_antenna(dev, channel); }
static void p54_update_channel_param(struct p54_channel_list *list, u16 freq, u16 data) { int band, i; /* * usually all lists in the eeprom are mostly sorted. * so it's very likely that the entry we are looking for * is right at the end of the list */ for (i = list->entries; i >= 0; i--) { if (freq == list->channels[i].freq) { list->channels[i].data |= data; break; } } if ((i < 0) && (list->entries < list->max_entries)) { /* entry does not exist yet. Initialize a new one. */ band = p54_get_band_from_freq(freq); /* * filter out frequencies which don't belong into * any supported band. */ if (band < 0) return ; i = list->entries++; list->band_channel_num[band]++; list->channels[i].freq = freq; list->channels[i].data = data; list->channels[i].band = band; list->channels[i].index = ieee80211_frequency_to_channel(freq); /* TODO: parse output_limit and fill max_power */ } }
static int orinoco_set_monitor_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef) { struct orinoco_private *priv = wiphy_priv(wiphy); int err = 0; unsigned long flags; int channel; if (!chandef->chan) return -EINVAL; if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT) return -EINVAL; if (chandef->chan->band != IEEE80211_BAND_2GHZ) return -EINVAL; channel = ieee80211_frequency_to_channel(chandef->chan->center_freq); if ((channel < 1) || (channel > NUM_CHANNELS) || !(priv->channel_mask & (1 << (channel - 1)))) return -EINVAL; if (orinoco_lock(priv, &flags) != 0) return -EBUSY; priv->channel = channel; if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { /* Fast channel change - no commit if successful */ struct hermes *hw = &priv->hw; err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_SET_CHANNEL, channel, NULL); } orinoco_unlock(priv, &flags); return err; }
void mwifiex_uap_set_channel(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_chan_def chandef) { u8 config_bands = 0, old_bands = priv->adapter->config_bands; priv->bss_chandef = chandef; bss_cfg->channel = ieee80211_frequency_to_channel( chandef.chan->center_freq); /* Set appropriate bands */ if (chandef.chan->band == IEEE80211_BAND_2GHZ) { bss_cfg->band_cfg = BAND_CONFIG_BG; config_bands = BAND_B | BAND_G; if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT) config_bands |= BAND_GN; } else { bss_cfg->band_cfg = BAND_CONFIG_A; config_bands = BAND_A; if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT) config_bands |= BAND_AN; if (chandef.width > NL80211_CHAN_WIDTH_40) config_bands |= BAND_AAC; } priv->adapter->config_bands = config_bands; if (old_bands != config_bands) { mwifiex_send_domain_info_cmd_fw(priv->adapter->wiphy); mwifiex_dnld_txpwr_table(priv); } }
int prism2_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { wlandevice_t *wlandev = dev->ml_priv; struct ieee80211_channel *channel = sme->channel; struct p80211msg_lnxreq_autojoin msg_join; u32 did; int length = sme->ssid_len; int chan = -1; int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104); int result; int err = 0; /* Set the channel */ if (channel) { chan = ieee80211_frequency_to_channel(channel->center_freq); result = prism2_domibset_uint32(wlandev, DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, chan); if (result) goto exit; } /* Set the authorisation */ if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) msg_join.authtype.data = P80211ENUM_authalg_opensystem; else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep)) msg_join.authtype.data = P80211ENUM_authalg_sharedkey; else printk(KERN_WARNING "Unhandled authorisation type for connect (%d)\n", sme->auth_type); /* Set the encryption - we only support wep */ if (is_wep) { if (sme->key) { result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, sme->key_idx); if (result) goto exit; /* send key to driver */ switch (sme->key_idx) { case 0: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; break; case 1: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; break; case 2: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; break; case 3: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; break; default: err = -EINVAL; goto exit; } result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *) sme->key); if (result) goto exit; } /* Assume we should set privacy invoked and exclude unencrypted We could possibly use sme->privacy here, but the assumption seems reasonable anyway */ result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); if (result) goto exit; } else { /* Assume we should unset privacy invoked and exclude unencrypted */ result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); if (result) goto exit; } /* Now do the actual join. Note there is no way that I can see to request a specific bssid */ msg_join.msgcode = DIDmsg_lnxreq_autojoin; memcpy(msg_join.ssid.data.data, sme->ssid, length); msg_join.ssid.data.len = length; result = p80211req_dorequest(wlandev, (u8 *) &msg_join); exit: if (result) err = -EFAULT; return err; }
static int prism2_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { struct wlandevice *wlandev = dev->ml_priv; struct ieee80211_channel *channel = sme->channel; struct p80211msg_lnxreq_autojoin msg_join; u32 did; int length = sme->ssid_len; int chan = -1; int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104); int result; int err = 0; /* Set the channel */ if (channel) { chan = ieee80211_frequency_to_channel(channel->center_freq); result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL, chan); if (result) goto exit; } /* Set the authorization */ if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) msg_join.authtype.data = P80211ENUM_authalg_opensystem; else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep)) msg_join.authtype.data = P80211ENUM_authalg_sharedkey; else netdev_warn(dev, "Unhandled authorisation type for connect (%d)\n", sme->auth_type); /* Set the encryption - we only support wep */ if (is_wep) { if (sme->key) { if (sme->key_idx >= NUM_WEPKEYS) { err = -EINVAL; goto exit; } result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, sme->key_idx); if (result) goto exit; /* send key to driver */ did = didmib_dot11smt_wepdefaultkeystable_key( sme->key_idx + 1); result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *)sme->key); if (result) goto exit; } /* Assume we should set privacy invoked and exclude unencrypted * We could possible use sme->privacy here, but the assumption * seems reasonable anyways */ result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, P80211ENUM_truth_true); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, P80211ENUM_truth_true); if (result) goto exit; } else { /* Assume we should unset privacy invoked * and exclude unencrypted */ result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, P80211ENUM_truth_false); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, P80211ENUM_truth_false); if (result) goto exit; } /* Now do the actual join. Note there is no way that I can * see to request a specific bssid */ msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN; memcpy(msg_join.ssid.data.data, sme->ssid, length); msg_join.ssid.data.len = length; result = p80211req_dorequest(wlandev, (u8 *)&msg_join); exit: if (result) err = -EFAULT; return err; }
static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { struct iwl6000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; u8 switch_count; u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); struct ieee80211_vif *vif = priv->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), .flags = CMD_SYNC, .data = &cmd, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", priv->active_rxon.channel, ch); cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = priv->staging_rxon.flags; cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* * calculate the ucode channel switch time * adding TSF as one of the factor for when to switch */ if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { if (switch_count > ((priv->ucode_beacon_time - tsf_low) / beacon_interval)) { switch_count -= (priv->ucode_beacon_time - tsf_low) / beacon_interval; } else switch_count = 0; } if (switch_count <= 1) cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); else { switch_time_in_usec = vif->bss_conf.beacon_int * switch_count * TIME_UNIT; ucode_switch_time = iwl_usecs_to_beacons(priv, switch_time_in_usec, beacon_interval); cmd.switch_time = iwl_add_beacon_time(priv, priv->ucode_beacon_time, ucode_switch_time, beacon_interval); } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", cmd.switch_time); ch_info = iwl_get_channel_info(priv, priv->band, ch); if (ch_info) cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", priv->active_rxon.channel, ch); return -EFAULT; } priv->switch_rxon.channel = cmd.channel; priv->switch_rxon.switch_in_progress = true; return iwl_send_cmd_sync(priv, &hcmd); } static struct iwl_lib_ops iwl6000_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, .txq_agg_enable = iwlagn_txq_agg_enable, .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, .init_alive_start = iwlagn_init_alive_start, .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl6000_nic_config, .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, EEPROM_REG_BAND_2_CHANNELS, EEPROM_REG_BAND_3_CHANNELS, EEPROM_REG_BAND_4_CHANNELS, EEPROM_REG_BAND_5_CHANNELS, EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, },
static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { struct net_device *dev; struct prism2_wiphy_private *priv = wiphy_priv(wiphy); struct wlandevice *wlandev; struct p80211msg_dot11req_scan msg1; struct p80211msg_dot11req_scan_results msg2; struct cfg80211_bss *bss; struct cfg80211_scan_info info = {}; int result; int err = 0; int numbss = 0; int i = 0; u8 ie_buf[46]; int ie_len; if (!request) return -EINVAL; dev = request->wdev->netdev; wlandev = dev->ml_priv; if (priv->scan_request && priv->scan_request != request) return -EBUSY; if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { netdev_err(dev, "Can't scan in AP mode\n"); return -EOPNOTSUPP; } priv->scan_request = request; memset(&msg1, 0x00, sizeof(msg1)); msg1.msgcode = DIDMSG_DOT11REQ_SCAN; msg1.bsstype.data = P80211ENUM_bsstype_any; memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data)); msg1.bssid.data.len = 6; if (request->n_ssids > 0) { msg1.scantype.data = P80211ENUM_scantype_active; msg1.ssid.data.len = request->ssids->ssid_len; memcpy(msg1.ssid.data.data, request->ssids->ssid, request->ssids->ssid_len); } else { msg1.scantype.data = 0; } msg1.probedelay.data = 0; for (i = 0; (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels); i++) msg1.channellist.data.data[i] = ieee80211_frequency_to_channel( request->channels[i]->center_freq); msg1.channellist.data.len = request->n_channels; msg1.maxchanneltime.data = 250; msg1.minchanneltime.data = 200; result = p80211req_dorequest(wlandev, (u8 *)&msg1); if (result) { err = prism2_result2err(msg1.resultcode.data); goto exit; } /* Now retrieve scan results */ numbss = msg1.numbss.data; for (i = 0; i < numbss; i++) { int freq; memset(&msg2, 0, sizeof(msg2)); msg2.msgcode = DIDMSG_DOT11REQ_SCAN_RESULTS; msg2.bssindex.data = i; result = p80211req_dorequest(wlandev, (u8 *)&msg2); if ((result != 0) || (msg2.resultcode.data != P80211ENUM_resultcode_success)) { break; } ie_buf[0] = WLAN_EID_SSID; ie_buf[1] = msg2.ssid.data.len; ie_len = ie_buf[1] + 2; memcpy(&ie_buf[2], &msg2.ssid.data.data, msg2.ssid.data.len); freq = ieee80211_channel_to_frequency(msg2.dschannel.data, NL80211_BAND_2GHZ); bss = cfg80211_inform_bss(wiphy, ieee80211_get_channel(wiphy, freq), CFG80211_BSS_FTYPE_UNKNOWN, (const u8 *)&msg2.bssid.data.data, msg2.timestamp.data, msg2.capinfo.data, msg2.beaconperiod.data, ie_buf, ie_len, (msg2.signal.data - 65536) * 100, /* Conversion to signed type */ GFP_KERNEL ); if (!bss) { err = -ENOMEM; goto exit; } cfg80211_put_bss(wiphy, bss); } if (result) err = prism2_result2err(msg2.resultcode.data); exit: info.aborted = !!(err); cfg80211_scan_done(request, &info); priv->scan_request = NULL; return err; }
/* ======================================================================== Routine Description: Connect to the ESS with the specified parameters. When connected, call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call cfg80211_connect_result() with the status from the AP. Arguments: pWiphy - Wireless hardware description pNdev - Network device interface pSme - Return Value: 0 - success -x - fail Note: For iw utility: connect You must use "iw ra0 connect xxx", then "iw ra0 disconnect"; You can not use "iw ra0 connect xxx" twice without disconnect; Or you will suffer "command failed: Operation already in progress (-114)". You must support add_key and set_default_key function; Or kernel will crash without any error message in linux 2.6.32. ======================================================================== */ static int CFG80211_OpsConnect( IN struct wiphy *pWiphy, IN struct net_device *pNdev, IN struct cfg80211_connect_params *pSme) { VOID *pAd; CMD_RTPRIV_IOCTL_80211_CONNECT ConnInfo; struct ieee80211_channel *pChannel = pSme->channel; INT32 Pairwise = 0; INT32 Groupwise = 0; INT32 Keymgmt = 0; INT32 WpaVersion = NL80211_WPA_VERSION_2; INT32 Chan = -1, Idx; CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__)); /* init */ MAC80211_PAD_GET(pAd, pWiphy); if (pChannel != NULL) Chan = ieee80211_frequency_to_channel(pChannel->center_freq); Groupwise = pSme->crypto.cipher_group; for(Idx=0; Idx<pSme->crypto.n_ciphers_pairwise; Idx++) Pairwise |= pSme->crypto.ciphers_pairwise[Idx]; /* End of for */ for(Idx=0; Idx<pSme->crypto.n_akm_suites; Idx++) Keymgmt |= pSme->crypto.akm_suites[Idx]; /* End of for */ WpaVersion = pSme->crypto.wpa_versions; memset(&ConnInfo, 0, sizeof(ConnInfo)); if (WpaVersion & NL80211_WPA_VERSION_2) ConnInfo.WpaVer = 2; else if (WpaVersion & NL80211_WPA_VERSION_1) ConnInfo.WpaVer = 1; else ConnInfo.WpaVer = 0; if (Keymgmt & WLAN_AKM_SUITE_8021X) ConnInfo.FlgIs8021x = TRUE; else ConnInfo.FlgIs8021x = FALSE; if (pSme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ConnInfo.FlgIsAuthOpen = FALSE; else ConnInfo.FlgIsAuthOpen = TRUE; if (Pairwise & WLAN_CIPHER_SUITE_CCMP) ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; else if (Pairwise & WLAN_CIPHER_SUITE_TKIP) ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; else if ((Pairwise & WLAN_CIPHER_SUITE_WEP40) || (Pairwise & WLAN_CIPHER_SUITE_WEP104)) { ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_WEP; } else ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; if (Groupwise & WLAN_CIPHER_SUITE_CCMP) ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; else if (Groupwise & WLAN_CIPHER_SUITE_TKIP) ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; else ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; /* End of if */ ConnInfo.pKey = (UINT8 *)(pSme->key); ConnInfo.KeyLen = pSme->key_len; ConnInfo.pSsid = pSme->ssid; ConnInfo.SsidLen = pSme->ssid_len; CFG80211DBG(RT_DEBUG_ERROR, ("80211> SME %x\n", pSme->auth_type)); RTMP_DRIVER_80211_CONNECT(pAd, &ConnInfo); return 0; } /* End of CFG80211_OpsConnect */
static int print_iface_handler(struct nl_msg *msg, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; unsigned int *wiphy = arg; const char *indent = ""; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (wiphy && tb_msg[NL80211_ATTR_WIPHY]) { unsigned int thiswiphy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]); indent = "\t"; if (*wiphy != thiswiphy) printf("phy#%d\n", thiswiphy); *wiphy = thiswiphy; } if (tb_msg[NL80211_ATTR_IFNAME]) printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL80211_ATTR_IFNAME])); else printf("%sUnnamed/non-netdev interface\n", indent); if (tb_msg[NL80211_ATTR_IFINDEX]) printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX])); if (tb_msg[NL80211_ATTR_WDEV]) printf("%s\twdev 0x%llx\n", indent, (unsigned long long)nla_get_u64(tb_msg[NL80211_ATTR_WDEV])); if (tb_msg[NL80211_ATTR_MAC]) { char mac_addr[20]; mac_addr_n2a(mac_addr, nla_data(tb_msg[NL80211_ATTR_MAC])); printf("%s\taddr %s\n", indent, mac_addr); } if (tb_msg[NL80211_ATTR_SSID]) { printf("%s\tssid ", indent); print_ssid_escaped(nla_len(tb_msg[NL80211_ATTR_SSID]), nla_data(tb_msg[NL80211_ATTR_SSID])); printf("\n"); } if (tb_msg[NL80211_ATTR_IFTYPE]) printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]))); if (!wiphy && tb_msg[NL80211_ATTR_WIPHY]) printf("%s\twiphy %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_WIPHY])); if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) { uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]); printf("%s\tchannel %d (%d MHz)", indent, ieee80211_frequency_to_channel(freq), freq); if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) { printf(", width: %s", channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH]))); if (tb_msg[NL80211_ATTR_CENTER_FREQ1]) printf(", center1: %d MHz", nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1])); if (tb_msg[NL80211_ATTR_CENTER_FREQ2]) printf(", center2: %d MHz", nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2])); } else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { enum nl80211_channel_type channel_type; channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); printf(" %s", channel_type_name(channel_type)); } printf("\n"); } return NL_SKIP; }
static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) { struct wl1271 *wl = hw->priv; struct ieee80211_conf *conf = &hw->conf; int channel, ret = 0; channel = ieee80211_frequency_to_channel(conf->channel->center_freq); wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", channel, conf->flags & IEEE80211_CONF_PS ? "on" : "off", conf->power_level); mutex_lock(&wl->mutex); ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; if (channel != wl->channel) { u8 old_channel = wl->channel; wl->channel = channel; ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0); if (ret < 0) { wl->channel = old_channel; goto out_sleep; } } ret = wl1271_cmd_build_null_data(wl); if (ret < 0) goto out_sleep; if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { wl1271_info("psm enabled"); wl->psm_requested = true; ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); } else if (!(conf->flags & IEEE80211_CONF_PS) && wl->psm_requested) { wl1271_info("psm disabled"); wl->psm_requested = false; if (wl->psm) ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE); } if (conf->power_level != wl->power_level) { ret = wl1271_acx_tx_power(wl, conf->power_level); if (ret < 0) goto out; wl->power_level = conf->power_level; } out_sleep: wl1271_ps_elp_sleep(wl); out: mutex_unlock(&wl->mutex); return ret; }
/* ======================================================================== Routine Description: Connect to the ESS with the specified parameters. When connected, call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call cfg80211_connect_result() with the status from the AP. Arguments: pWiphy - Wireless hardware description pNdev - Network device interface pSme - Return Value: 0 - success -x - fail Note: For iw utility: connect You must use "iw ra0 connect xxx", then "iw ra0 disconnect"; You can not use "iw ra0 connect xxx" twice without disconnect; Or you will suffer "command failed: Operation already in progress (-114)". You must support add_key and set_default_key function; Or kernel will crash without any error message in linux 2.6.32. ======================================================================== */ static int CFG80211_OpsConnect( IN struct wiphy *pWiphy, IN struct net_device *pNdev, IN struct cfg80211_connect_params *pSme) { struct rtmp_adapter *pAd; CMD_RTPRIV_IOCTL_80211_CONNECT ConnInfo; struct ieee80211_channel *pChannel = pSme->channel; INT32 Pairwise = 0; INT32 Groupwise = 0; INT32 Keymgmt = 0; // INT32 WpaVersion = NL80211_WPA_VERSION_2; INT32 WpaVersion = 0; INT32 Chan = -1, Idx; CFG80211DBG(RT_DEBUG_ERROR, ("80211 [CONNECT TEST]> %s ==>\n", __FUNCTION__)); /* init */ MAC80211_PAD_GET(pAd, pWiphy); if (pChannel != NULL) Chan = ieee80211_frequency_to_channel(pChannel->center_freq); /*Groupwise = pSme->crypto.cipher_group; for(Idx=0; Idx<pSme->crypto.n_ciphers_pairwise; Idx++) Pairwise |= pSme->crypto.ciphers_pairwise[Idx];*/ /* End of for */ CFG80211DBG(RT_DEBUG_ERROR, ("Groupwise: %x\n", pSme->crypto.cipher_group)); Groupwise = pSme->crypto.cipher_group; //for(Idx=0; Idx<pSme->crypto.n_ciphers_pairwise; Idx++) Pairwise |= pSme->crypto.ciphers_pairwise[0]; CFG80211DBG(RT_DEBUG_ERROR, ("Pairwise %x\n", pSme->crypto.ciphers_pairwise[0])); for(Idx=0; Idx<pSme->crypto.n_akm_suites; Idx++) Keymgmt |= pSme->crypto.akm_suites[Idx]; /* End of for */ WpaVersion = pSme->crypto.wpa_versions; CFG80211DBG(RT_DEBUG_ERROR, ("Wpa_versions %x\n", WpaVersion)); memset(&ConnInfo, 0, sizeof(ConnInfo)); ConnInfo.WpaVer = 0; /* if (WpaVersion & NL80211_WPA_VERSION_2) ConnInfo.WpaVer = 2; else if (WpaVersion & NL80211_WPA_VERSION_1) ConnInfo.WpaVer = 1; else ConnInfo.WpaVer = 0; if (Keymgmt & WLAN_AKM_SUITE_8021X) ConnInfo.FlgIs8021x = true; else ConnInfo.FlgIs8021x = false; if (pSme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ConnInfo.FlgIsAuthOpen = false; else ConnInfo.FlgIsAuthOpen = true; if (Pairwise & WLAN_CIPHER_SUITE_CCMP) ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; else if (Pairwise & WLAN_CIPHER_SUITE_TKIP) ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; else if ((Pairwise & WLAN_CIPHER_SUITE_WEP40) || (Pairwise & WLAN_CIPHER_SUITE_WEP104)) { ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_WEP; } else ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; if (Groupwise & WLAN_CIPHER_SUITE_CCMP) ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; else if (Groupwise & WLAN_CIPHER_SUITE_TKIP) ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; else ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; */ if (WpaVersion & NL80211_WPA_VERSION_1) { ConnInfo.WpaVer = 1; } if (WpaVersion & NL80211_WPA_VERSION_2) { ConnInfo.WpaVer = 2; } CFG80211DBG(RT_DEBUG_ERROR, ("Keymgmt %x\n", Keymgmt)); if (Keymgmt == WLAN_AKM_SUITE_8021X) ConnInfo.FlgIs8021x = true; else ConnInfo.FlgIs8021x = false; CFG80211DBG(RT_DEBUG_ERROR, ("Auth_type %x\n", pSme->auth_type)); if (pSme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ConnInfo.AuthType = Ndis802_11AuthModeShared; else if (pSme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ConnInfo.AuthType = Ndis802_11AuthModeOpen; else ConnInfo.AuthType = Ndis802_11AuthModeAutoSwitch; if (Pairwise == WLAN_CIPHER_SUITE_CCMP) { CFG80211DBG(RT_DEBUG_ERROR, ("WLAN_CIPHER_SUITE_CCMP...\n")); ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; } else if (Pairwise == WLAN_CIPHER_SUITE_TKIP) { CFG80211DBG(RT_DEBUG_ERROR, ("WLAN_CIPHER_SUITE_TKIP...\n")); ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; } else if ((Pairwise == WLAN_CIPHER_SUITE_WEP40) || (Pairwise & WLAN_CIPHER_SUITE_WEP104)) { CFG80211DBG(RT_DEBUG_ERROR, ("WLAN_CIPHER_SUITE_WEP...\n")); ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_WEP; } else { CFG80211DBG(RT_DEBUG_ERROR, ("NONE...\n")); ConnInfo.PairwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; } if (Groupwise == WLAN_CIPHER_SUITE_CCMP) { ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_CCMP; } else if (Groupwise == WLAN_CIPHER_SUITE_TKIP) { ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_TKIP; } else { ConnInfo.GroupwiseEncrypType |= RT_CMD_80211_CONN_ENCRYPT_NONE; } CFG80211DBG(RT_DEBUG_ERROR, ("ConnInfo.KeyLen ===> %d\n", pSme->key_len)); CFG80211DBG(RT_DEBUG_ERROR, ("ConnInfo.KeyIdx ===> %d\n", pSme->key_idx)); /* ConnInfo.pKey = (u8 *)(pSme->key); ConnInfo.KeyLen = pSme->key_len; ConnInfo.pSsid = pSme->ssid; ConnInfo.SsidLen = pSme->ssid_len;*/ memcpy(ConnInfo.Key, pSme->key, pSme->key_len); ConnInfo.KeyLen = pSme->key_len; ConnInfo.pSsid = (char *) pSme->ssid; ConnInfo.SsidLen = pSme->ssid_len; ConnInfo.KeyIdx = pSme->key_idx; /* YF@20120328: Reset to default */ ConnInfo.bWpsConnection= false; /* YF@20120328: Use SIOCSIWGENIE to make out the WPA/WPS IEs in AssocReq. */ { if (pSme->ie_len > 0) { char *ie = (char *) pSme->ie; RTMP_DRIVER_80211_GEN_IE_SET(pAd, ie, pSme->ie_len); } else { RTMP_DRIVER_80211_GEN_IE_SET(pAd, NULL, 0); } } //CFG80211DBG(RT_DEBUG_ERROR, ("80211> SME %x\n", pSme->auth_type)); if ((pSme->ie_len > 6) /* EID(1) + LEN(1) + OUI(4) */ && (pSme->ie[0] == WLAN_EID_VENDOR_SPECIFIC && pSme->ie[1] >= 4 && pSme->ie[2] == 0x00 && pSme->ie[3] == 0x50 && pSme->ie[4] == 0xf2 && pSme->ie[5] == 0x04)) { ConnInfo.bWpsConnection= true; } /* %NULL if not specified (auto-select based on scan)*/ if (pSme->bssid != NULL) { CFG80211DBG(RT_DEBUG_ERROR, ("80211> Connect bssid %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pSme->bssid))); memcpy(ConnInfo.Bssid, pSme->bssid, ETH_ALEN); } RTMP_DRIVER_80211_CONNECT(pAd, &ConnInfo); return 0; } /* End of CFG80211_OpsConnect */
static int iwl_get_channels_for_scan(struct iwl_priv *priv, enum ieee80211_band band, u8 is_active, u8 n_probes, struct iwl_scan_channel *scan_ch) { const struct ieee80211_channel *channels = NULL; const struct ieee80211_supported_band *sband; const struct iwl_channel_info *ch_info; u16 passive_dwell = 0; u16 active_dwell = 0; int added, i; u16 channel; sband = iwl_get_hw_mode(priv, band); if (!sband) return 0; channels = sband->channels; active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); passive_dwell = iwl_get_passive_dwell_time(priv, band); if (passive_dwell <= active_dwell) passive_dwell = active_dwell + 1; for (i = 0, added = 0; i < sband->n_channels; i++) { if (channels[i].flags & IEEE80211_CHAN_DISABLED) continue; channel = ieee80211_frequency_to_channel(channels[i].center_freq); scan_ch->channel = cpu_to_le16(channel); ch_info = iwl_get_channel_info(priv, band, channel); if (!is_channel_valid(ch_info)) { IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", channel); continue; } if (!is_active || is_channel_passive(ch_info) || (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; else scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; if (n_probes) scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); scan_ch->active_dwell = cpu_to_le16(active_dwell); scan_ch->passive_dwell = cpu_to_le16(passive_dwell); /* Set txpower levels to defaults */ scan_ch->dsp_atten = 110; /* NOTE: if we were doing 6Mb OFDM for scans we'd use * power level: * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; */ if (band == IEEE80211_BAND_5GHZ) scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; else scan_ch->tx_gain = ((1 << 5) | (5 << 3)); IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n", channel, le32_to_cpu(scan_ch->type), (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? "ACTIVE" : "PASSIVE", (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? active_dwell : passive_dwell); scan_ch++; added++; } IWL_DEBUG_SCAN("total channels to scan %d \n", added); return added; }
int prism2_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { wlandevice_t *wlandev = dev->ml_priv; struct ieee80211_channel *channel = sme->channel; struct p80211msg_lnxreq_autojoin msg_join; u32 did; int length = sme->ssid_len; int chan = -1; int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104); int result; int err = 0; if (channel) { chan = ieee80211_frequency_to_channel(channel->center_freq); result = prism2_domibset_uint32(wlandev, DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, chan); if (result) goto exit; } if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) msg_join.authtype.data = P80211ENUM_authalg_opensystem; else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep)) msg_join.authtype.data = P80211ENUM_authalg_sharedkey; else printk(KERN_WARNING "Unhandled authorisation type for connect (%d)\n", sme->auth_type); if (is_wep) { if (sme->key) { result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, sme->key_idx); if (result) goto exit; switch (sme->key_idx) { case 0: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; break; case 1: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; break; case 2: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; break; case 3: did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; break; default: err = -EINVAL; goto exit; } result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *) sme->key); if (result) goto exit; } result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); if (result) goto exit; } else { result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); if (result) goto exit; } msg_join.msgcode = DIDmsg_lnxreq_autojoin; memcpy(msg_join.ssid.data.data, sme->ssid, length); msg_join.ssid.data.len = length; result = p80211req_dorequest(wlandev, (u8 *) &msg_join); exit: if (result) err = -EFAULT; return err; }
/* * This function sets the RF channel. * * This function creates multiple IOCTL requests, populates them accordingly * and issues them to set the band/channel and frequency. */ static int mwifiex_set_rf_channel(struct mwifiex_private *priv, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { struct mwifiex_chan_freq_power cfp; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; struct mwifiex_adapter *adapter = priv->adapter; if (chan) { /* Set appropriate bands */ if (chan->band == IEEE80211_BAND_2GHZ) { if (channel_type == NL80211_CHAN_NO_HT) if (priv->adapter->config_bands == BAND_B || priv->adapter->config_bands == BAND_G) config_bands = priv->adapter->config_bands; else config_bands = BAND_B | BAND_G; else config_bands = BAND_B | BAND_G | BAND_GN; } else { if (channel_type == NL80211_CHAN_NO_HT) config_bands = BAND_A; else config_bands = BAND_AN | BAND_A; } if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) { adapter->config_bands = config_bands; if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { adapter->adhoc_start_band = config_bands; if ((config_bands & BAND_GN) || (config_bands & BAND_AN)) adapter->adhoc_11n_enabled = true; else adapter->adhoc_11n_enabled = false; } } adapter->sec_chan_offset = mwifiex_cfg80211_channel_type_to_sec_chan_offset (channel_type); adapter->channel_type = channel_type; mwifiex_send_domain_info_cmd_fw(wiphy); } wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", config_bands, adapter->sec_chan_offset, priv->bss_mode); if (!chan) return 0; memset(&cfp, 0, sizeof(cfp)); cfp.freq = chan->center_freq; cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); if (mwifiex_bss_set_channel(priv, &cfp)) return -EFAULT; if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); else return mwifiex_uap_set_channel(priv, cfp.channel); }
int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, bool channel_type_valid, const u8 *buf, size_t len, u64 *cookie ) #endif //LINUX_VERSION_CODE { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); tANI_U16 extendedWait = 0; tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); tActionFrmType actionFrmType; bool noack = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) hdd_adapter_t *goAdapter; #endif #ifdef WLAN_FEATURE_P2P_DEBUG if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; if(actionFrmType > MAX_P2P_ACTION_FRAME_TYPE) { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA", actionFrmType); } else { hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA", p2p_action_frame_type[actionFrmType]); if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) { globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; hddLog(LOGE,"[P2P State]Inactive state to " "GO negotation progress state"); } else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) { globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; hddLog(LOGE,"[P2P State]GO nego progress to GO nego" " completed state"); } } } #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) noack = dont_wait_for_ack; #endif //If the wait is coming as 0 with off channel set //then set the wait to 200 ms if (offchan && !wait) wait = ACTION_FRAME_DEFAULT_WAIT; hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", __func__,pAdapter->device_mode); //Call sme API to send out a action frame. // OR can we send it directly through data path?? // After tx completion send tx status back. if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { if (type == SIR_MAC_MGMT_FRAME) { if (subType == SIR_MAC_MGMT_PROBE_RSP) { /* Drop Probe response recieved from supplicant, as for GO and SAP PE itself sends probe response */ goto err_rem_channel; } else if ((subType == SIR_MAC_MGMT_DISASSOC) || (subType == SIR_MAC_MGMT_DEAUTH)) { /* During EAP failure or P2P Group Remove supplicant * is sending del_station command to driver. From * del_station function, Driver will send deauth frame to * p2p client. No need to send disassoc frame from here. * so Drop the frame here and send tx indication back to * supplicant. */ tANI_U8 dstMac[ETH_ALEN] = {0}; memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN); hddLog(VOS_TRACE_LEVEL_INFO, "%s: Deauth/Disassoc received for STA:" "%02x:%02x:%02x:%02x:%02x:%02x", __func__, dstMac[0], dstMac[1], dstMac[2], dstMac[3], dstMac[4], dstMac[5]); goto err_rem_channel; } } } if( NULL != cfgState->buf ) return -EBUSY; hddLog( LOG1, "Action frame tx request"); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO ); //If GO adapter exists and operating on same frequency //then we will not request remain on channel if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq) == goAdapter->sessionCtx.ap.operatingChannel ) ) { goto send_frame; } #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) if( offchan && wait) { int status; // In case of P2P Client mode if we are already // on the same channel then send the frame directly if((cfgState->remain_on_chan_ctx != NULL) && (cfgState->current_freq == chan->center_freq) ) { hddLog(LOG1,"action frame: extending the wait time\n"); extendedWait = (tANI_U16)wait; goto send_frame; } INIT_COMPLETION(pAdapter->offchannel_tx_event); status = wlan_hdd_request_remain_on_channel(wiphy, dev, chan, channel_type, wait, cookie, OFF_CHANNEL_ACTION_TX); if(0 != status) { if( (-EBUSY == status) && (cfgState->current_freq == chan->center_freq) ) { goto send_frame; } goto err_rem_channel; } /* Wait for driver to be ready on the requested channel */ status = wait_for_completion_interruptible_timeout( &pAdapter->offchannel_tx_event, msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX)); if(!status) { hddLog( LOGE, "Not able to complete remain on channel request" " within timeout period"); goto err_rem_channel; } } else if ( offchan ) { /* Check before sending action frame whether we already remain on channel */ if(NULL == cfgState->remain_on_chan_ctx) { goto err_rem_channel; } } send_frame: #endif if(!noack) { cfgState->buf = vos_mem_malloc( len ); //buf; if( cfgState->buf == NULL ) return -ENOMEM; cfgState->len = len; vos_mem_copy( cfgState->buf, buf, len); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) if( cfgState->remain_on_chan_ctx ) { cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie; *cookie = cfgState->action_cookie; } else { #endif *cookie = (tANI_U32) cfgState->buf; cfgState->action_cookie = *cookie; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) } #endif } if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) ) { tANI_U8 sessionId = pAdapter->sessionId; if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; hddLog(LOG1, "Tx Action Frame %u \n", actionFrmType); if (actionFrmType == WLAN_HDD_PROV_DIS_REQ) { cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING; hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING \n", __func__); } else if (actionFrmType == WLAN_HDD_GO_NEG_REQ) { cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING; hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING \n", __func__); } } if (eHAL_STATUS_SUCCESS != sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, buf, len, extendedWait, noack)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_sendAction returned fail", __func__); goto err; } } else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) ) { if( VOS_STATUS_SUCCESS != WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, buf, len, 0 ) ) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: WLANSAP_SendAction returned fail", __func__); goto err; } } return 0; err: if(!noack) { hdd_sendActionCnf( pAdapter, FALSE ); } return 0; err_rem_channel: *cookie = (tANI_U32)cfgState; cfg80211_mgmt_tx_status( pAdapter->dev, *cookie, buf, len, FALSE, GFP_KERNEL ); return 0; }
int cfg80211_wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct iw_range *range = (struct iw_range *) extra; enum ieee80211_band band; int i, c = 0; if (!wdev) return -EOPNOTSUPP; data->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); range->we_version_compiled = WIRELESS_EXT; range->we_version_source = 21; range->retry_capa = IW_RETRY_LIMIT; range->retry_flags = IW_RETRY_LIMIT; range->min_retry = 0; range->max_retry = 255; range->min_rts = 0; range->max_rts = 2347; range->min_frag = 256; range->max_frag = 2346; range->max_encoding_tokens = 4; range->max_qual.updated = IW_QUAL_NOISE_INVALID; switch (wdev->wiphy->signal_type) { case CFG80211_SIGNAL_TYPE_NONE: break; case CFG80211_SIGNAL_TYPE_MBM: range->max_qual.level = -110; range->max_qual.qual = 70; range->avg_qual.qual = 35; range->max_qual.updated |= IW_QUAL_DBM; range->max_qual.updated |= IW_QUAL_QUAL_UPDATED; range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED; break; case CFG80211_SIGNAL_TYPE_UNSPEC: range->max_qual.level = 100; range->max_qual.qual = 100; range->avg_qual.qual = 50; range->max_qual.updated |= IW_QUAL_QUAL_UPDATED; range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED; break; } range->avg_qual.level = range->max_qual.level / 2; range->avg_qual.noise = range->max_qual.noise / 2; range->avg_qual.updated = range->max_qual.updated; for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) { switch (wdev->wiphy->cipher_suites[i]) { case WLAN_CIPHER_SUITE_TKIP: range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_WPA); break; case WLAN_CIPHER_SUITE_CCMP: range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP | IW_ENC_CAPA_WPA2); break; case WLAN_CIPHER_SUITE_WEP40: range->encoding_size[range->num_encoding_sizes++] = WLAN_KEY_LEN_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: range->encoding_size[range->num_encoding_sizes++] = WLAN_KEY_LEN_WEP104; break; } } for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { struct ieee80211_supported_band *sband; sband = wdev->wiphy->bands[band]; if (!sband) continue; for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) { struct ieee80211_channel *chan = &sband->channels[i]; if (!(chan->flags & IEEE80211_CHAN_DISABLED)) { range->freq[c].i = ieee80211_frequency_to_channel( chan->center_freq); range->freq[c].m = chan->center_freq; range->freq[c].e = 6; c++; } } } range->num_channels = c; range->num_frequency = c; IW_EVENT_CAPA_SET_KERNEL(range->event_capa); IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); if (wdev->wiphy->max_scan_ssids > 0) range->scan_capa |= IW_SCAN_CAPA_ESSID; return 0; }
int prism2_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct prism2_wiphy_private *priv = wiphy_priv(wiphy); wlandevice_t *wlandev = dev->ml_priv; struct p80211msg_dot11req_scan msg1; struct p80211msg_dot11req_scan_results msg2; int result; int err = 0; int numbss = 0; int i = 0; u8 ie_buf[46]; int ie_len; if (!request) return -EINVAL; if (priv->scan_request && priv->scan_request != request) return -EBUSY; if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { printk(KERN_ERR "Can't scan in AP mode\n"); return -EOPNOTSUPP; } priv->scan_request = request; memset(&msg1, 0x00, sizeof(struct p80211msg_dot11req_scan)); msg1.msgcode = DIDmsg_dot11req_scan; msg1.bsstype.data = P80211ENUM_bsstype_any; memset(&(msg1.bssid.data), 0xFF, sizeof(p80211item_pstr6_t)); msg1.bssid.data.len = 6; if (request->n_ssids > 0) { msg1.scantype.data = P80211ENUM_scantype_active; msg1.ssid.data.len = request->ssids->ssid_len; memcpy(msg1.ssid.data.data, request->ssids->ssid, request->ssids->ssid_len); } else { msg1.scantype.data = 0; } msg1.probedelay.data = 0; for (i = 0; (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels); i++) msg1.channellist.data.data[i] = ieee80211_frequency_to_channel(request->channels[i]->center_freq); msg1.channellist.data.len = request->n_channels; msg1.maxchanneltime.data = 250; msg1.minchanneltime.data = 200; result = p80211req_dorequest(wlandev, (u8 *) &msg1); if (result) { err = prism2_result2err(msg1.resultcode.data); goto exit; } /* Now retrieve scan results */ numbss = msg1.numbss.data; for (i = 0; i < numbss; i++) { memset(&msg2, 0, sizeof(msg2)); msg2.msgcode = DIDmsg_dot11req_scan_results; msg2.bssindex.data = i; result = p80211req_dorequest(wlandev, (u8 *) &msg2); if ((result != 0) || (msg2.resultcode.data != P80211ENUM_resultcode_success)) { break; } ie_buf[0] = WLAN_EID_SSID; ie_buf[1] = msg2.ssid.data.len; ie_len = ie_buf[1] + 2; memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len); cfg80211_inform_bss(wiphy, ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), (const u8 *) &(msg2.bssid.data.data), msg2.timestamp.data, msg2.capinfo.data, msg2.beaconperiod.data, ie_buf, ie_len, (msg2.signal.data - 65536) * 100, /* Conversion to signed type */ GFP_KERNEL ); } if (result) err = prism2_result2err(msg2.resultcode.data); exit: cfg80211_scan_done(request, err ? 1 : 0); priv->scan_request = NULL; return err; }