diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
24 files changed, 627 insertions, 1246 deletions
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 5e10ce0d351..4bc46a60ae2 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -79,7 +79,7 @@ static u8 *lbs_code_2_region(u8 code) * @param nrchan number of channels * @return the nrchan-th chan number */ -static u8 lbs_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 *chan) +static u8 lbs_get_chan_11d(u8 firstchan, u8 nrchan, u8 *chan) /*find the nrchan-th chan after the firstchan*/ { u8 i; @@ -134,7 +134,7 @@ static u8 lbs_channel_known_11d(u8 chan, return 0; } -u32 lbs_chan_2_freq(u8 chan, u8 band) +u32 lbs_chan_2_freq(u8 chan) { struct chan_freq_power *cf; u16 i; @@ -264,7 +264,7 @@ static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_ch * @param chan chan * @return TRUE;FALSE */ -static u8 lbs_region_chan_supported_11d(u8 region, u8 band, u8 chan) +static u8 lbs_region_chan_supported_11d(u8 region, u8 chan) { struct chan_freq_power *cfp; int cfp_no; @@ -273,7 +273,7 @@ static u8 lbs_region_chan_supported_11d(u8 region, u8 band, u8 chan) lbs_deb_enter(LBS_DEB_11D); - cfp = lbs_get_region_cfp_table(region, band, &cfp_no); + cfp = lbs_get_region_cfp_table(region, &cfp_no); if (cfp == NULL) return 0; @@ -367,7 +367,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) { /*step4: channel is supported? */ - if (!lbs_get_chan_11d(band, firstchan, i, &curchan)) { + if (!lbs_get_chan_11d(firstchan, i, &curchan)) { /* Chan is not found in UN table */ lbs_deb_11d("chan is not supported: %d \n", i); break; @@ -375,8 +375,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* lastchan = curchan; - if (lbs_region_chan_supported_11d - (region, band, curchan)) { + if (lbs_region_chan_supported_11d(region, curchan)) { /*step5: Check if curchan is supported by mrvl in region */ parsed_region_chan->chanpwr[idx].chan = curchan; parsed_region_chan->chanpwr[idx].pwr = @@ -554,8 +553,7 @@ done: * @param resp pointer to command response buffer * @return 0; -1 */ -int lbs_ret_802_11d_domain_info(struct lbs_private *priv, - struct cmd_ds_command *resp) +int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) { struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; struct mrvlietypes_domainparamset *domain = &domaininfo->domain; diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h index 811eea2cfba..4f4f47f0f87 100644 --- a/drivers/net/wireless/libertas/11d.h +++ b/drivers/net/wireless/libertas/11d.h @@ -83,7 +83,7 @@ struct lbs_private; u8 lbs_get_scan_type_11d(u8 chan, struct parsed_region_chan_11d *parsed_region_chan); -u32 lbs_chan_2_freq(u8 chan, u8 band); +u32 lbs_chan_2_freq(u8 chan); void lbs_init_11d(struct lbs_private *priv); @@ -93,8 +93,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmdno, u16 cmdOption); -int lbs_ret_802_11d_domain_info(struct lbs_private *priv, - struct cmd_ds_command *resp); +int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp); struct bss_descriptor; int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv, diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 87e145ffe8f..95d98203eb4 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -38,7 +38,7 @@ static int assoc_helper_essid(struct lbs_private *priv, escape_essid(assoc_req->ssid, assoc_req->ssid_len)); if (assoc_req->mode == IW_MODE_INFRA) { lbs_send_specific_ssid_scan(priv, assoc_req->ssid, - assoc_req->ssid_len, 0); + assoc_req->ssid_len); bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); @@ -53,7 +53,7 @@ static int assoc_helper_essid(struct lbs_private *priv, * scan data will cause us to join a non-existant adhoc network */ lbs_send_specific_ssid_scan(priv, assoc_req->ssid, - assoc_req->ssid_len, 1); + assoc_req->ssid_len); /* Search for the requested SSID in the scan table */ bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, @@ -181,17 +181,6 @@ int lbs_update_channel(struct lbs_private *priv) return ret; } -void lbs_sync_channel(struct work_struct *work) -{ - struct lbs_private *priv = container_of(work, struct lbs_private, - sync_channel); - - lbs_deb_enter(LBS_DEB_ASSOC); - if (lbs_update_channel(priv)) - lbs_pr_info("Channel synchronization failed."); - lbs_deb_leave(LBS_DEB_ASSOC); -} - static int assoc_helper_channel(struct lbs_private *priv, struct assoc_request * assoc_req) { @@ -279,13 +268,11 @@ static int assoc_helper_wep_keys(struct lbs_private *priv, /* enable/disable the MAC's WEP packet filter */ if (assoc_req->secinfo.wep_enabled) - priv->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE; + priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; else - priv->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE; + priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; - ret = lbs_set_mac_packet_filter(priv); - if (ret) - goto out; + lbs_set_mac_control(priv); mutex_lock(&priv->lock); @@ -315,9 +302,7 @@ static int assoc_helper_secinfo(struct lbs_private *priv, memcpy(&priv->secinfo, &assoc_req->secinfo, sizeof(struct lbs_802_11_security)); - ret = lbs_set_mac_packet_filter(priv); - if (ret) - goto out; + lbs_set_mac_control(priv); /* If RSN is already enabled, don't try to enable it again, since * ENABLE_RSN resets internal state machines and will clobber the @@ -360,11 +345,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv, if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); - ret = lbs_prepare_and_send_command(priv, - CMD_802_11_KEY_MATERIAL, - CMD_ACT_SET, - CMD_OPTION_WAITFORRSP, - 0, assoc_req); + ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); assoc_req->flags = flags; } @@ -374,11 +355,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv, if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); - ret = lbs_prepare_and_send_command(priv, - CMD_802_11_KEY_MATERIAL, - CMD_ACT_SET, - CMD_OPTION_WAITFORRSP, - 0, assoc_req); + ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); assoc_req->flags = flags; } @@ -413,11 +390,10 @@ static int should_deauth_infrastructure(struct lbs_private *priv, { int ret = 0; - lbs_deb_enter(LBS_DEB_ASSOC); - if (priv->connect_status != LBS_CONNECTED) return 0; + lbs_deb_enter(LBS_DEB_ASSOC); if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { lbs_deb_assoc("Deauthenticating due to new SSID\n"); ret = 1; @@ -456,7 +432,7 @@ static int should_deauth_infrastructure(struct lbs_private *priv, out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return 0; + return ret; } @@ -643,17 +619,11 @@ void lbs_association_worker(struct work_struct *work) } if (success) { - lbs_deb_assoc("ASSOC: associated to '%s', %s\n", - escape_essid(priv->curbssparams.ssid, - priv->curbssparams.ssid_len), + lbs_deb_assoc("associated to %s\n", print_mac(mac, priv->curbssparams.bssid)); lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, CMD_OPTION_WAITFORRSP, 0, NULL); - - lbs_prepare_and_send_command(priv, - CMD_802_11_GET_LOG, - 0, CMD_OPTION_WAITFORRSP, 0, NULL); } else { ret = -1; } diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index 08372bbf376..d489cf4cc1e 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h @@ -7,6 +7,5 @@ void lbs_association_worker(struct work_struct *work); struct assoc_request *lbs_get_association_request(struct lbs_private *priv); -void lbs_sync_channel(struct work_struct *work); #endif /* _LBS_ASSOC_H */ diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b3c1acbcc65..44b918a6c21 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -14,9 +14,46 @@ #include "cmd.h" static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); -static void lbs_set_cmd_ctrl_node(struct lbs_private *priv, - struct cmd_ctrl_node *ptempnode, - void *pdata_buf); + + +/** + * @brief Simple callback that copies response back into command + * + * @param priv A pointer to struct lbs_private structure + * @param extra A pointer to the original command structure for which + * 'resp' is a response + * @param resp A pointer to the command response + * + * @return 0 on success, error on failure + */ +int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, + struct cmd_header *resp) +{ + struct cmd_header *buf = (void *)extra; + uint16_t copy_len; + + copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); + memcpy(buf, resp, copy_len); + return 0; +} +EXPORT_SYMBOL_GPL(lbs_cmd_copyback); + +/** + * @brief Simple callback that ignores the result. Use this if + * you just want to send a command to the hardware, but don't + * care for the result. + * + * @param priv ignored + * @param extra ignored + * @param resp ignored + * + * @return 0 for success + */ +static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, + struct cmd_header *resp) +{ + return 0; +} /** @@ -143,8 +180,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria) } EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); -static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv, - struct cmd_ds_command *cmd, +static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd, u16 cmd_action) { struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; @@ -338,81 +374,108 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, return ret; } -static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, - struct enc_key * pkey) +static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, + struct enc_key *key) { lbs_deb_enter(LBS_DEB_CMD); - if (pkey->flags & KEY_INFO_WPA_ENABLED) { - pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); - } - if (pkey->flags & KEY_INFO_WPA_UNICAST) { - pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); - } - if (pkey->flags & KEY_INFO_WPA_MCAST) { - pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); - } + if (key->flags & KEY_INFO_WPA_ENABLED) + keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); + if (key->flags & KEY_INFO_WPA_UNICAST) + keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); + if (key->flags & KEY_INFO_WPA_MCAST) + keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); + + keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + keyparam->keytypeid = cpu_to_le16(key->type); + keyparam->keylen = cpu_to_le16(key->len); + memcpy(keyparam->key, key->key, key->len); - pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); - pkeyparamset->keytypeid = cpu_to_le16(pkey->type); - pkeyparamset->keylen = cpu_to_le16(pkey->len); - memcpy(pkeyparamset->key, pkey->key, pkey->len); - pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid) - + sizeof(pkeyparamset->keyinfo) - + sizeof(pkeyparamset->keylen) - + sizeof(pkeyparamset->key)); + /* Length field doesn't include the {type,length} header */ + keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); lbs_deb_leave(LBS_DEB_CMD); } -static int lbs_cmd_802_11_key_material(struct lbs_private *priv, - struct cmd_ds_command *cmd, - u16 cmd_action, - u32 cmd_oid, void *pdata_buf) +int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, + struct assoc_request *assoc) { - struct cmd_ds_802_11_key_material *pkeymaterial = - &cmd->params.keymaterial; - struct assoc_request * assoc_req = pdata_buf; + struct cmd_ds_802_11_key_material cmd; int ret = 0; int index = 0; lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); - pkeymaterial->action = cpu_to_le16(cmd_action); + cmd.action = cpu_to_le16(cmd_action); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); if (cmd_action == CMD_ACT_GET) { - cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); - ret = 0; - goto done; - } + cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2); + } else { + memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); - memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); + if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { + set_one_wpa_key(&cmd.keyParamSet[index], + &assoc->wpa_unicast_key); + index++; + } - if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { - set_one_wpa_key(&pkeymaterial->keyParamSet[index], - &assoc_req->wpa_unicast_key); - index++; - } + if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { + set_one_wpa_key(&cmd.keyParamSet[index], + &assoc->wpa_mcast_key); + index++; + } - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { - set_one_wpa_key(&pkeymaterial->keyParamSet[index], - &assoc_req->wpa_mcast_key); - index++; + /* The common header and as many keys as we included */ + cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), + keyParamSet[index])); } + ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); + /* Copy the returned key to driver private data */ + if (!ret && cmd_action == CMD_ACT_GET) { + void *buf_ptr = cmd.keyParamSet; + void *resp_end = &(&cmd)[1]; + + while (buf_ptr < resp_end) { + struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; + struct enc_key *key; + uint16_t param_set_len = le16_to_cpu(keyparam->length); + uint16_t key_len = le16_to_cpu(keyparam->keylen); + uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); + uint16_t key_type = le16_to_cpu(keyparam->keytypeid); + void *end; + + end = (void *)keyparam + sizeof(keyparam->type) + + sizeof(keyparam->length) + param_set_len; + + /* Make sure we don't access past the end of the IEs */ + if (end > resp_end) + break; - cmd->size = cpu_to_le16( S_DS_GEN - + sizeof (pkeymaterial->action) - + (index * sizeof(struct MrvlIEtype_keyParamSet))); + if (key_flags & KEY_INFO_WPA_UNICAST) + key = &priv->wpa_unicast_key; + else if (key_flags & KEY_INFO_WPA_MCAST) + key = &priv->wpa_mcast_key; + else + break; - ret = 0; + /* Copy returned key into driver */ + memset(key, 0, sizeof(struct enc_key)); + if (key_len > sizeof(key->key)) + break; + key->type = key_type; + key->flags = key_flags; + key->len = key_len; + memcpy(key->key, keyparam->key, key->len); + + buf_ptr = end + 1; + } + } -done: lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } -static int lbs_cmd_802_11_reset(struct lbs_private *priv, - struct cmd_ds_command *cmd, int cmd_action) +static int lbs_cmd_802_11_reset(struct cmd_ds_command *cmd, int cmd_action) { struct cmd_ds_802_11_reset *reset = &cmd->params.reset; @@ -426,30 +489,6 @@ static int lbs_cmd_802_11_reset(struct lbs_private *priv, return 0; } -static int lbs_cmd_802_11_get_log(struct lbs_private *priv, - struct cmd_ds_command *cmd) -{ - lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(CMD_802_11_GET_LOG); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - -static int lbs_cmd_802_11_get_stat(struct lbs_private *priv, - struct cmd_ds_command *cmd) -{ - lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(CMD_802_11_GET_STAT); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv, struct cmd_ds_command *cmd, int cmd_action, @@ -570,8 +609,7 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv, return 0; } -static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv, - struct cmd_ds_command *cmd, +static int lbs_cmd_802_11_rf_tx_power(struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -614,8 +652,7 @@ static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv, return 0; } -static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv, - struct cmd_ds_command *cmd, +static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; @@ -842,8 +879,7 @@ static int lbs_cmd_802_11_rssi(struct lbs_private *priv, return 0; } -static int lbs_cmd_reg_access(struct lbs_private *priv, - struct cmd_ds_command *cmdptr, +static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, u8 cmd_action, void *pdata_buf) { struct lbs_offset_value *offval; @@ -940,9 +976,8 @@ static int lbs_cmd_802_11_mac_address(struct lbs_private *priv, return 0; } -static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv, - struct cmd_ds_command *cmd, - int cmd_action, void *pdata_buf) +static int lbs_cmd_802_11_eeprom_access(struct cmd_ds_command *cmd, + void *pdata_buf) { struct lbs_ioctl_regrdwr *ea = pdata_buf; @@ -962,8 +997,7 @@ static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv, return 0; } -static int lbs_cmd_bt_access(struct lbs_private *priv, - struct cmd_ds_command *cmd, +static int lbs_cmd_bt_access(struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { struct cmd_ds_bt_access *bt_access = &cmd->params.bt; @@ -1000,8 +1034,7 @@ static int lbs_cmd_bt_access(struct lbs_private *priv, return 0; } -static int lbs_cmd_fwt_access(struct lbs_private *priv, - struct cmd_ds_command *cmd, +static int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; @@ -1153,9 +1186,9 @@ static void lbs_submit_command(struct lbs_private *priv, command == CMD_802_11_AUTHENTICATE) timeo = 10 * HZ; - lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", - command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); - lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); + lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", + command, le16_to_cpu(cmd->seqnum), cmdsize); + lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); @@ -1164,9 +1197,7 @@ static void lbs_submit_command(struct lbs_private *priv, /* Let the timer kick in and retry, and potentially reset the whole thing if the condition persists */ timeo = HZ; - } else - lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", - command, jiffies); + } /* Setup the timer after transmit command */ mod_timer(&priv->command_timer, jiffies + timeo); @@ -1174,24 +1205,6 @@ static void lbs_submit_command(struct lbs_private *priv, lbs_deb_leave(LBS_DEB_HOST); } -static int lbs_cmd_mac_control(struct lbs_private *priv, - struct cmd_ds_command *cmd) -{ - struct cmd_ds_mac_control *mac = &cmd->params.macctrl; - - lbs_deb_enter(LBS_DEB_CMD); - - cmd->command = cpu_to_le16(CMD_MAC_CONTROL); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); - mac->action = cpu_to_le16(priv->currentpacketfilter); - - lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n", - le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - /** * This function inserts command node to cmdfreeq * after cleans it. Requires priv->driver_lock held. @@ -1234,7 +1247,7 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, cmd->cmdwaitqwoken = 1; wake_up_interruptible(&cmd->cmdwait_q); - if (!cmd->callback) + if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) __lbs_cleanup_and_insert_cmd(priv, cmd); priv->cur_cmd = NULL; } @@ -1278,18 +1291,20 @@ int lbs_set_radio_control(struct lbs_private *priv) return ret; } -int lbs_set_mac_packet_filter(struct lbs_private *priv) +void lbs_set_mac_control(struct lbs_private *priv) { - int ret = 0; + struct cmd_ds_mac_control cmd; lbs_deb_enter(LBS_DEB_CMD); - /* Send MAC control command to station */ - ret = lbs_prepare_and_send_command(priv, - CMD_MAC_CONTROL, 0, 0, 0, NULL); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(priv->mac_control); + cmd.reserved = 0; - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; + lbs_cmd_async(priv, CMD_MAC_CONTROL, + &cmd.hdr, sizeof(cmd)); + + lbs_deb_leave(LBS_DEB_CMD); } /** @@ -1338,7 +1353,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, goto done; } - lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf); + cmdnode->callback = NULL; + cmdnode->callback_arg = (unsigned long)pdata_buf; cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; @@ -1353,15 +1369,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, switch (cmd_no) { case CMD_802_11_PS_MODE: - ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); - break; - - case CMD_802_11_SCAN: - ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf); - break; - - case CMD_MAC_CONTROL: - ret = lbs_cmd_mac_control(priv, cmdptr); + ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); break; case CMD_802_11_ASSOCIATE: @@ -1376,25 +1384,15 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, case CMD_802_11_AD_HOC_START: ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf); break; - case CMD_CODE_DNLD: - break; case CMD_802_11_RESET: - ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action); - break; - - case CMD_802_11_GET_LOG: - ret = lbs_cmd_802_11_get_log(priv, cmdptr); + ret = lbs_cmd_802_11_reset(cmdptr, cmd_action); break; case CMD_802_11_AUTHENTICATE: ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf); break; - case CMD_802_11_GET_STAT: - ret = lbs_cmd_802_11_get_stat(priv, cmdptr); - break; - case CMD_802_11_SNMP_MIB: ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr, cmd_action, cmd_oid, pdata_buf); @@ -1403,12 +1401,12 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, case CMD_MAC_REG_ACCESS: case CMD_BBP_REG_ACCESS: case CMD_RF_REG_ACCESS: - ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_RF_TX_POWER: - ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, - cmd_action, pdata_buf); + ret = lbs_cmd_802_11_rf_tx_power(cmdptr, + cmd_action, pdata_buf); break; case CMD_802_11_RATE_ADAPT_RATESET: @@ -1421,7 +1419,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, break; case CMD_802_11_MONITOR_MODE: - ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr, + ret = lbs_cmd_802_11_monitor_mode(cmdptr, cmd_action, pdata_buf); break; @@ -1434,17 +1432,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, break; case CMD_802_11_AD_HOC_STOP: - ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); - break; - - case CMD_802_11_KEY_MATERIAL: - ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action, - cmd_oid, pdata_buf); - break; - - case CMD_802_11_PAIRWISE_TSC: - break; - case CMD_802_11_GROUP_TSC: + ret = lbs_cmd_80211_ad_hoc_stop(cmdptr); break; case CMD_802_11_MAC_ADDRESS: @@ -1452,8 +1440,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, break; case CMD_802_11_EEPROM_ACCESS: - ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr, - cmd_action, pdata_buf); + ret = lbs_cmd_802_11_eeprom_access(cmdptr, pdata_buf); break; case CMD_802_11_SET_AFC: @@ -1509,22 +1496,12 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, break; } - case CMD_802_11_PWR_CFG: - cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG); - cmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) + - S_DS_GEN); - memmove(&cmdptr->params.pwrcfg, pdata_buf, - sizeof(struct cmd_ds_802_11_pwr_cfg)); - - ret = 0; - break; case CMD_BT_ACCESS: - ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); break; case CMD_FWT_ACCESS: - ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); break; case CMD_GET_TSF: @@ -1697,36 +1674,6 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) } /** - * @brief This function cleans command node. - * - * @param ptempnode A pointer to cmdCtrlNode structure - * @return n/a - */ - -/** - * @brief This function initializes the command node. - * - * @param priv A pointer to struct lbs_private structure - * @param ptempnode A pointer to cmd_ctrl_node structure - * @param pdata_buf A pointer to informaion buffer - * @return 0 or -1 - */ -static void lbs_set_cmd_ctrl_node(struct lbs_private *priv, - struct cmd_ctrl_node *ptempnode, - void *pdata_buf) -{ - lbs_deb_enter(LBS_DEB_HOST); - - if (!ptempnode) - return; - - ptempnode->callback = NULL; - ptempnode->callback_arg = (unsigned long)pdata_buf; - - lbs_deb_leave(LBS_DEB_HOST); -} - -/** * @brief This function executes next command in command * pending queue. It will put fimware back to PS mode * if applicable. @@ -1741,9 +1688,9 @@ int lbs_execute_next_command(struct lbs_private *priv) unsigned long flags; int ret = 0; - // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the - // only caller to us is lbs_thread() and we get even when a - // data packet is received + /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the + * only caller to us is lbs_thread() and we get even when a + * data packet is received */ lbs_deb_enter(LBS_DEB_THREAD); spin_lock_irqsave(&priv->driver_lock, flags); @@ -1913,10 +1860,6 @@ static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size) int ret = 0; lbs_deb_enter(LBS_DEB_HOST); - - lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n", - size); - lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size); ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size); @@ -1939,8 +1882,6 @@ static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size) priv->intcounter); } spin_unlock_irqrestore(&priv->driver_lock, flags); - - lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n"); } lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); @@ -1992,10 +1933,10 @@ void lbs_ps_wakeup(struct lbs_private *priv, int wait_option) * @param psmode Power Saving mode * @return n/a */ -void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode) +void lbs_ps_confirm_sleep(struct lbs_private *priv) { unsigned long flags =0; - u8 allowed = 1; + int allowed = 1; lbs_deb_enter(LBS_DEB_HOST); @@ -2027,39 +1968,10 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode) } -/** - * @brief Simple callback that copies response back into command - * - * @param priv A pointer to struct lbs_private structure - * @param extra A pointer to the original command structure for which - * 'resp' is a response - * @param resp A pointer to the command response - * - * @return 0 on success, error on failure - */ -int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, - struct cmd_header *resp) -{ - struct cmd_header *buf = (void *)extra; - uint16_t copy_len; - - lbs_deb_enter(LBS_DEB_CMD); - - copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); - lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, " - "copy back buffer was %u bytes\n", copy_len, - le16_to_cpu(resp->size), le16_to_cpu(buf->size)); - memcpy(buf, resp, copy_len); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} -EXPORT_SYMBOL_GPL(lbs_cmd_copyback); - -struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command, - struct cmd_header *in_cmd, int in_cmd_size, - int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), - unsigned long callback_arg) +static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, + uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, + int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), + unsigned long callback_arg) { struct cmd_ctrl_node *cmdnode; @@ -2096,9 +2008,6 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command lbs_deb_host("PREP_CMD: command 0x%04x\n", command); - /* here was the big old switch() statement, which is now obsolete, - * because the caller of lbs_cmd() sets up all of *cmd for us. */ - cmdnode->cmdwaitqwoken = 0; lbs_queue_cmd(priv, cmdnode); wake_up_interruptible(&priv->waitq); @@ -2108,6 +2017,15 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command return cmdnode; } +void lbs_cmd_async(struct lbs_private *priv, uint16_t command, + struct cmd_header *in_cmd, int in_cmd_size) +{ + lbs_deb_enter(LBS_DEB_CMD); + __lbs_cmd_async(priv, command, in_cmd, in_cmd_size, + lbs_cmd_async_callback, 0); + lbs_deb_leave(LBS_DEB_CMD); +} + int __lbs_cmd(struct lbs_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index b9ab85cc791..3dfc2d43c22 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h @@ -18,12 +18,9 @@ #define lbs_cmd_with_response(priv, cmdnr, cmd) \ lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd)) -/* __lbs_cmd() will free the cmdnode and return success/failure. - __lbs_cmd_async() requires that the callback free the cmdnode */ -struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command, - struct cmd_header *in_cmd, int in_cmd_size, - int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), - unsigned long callback_arg); +void lbs_cmd_async(struct lbs_private *priv, uint16_t command, + struct cmd_header *in_cmd, int in_cmd_size); + int __lbs_cmd(struct lbs_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), @@ -57,5 +54,7 @@ int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, struct assoc_request *assoc); int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, uint16_t *enable); +int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, + struct assoc_request *assoc); #endif /* _LBS_CMD_H */ diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index f0ef7081bde..9de9666d495 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -74,7 +74,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) lbs_deb_cmd("disconnected, so exit PS mode\n"); lbs_ps_wakeup(priv, 0); } - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_ASSOC); } /** @@ -146,22 +146,6 @@ static int lbs_ret_reg_access(struct lbs_private *priv, return ret; } -static int lbs_ret_802_11_stat(struct lbs_private *priv, - struct cmd_ds_command *resp) -{ - lbs_deb_enter(LBS_DEB_CMD); -/* currently priv->wlan802_11Stat is unused - - struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat; - - // TODO Convert it to Big endian befor copy - memcpy(&priv->wlan802_11Stat, - p11Stat, sizeof(struct cmd_ds_802_11_get_stat)); -*/ - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv, struct cmd_ds_command *resp) { @@ -204,61 +188,6 @@ static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv, return 0; } -static int lbs_ret_802_11_key_material(struct lbs_private *priv, - struct cmd_ds_command *resp) -{ - struct cmd_ds_802_11_key_material *pkeymaterial = - &resp->params.keymaterial; - u16 action = le16_to_cpu(pkeymaterial->action); - - lbs_deb_enter(LBS_DEB_CMD); - - /* Copy the returned key to driver private data */ - if (action == CMD_ACT_GET) { - u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet; - u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size)); - - while (buf_ptr < resp_end) { - struct MrvlIEtype_keyParamSet * pkeyparamset = - (struct MrvlIEtype_keyParamSet *) buf_ptr; - struct enc_key * pkey; - u16 param_set_len = le16_to_cpu(pkeyparamset->length); - u16 key_len = le16_to_cpu(pkeyparamset->keylen); - u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo); - u16 key_type = le16_to_cpu(pkeyparamset->keytypeid); - u8 * end; - - end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type) - + sizeof (pkeyparamset->length) - + param_set_len; - /* Make sure we don't access past the end of the IEs */ - if (end > resp_end) - break; - - if (key_flags & KEY_INFO_WPA_UNICAST) - pkey = &priv->wpa_unicast_key; - else if (key_flags & KEY_INFO_WPA_MCAST) - pkey = &priv->wpa_mcast_key; - else - break; - - /* Copy returned key into driver */ - memset(pkey, 0, sizeof(struct enc_key)); - if (key_len > sizeof(pkey->key)) - break; - pkey->type = key_type; - pkey->flags = key_flags; - pkey->len = key_len; - memcpy(pkey->key, pkeyparamset->key, pkey->len); - - buf_ptr = end + 1; - } - } - - lbs_deb_enter(LBS_DEB_CMD); - return 0; -} - static int lbs_ret_802_11_mac_address(struct lbs_private *priv, struct cmd_ds_command *resp) { @@ -358,20 +287,6 @@ static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv, return 0; } -static int lbs_ret_get_log(struct lbs_private *priv, - struct cmd_ds_command *resp) -{ - struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog; - - lbs_deb_enter(LBS_DEB_CMD); - - /* Stored little-endian */ - memcpy(&priv->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log)); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv, struct cmd_ds_command *resp) { @@ -390,7 +305,6 @@ static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv, } static inline int handle_cmd_response(struct lbs_private *priv, - unsigned long dummy, struct cmd_header *cmd_response) { struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response; @@ -407,14 +321,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, ret = lbs_ret_reg_access(priv, respcmd, resp); break; - case CMD_RET(CMD_802_11_SCAN): - ret = lbs_ret_80211_scan(priv, resp); - break; - - case CMD_RET(CMD_802_11_GET_LOG): - ret = lbs_ret_get_log(priv, resp); - break; - case CMD_RET_802_11_ASSOCIATE: case CMD_RET(CMD_802_11_ASSOCIATE): case CMD_RET(CMD_802_11_REASSOCIATE): @@ -423,7 +329,7 @@ static inline int handle_cmd_response(struct lbs_private *priv, case CMD_RET(CMD_802_11_DISASSOCIATE): case CMD_RET(CMD_802_11_DEAUTHENTICATE): - ret = lbs_ret_80211_disassociate(priv, resp); + ret = lbs_ret_80211_disassociate(priv); break; case CMD_RET(CMD_802_11_AD_HOC_START): @@ -431,10 +337,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, ret = lbs_ret_80211_ad_hoc_start(priv, resp); break; - case CMD_RET(CMD_802_11_GET_STAT): - ret = lbs_ret_802_11_stat(priv, resp); - break; - case CMD_RET(CMD_802_11_SNMP_MIB): ret = lbs_ret_802_11_snmp_mib(priv, resp); break; @@ -453,7 +355,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, break; case CMD_RET(CMD_MAC_MULTICAST_ADR): - case CMD_RET(CMD_MAC_CONTROL): case CMD_RET(CMD_802_11_RESET): case CMD_RET(CMD_802_11_AUTHENTICATE): case CMD_RET(CMD_802_11_BEACON_STOP): @@ -472,11 +373,7 @@ static inline int handle_cmd_response(struct lbs_private *priv, break; case CMD_RET(CMD_802_11_AD_HOC_STOP): - ret = lbs_ret_80211_ad_hoc_stop(priv, resp); - break; - - case CMD_RET(CMD_802_11_KEY_MATERIAL): - ret = lbs_ret_802_11_key_material(priv, resp); + ret = lbs_ret_80211_ad_hoc_stop(priv); break; case CMD_RET(CMD_802_11_EEPROM_ACCESS): @@ -484,7 +381,7 @@ static inline int handle_cmd_response(struct lbs_private *priv, break; case CMD_RET(CMD_802_11D_DOMAIN_INFO): - ret = lbs_ret_802_11d_domain_info(priv, resp); + ret = lbs_ret_802_11d_domain_info(resp); break; case CMD_RET(CMD_802_11_TPC_CFG): @@ -500,14 +397,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, spin_unlock_irqrestore(&priv->driver_lock, flags); break; - case CMD_RET(CMD_802_11_PWR_CFG): - spin_lock_irqsave(&priv->driver_lock, flags); - memmove((void *)priv->cur_cmd->callback_arg, &resp->params.pwrcfg, - sizeof(struct cmd_ds_802_11_pwr_cfg)); - spin_unlock_irqrestore(&priv->driver_lock, flags); - - break; - case CMD_RET(CMD_GET_TSF): spin_lock_irqsave(&priv->driver_lock, flags); memcpy((void *)priv->cur_cmd->callback_arg, @@ -566,9 +455,9 @@ int lbs_process_rx_command(struct lbs_private *priv) respcmd = le16_to_cpu(resp->command); result = le16_to_cpu(resp->result); - lbs_deb_host("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n", - respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); - lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len); + lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d\n", + respcmd, le16_to_cpu(resp->seqnum), priv->upld_len); + lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, priv->upld_len); if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", @@ -687,7 +576,7 @@ int lbs_process_rx_command(struct lbs_private *priv) ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, resp); } else - ret = handle_cmd_response(priv, 0, resp); + ret = handle_cmd_response(priv, resp); spin_lock_irqsave(&priv->driver_lock, flags); @@ -738,11 +627,9 @@ int lbs_process_event(struct lbs_private *priv) eventcause = priv->eventcause >> SBI_EVENT_CAUSE_SHIFT; spin_unlock_irq(&priv->driver_lock); - lbs_deb_cmd("event cause %d\n", eventcause); - switch (eventcause) { case MACREG_INT_CODE_LINK_SENSED: - lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n"); + lbs_deb_cmd("EVENT: link sensed\n"); break; case MACREG_INT_CODE_DEAUTHENTICATED: @@ -761,7 +648,7 @@ int lbs_process_event(struct lbs_private *priv) break; case MACREG_INT_CODE_PS_SLEEP: - lbs_deb_cmd("EVENT: sleep\n"); + lbs_deb_cmd("EVENT: ps sleep\n"); /* handle unexpected PS SLEEP event */ if (priv->psstate == PS_STATE_FULL_POWER) { @@ -771,17 +658,17 @@ int lbs_process_event(struct lbs_private *priv) } priv->psstate = PS_STATE_PRE_SLEEP; - lbs_ps_confirm_sleep(priv, (u16) priv->psmode); + lbs_ps_confirm_sleep(priv); break; case MACREG_INT_CODE_HOST_AWAKE: - lbs_deb_cmd("EVENT: HOST_AWAKE\n"); + lbs_deb_cmd("EVENT: host awake\n"); lbs_send_confirmwake(priv); break; case MACREG_INT_CODE_PS_AWAKE: - lbs_deb_cmd("EVENT: awake\n"); + lbs_deb_cmd("EVENT: ps awake\n"); /* handle unexpected PS AWAKE event */ if (priv->psstate == PS_STATE_FULL_POWER) { lbs_deb_cmd( @@ -812,14 +699,16 @@ int lbs_process_event(struct lbs_private *priv) lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n"); handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST); break; + case MACREG_INT_CODE_MIB_CHANGED: + lbs_deb_cmd("EVENT: MIB CHANGED\n"); + break; case MACREG_INT_CODE_INIT_DONE: + lbs_deb_cmd("EVENT: INIT DONE\n"); break; - case MACREG_INT_CODE_ADHOC_BCN_LOST: lbs_deb_cmd("EVENT: ADHOC beacon lost\n"); break; - case MACREG_INT_CODE_RSSI_LOW: lbs_pr_alert("EVENT: rssi low\n"); break; diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index fd67b770dd7..7072e26b42d 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -19,7 +19,7 @@ static char *szStates[] = { }; #ifdef PROC_DEBUG -static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev); +static void lbs_debug_init(struct lbs_private *priv); #endif static int open_file_generic(struct inode *inode, struct file *file) @@ -78,7 +78,7 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf, u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); pos += snprintf(buf+pos, len-pos, - "%02u| %03d | %04ld | %s |", + "%02u| %03d | %04d | %s |", numscansdone, iter_bss->channel, iter_bss->rssi, print_mac(mac, iter_bss->bssid)); pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); @@ -164,173 +164,6 @@ out_unlock: return ret; } -static ssize_t lbs_extscan(struct file *file, const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; - union iwreq_data wrqu; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - - lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); - - memset(&wrqu, 0, sizeof(union iwreq_data)); - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); - -out_unlock: - free_page(addr); - return count; -} - -static void lbs_parse_bssid(char *buf, size_t count, - struct lbs_ioctl_user_scan_cfg *scan_cfg) -{ - char *hold; - unsigned int mac[ETH_ALEN]; - - hold = strstr(buf, "bssid="); - if (!hold) - return; - hold += 6; - sscanf(hold, "%02x:%02x:%02x:%02x:%02x:%02x", - mac, mac+1, mac+2, mac+3, mac+4, mac+5); - memcpy(scan_cfg->bssid, mac, ETH_ALEN); -} - -static void lbs_parse_ssid(char *buf, size_t count, - struct lbs_ioctl_user_scan_cfg *scan_cfg) -{ - char *hold, *end; - ssize_t size; - - hold = strstr(buf, "ssid="); - if (!hold) - return; - hold += 5; - end = strchr(hold, ' '); - if (!end) - end = buf + count - 1; - - size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold)); - strncpy(scan_cfg->ssid, hold, size); - - return; -} - -static int lbs_parse_clear(char *buf, size_t count, const char *tag) -{ - char *hold; - int val; - - hold = strstr(buf, tag); - if (!hold) - return 0; - hold += strlen(tag); - sscanf(hold, "%d", &val); - - if (val != 0) - val = 1; - - return val; -} - -static int lbs_parse_dur(char *buf, size_t count, - struct lbs_ioctl_user_scan_cfg *scan_cfg) -{ - char *hold; - int val; - - hold = strstr(buf, "dur="); - if (!hold) - return 0; - hold += 4; - sscanf(hold, "%d", &val); - - return val; -} - -static void lbs_parse_type(char *buf, size_t count, - struct lbs_ioctl_user_scan_cfg *scan_cfg) -{ - char *hold; - int val; - - hold = strstr(buf, "type="); - if (!hold) - return; - hold += 5; - sscanf(hold, "%d", &val); - - /* type=1,2 or 3 */ - if (val < 1 || val > 3) - return; - - scan_cfg->bsstype = val; - - return; -} - -static ssize_t lbs_setuserscan(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct lbs_private *priv = file->private_data; - ssize_t res, buf_size; - struct lbs_ioctl_user_scan_cfg *scan_cfg; - union iwreq_data wrqu; - int dur; - char *buf = (char *)get_zeroed_page(GFP_KERNEL); - - if (!buf) - return -ENOMEM; - - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_buf; - } - - scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL); - if (!scan_cfg) { - res = -ENOMEM; - goto out_buf; - } - res = count; - - scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY; - - dur = lbs_parse_dur(buf, count, scan_cfg); - lbs_parse_bssid(buf, count, scan_cfg); - scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid="); - lbs_parse_ssid(buf, count, scan_cfg); - scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid="); - lbs_parse_type(buf, count, scan_cfg); - - lbs_scan_networks(priv, scan_cfg, 1); - wait_event_interruptible(priv->cmd_pending, - priv->surpriseremoved || !priv->last_scanned_channel); - - if (priv->surpriseremoved) - goto out_scan_cfg; - - memset(&wrqu, 0x00, sizeof(union iwreq_data)); - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); - - out_scan_cfg: - kfree(scan_cfg); - out_buf: - free_page((unsigned long)buf); - return res; -} - - /* * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the @@ -857,8 +690,6 @@ static struct lbs_debugfs_files debugfs_files[] = { write_file_dummy), }, { "sleepparams", 0644, FOPS(lbs_sleepparams_read, lbs_sleepparams_write), }, - { "extscan", 0600, FOPS(NULL, lbs_extscan), }, - { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), }, }; static struct lbs_debugfs_files debugfs_events_files[] = { @@ -947,7 +778,7 @@ void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) } #ifdef PROC_DEBUG - lbs_debug_init(priv, dev); + lbs_debug_init(priv); #endif exit: return; @@ -1121,7 +952,7 @@ static struct file_operations lbs_debug_fops = { * @param dev pointer net_device * @return N/A */ -static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev) +static void lbs_debug_init(struct lbs_private *priv) { int i; diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 4e22341b4f3..cadc59d7f77 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -17,7 +17,7 @@ struct net_device; struct cmd_ctrl_node; struct cmd_ds_command; -int lbs_set_mac_packet_filter(struct lbs_private *priv); +void lbs_set_mac_control(struct lbs_private *priv); void lbs_send_tx_feedback(struct lbs_private *priv); @@ -49,7 +49,7 @@ int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band); int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *); void lbs_ps_sleep(struct lbs_private *priv, int wait_option); -void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode); +void lbs_ps_confirm_sleep(struct lbs_private *priv); void lbs_ps_wakeup(struct lbs_private *priv, int wait_option); struct chan_freq_power *lbs_find_cfp_by_band_and_channel( @@ -63,7 +63,6 @@ void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str); /* main.c */ struct chan_freq_power *lbs_get_region_cfp_table(u8 region, - u8 band, int *cfp_no); struct lbs_private *lbs_add_card(void *card, struct device *dmdev); int lbs_remove_card(struct lbs_private *priv); diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 3053cc2160b..84e8de5e21d 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -53,14 +53,14 @@ do { if ((lbs_debug & (grp)) == (grp)) \ #endif #define lbs_deb_enter(grp) \ - LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s():%d\n", __FUNCTION__, __LINE__); + LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s()\n", __func__); #define lbs_deb_enter_args(grp, fmt, args...) \ - LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__); + LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s(" fmt ")\n", __func__, ## args); #define lbs_deb_leave(grp) \ - LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d\n", __FUNCTION__, __LINE__); + LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s()\n", __func__); #define lbs_deb_leave_args(grp, fmt, args...) \ - LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d, " fmt "\n", \ - __FUNCTION__, __LINE__, ##args); + LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s(), " fmt "\n", \ + __func__, ##args); #define lbs_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, " main", fmt, ##args) #define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, " net", fmt, ##args) #define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, " mesh", fmt, ##args) diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 5a69f2b6086..17e02bed6bf 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -143,9 +143,14 @@ struct lbs_private { wait_queue_head_t waitq; struct workqueue_struct *work_thread; + /** Scanning */ struct delayed_work scan_work; struct delayed_work assoc_work; struct work_struct sync_channel; + /* remember which channel was scanned last, != 0 if currently scanning */ + int scan_channel; + u8 scan_ssid[IW_ESSID_MAX_SIZE + 1]; + u8 scan_ssid_len; /** Hardware access */ int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); @@ -247,7 +252,7 @@ struct lbs_private { struct sk_buff *currenttxskb; /** NIC Operation characteristics */ - u16 currentpacketfilter; + u16 mac_control; u32 connect_status; u32 mesh_connect_status; u16 regioncode; @@ -318,10 +323,7 @@ struct lbs_private { u8 *prdeeprom; struct lbs_offset_value offsetvalue; - struct cmd_ds_802_11_get_log logmsg; - u32 monitormode; - int last_scanned_channel; u8 fw_ready; }; diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 1aa04076b1a..3915c3144fa 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -33,7 +33,6 @@ #define CMD_RET_802_11_ASSOCIATE 0x8012 /* Command codes */ -#define CMD_CODE_DNLD 0x0002 #define CMD_GET_HW_SPEC 0x0003 #define CMD_EEPROM_UPDATE 0x0004 #define CMD_802_11_RESET 0x0005 @@ -68,8 +67,6 @@ #define CMD_802_11_AD_HOC_JOIN 0x002c #define CMD_802_11_QUERY_TKIP_REPLY_CNTRS 0x002e #define CMD_802_11_ENABLE_RSN 0x002f -#define CMD_802_11_PAIRWISE_TSC 0x0036 -#define CMD_802_11_GROUP_TSC 0x0037 #define CMD_802_11_SET_AFC 0x003c #define CMD_802_11_GET_AFC 0x003d #define CMD_802_11_AD_HOC_STOP 0x0040 @@ -87,7 +84,6 @@ #define CMD_802_11_INACTIVITY_TIMEOUT 0x0067 #define CMD_802_11_SLEEP_PERIOD 0x0068 #define CMD_802_11_TPC_CFG 0x0072 -#define CMD_802_11_PWR_CFG 0x0073 #define CMD_802_11_FW_WAKE_METHOD 0x0074 #define CMD_802_11_SUBSCRIBE_EVENT 0x0075 #define CMD_802_11_RATE_ADAPT_RATESET 0x0076 diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index d35b015b665..b8e372007bb 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -174,9 +174,11 @@ struct cmd_ds_802_11_subscribe_event { * Define data structure for CMD_802_11_SCAN */ struct cmd_ds_802_11_scan { - u8 bsstype; - u8 bssid[ETH_ALEN]; - u8 tlvbuffer[1]; + struct cmd_header hdr; + + uint8_t bsstype; + uint8_t bssid[ETH_ALEN]; + uint8_t tlvbuffer[0]; #if 0 mrvlietypes_ssidparamset_t ssidParamSet; mrvlietypes_chanlistparamset_t ChanListParamSet; @@ -185,12 +187,16 @@ struct cmd_ds_802_11_scan { }; struct cmd_ds_802_11_scan_rsp { + struct cmd_header hdr; + __le16 bssdescriptsize; - u8 nr_sets; - u8 bssdesc_and_tlvbuffer[1]; + uint8_t nr_sets; + uint8_t bssdesc_and_tlvbuffer[0]; }; struct cmd_ds_802_11_get_log { + struct cmd_header hdr; + __le32 mcasttxframe; __le32 failed; __le32 retry; @@ -207,8 +213,9 @@ struct cmd_ds_802_11_get_log { }; struct cmd_ds_mac_control { + struct cmd_header hdr; __le16 action; - __le16 reserved; + u16 reserved; }; struct cmd_ds_mac_multicast_adr { @@ -572,6 +579,8 @@ struct cmd_ds_host_sleep { } __attribute__ ((packed)); struct cmd_ds_802_11_key_material { + struct cmd_header hdr; + __le16 action; struct MrvlIEtype_keyParamSet keyParamSet[2]; } __attribute__ ((packed)); @@ -600,14 +609,6 @@ struct cmd_ds_802_11_led_ctrl { u8 data[256]; } __attribute__ ((packed)); -struct cmd_ds_802_11_pwr_cfg { - __le16 action; - u8 enable; - s8 PA_P0; - s8 PA_P1; - s8 PA_P2; -} __attribute__ ((packed)); - struct cmd_ds_802_11_afc { __le16 afc_auto; union { @@ -689,15 +690,11 @@ struct cmd_ds_command { /* command Body */ union { struct cmd_ds_802_11_ps_mode psmode; - struct cmd_ds_802_11_scan scan; - struct cmd_ds_802_11_scan_rsp scanresp; - struct cmd_ds_mac_control macctrl; struct cmd_ds_802_11_associate associate; struct cmd_ds_802_11_deauthenticate deauth; struct cmd_ds_802_11_ad_hoc_start ads; struct cmd_ds_802_11_reset reset; struct cmd_ds_802_11_ad_hoc_result result; - struct cmd_ds_802_11_get_log glog; struct cmd_ds_802_11_authenticate auth; struct cmd_ds_802_11_get_stat gstat; struct cmd_ds_802_3_get_stat gstat_8023; @@ -712,7 +709,6 @@ struct cmd_ds_command { struct cmd_ds_802_11_rssi_rsp rssirsp; struct cmd_ds_802_11_disassociate dassociate; struct cmd_ds_802_11_mac_address macadd; - struct cmd_ds_802_11_key_material keymaterial; struct cmd_ds_mac_reg_access macreg; struct cmd_ds_bbp_reg_access bbpreg; struct cmd_ds_rf_reg_access rfreg; @@ -722,7 +718,6 @@ struct cmd_ds_command { struct cmd_ds_802_11d_domain_info domaininforesp; struct cmd_ds_802_11_tpc_cfg tpccfg; - struct cmd_ds_802_11_pwr_cfg pwrcfg; struct cmd_ds_802_11_afc afc; struct cmd_ds_802_11_led_ctrl ledgpio; diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 5a9cadb9750..d1774658216 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -882,6 +882,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out3; } + /* The firmware for the CF card supports powersave */ + priv->ps_supported = 1; + ret = 0; goto out; diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index 2d4508048b6..3e5026ff2ff 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -99,23 +99,6 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len) } /** - * @brief Unsets the MSB on basic rates - * - * Scan through an array and unset the MSB for basic data rates. - * - * @param rates buffer of data rates - * @param len size of buffer - */ -void lbs_unset_basic_rate_flags(u8 *rates, size_t len) -{ - int i; - - for (i = 0; i < len; i++) - rates[i] &= 0x7f; -} - - -/** * @brief Associate to a specific BSS discovered in a scan * * @param priv A pointer to struct lbs_private structure @@ -578,8 +561,7 @@ done: return ret; } -int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv, - struct cmd_ds_command *cmd) +int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd) { cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP); cmd->size = cpu_to_le16(S_DS_GEN); @@ -769,9 +751,6 @@ int lbs_ret_80211_associate(struct lbs_private *priv, priv->curbssparams.ssid_len = bss->ssid_len; memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); - lbs_deb_assoc("ASSOC_RESP: currentpacketfilter is 0x%x\n", - priv->currentpacketfilter); - priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; priv->NF[TYPE_RXPD][TYPE_AVG] = 0; @@ -793,8 +772,7 @@ done: return ret; } -int lbs_ret_80211_disassociate(struct lbs_private *priv, - struct cmd_ds_command *resp) +int lbs_ret_80211_disassociate(struct lbs_private *priv) { lbs_deb_enter(LBS_DEB_JOIN); @@ -883,8 +861,7 @@ done: return ret; } -int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv, - struct cmd_ds_command *resp) +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv) { lbs_deb_enter(LBS_DEB_JOIN); diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index c617d071f78..bfc3a10a2f3 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h @@ -18,8 +18,7 @@ int lbs_cmd_80211_authenticate(struct lbs_private *priv, int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv, - struct cmd_ds_command *cmd); +int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd); int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); @@ -31,10 +30,8 @@ int lbs_cmd_80211_associate(struct lbs_private *priv, int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *resp); -int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv, - struct cmd_ds_command *resp); -int lbs_ret_80211_disassociate(struct lbs_private *priv, - struct cmd_ds_command *resp); +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv); +int lbs_ret_80211_disassociate(struct lbs_private *priv); int lbs_ret_80211_associate(struct lbs_private *priv, struct cmd_ds_command *resp); @@ -48,6 +45,4 @@ int lbs_send_deauthentication(struct lbs_private *priv); int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); -void lbs_unset_basic_rate_flags(u8 *rates, size_t len); - #endif diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4d4e2f3b66a..dac72f7af70 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -277,10 +277,10 @@ static ssize_t lbs_rtap_set(struct device *dev, struct lbs_private *priv = to_net_dev(dev)->priv; sscanf(buf, "%x", &monitor_mode); - if (monitor_mode != LBS_MONITOR_OFF) { - if(priv->monitormode == monitor_mode) + if (monitor_mode) { + if (priv->monitormode == monitor_mode) return strlen(buf); - if (priv->monitormode == LBS_MONITOR_OFF) { + if (!priv->monitormode) { if (priv->infra_open || priv->mesh_open) return -EBUSY; if (priv->mode == IW_MODE_INFRA) @@ -293,9 +293,9 @@ static ssize_t lbs_rtap_set(struct device *dev, } else { - if (priv->monitormode == LBS_MONITOR_OFF) + if (!priv->monitormode) return strlen(buf); - priv->monitormode = LBS_MONITOR_OFF; + priv->monitormode = 0; lbs_remove_rtap(priv); if (priv->currenttxskb) { @@ -392,7 +392,7 @@ static int lbs_dev_open(struct net_device *dev) spin_lock_irq(&priv->driver_lock); - if (priv->monitormode != LBS_MONITOR_OFF) { + if (priv->monitormode) { ret = -EBUSY; goto out; } @@ -581,45 +581,45 @@ static int lbs_copy_multicast_address(struct lbs_private *priv, static void lbs_set_multicast_list(struct net_device *dev) { struct lbs_private *priv = dev->priv; - int oldpacketfilter; + int old_mac_control; DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_NET); - oldpacketfilter = priv->currentpacketfilter; + old_mac_control = priv->mac_control; if (dev->flags & IFF_PROMISC) { lbs_deb_net("enable promiscuous mode\n"); - priv->currentpacketfilter |= + priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; - priv->currentpacketfilter &= + priv->mac_control &= ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE | CMD_ACT_MAC_MULTICAST_ENABLE); } else { /* Multicast */ - priv->currentpacketfilter &= + priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; if (dev->flags & IFF_ALLMULTI || dev->mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) { lbs_deb_net( "enabling all multicast\n"); - priv->currentpacketfilter |= + priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE; - priv->currentpacketfilter &= + priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE; } else { - priv->currentpacketfilter &= + priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE; if (!dev->mc_count) { lbs_deb_net("no multicast addresses, " "disabling multicast\n"); - priv->currentpacketfilter &= + priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE; } else { int i; - priv->currentpacketfilter |= + priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE; priv->nr_of_multicastmacaddr = @@ -642,9 +642,8 @@ static void lbs_set_multicast_list(struct net_device *dev) } } - if (priv->currentpacketfilter != oldpacketfilter) { - lbs_set_mac_packet_filter(priv); - } + if (priv->mac_control != old_mac_control) + lbs_set_mac_control(priv); lbs_deb_leave(LBS_DEB_NET); } @@ -804,7 +803,7 @@ static int lbs_thread(void *data) lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n", priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd); - lbs_ps_confirm_sleep(priv, (u16) priv->psmode); + lbs_ps_confirm_sleep(priv); } else { /* workaround for firmware sending * deauth/linkloss event immediately @@ -945,7 +944,7 @@ static int lbs_setup_firmware(struct lbs_private *priv) goto done; } - lbs_set_mac_packet_filter(priv); + lbs_set_mac_control(priv); ret = lbs_get_data_rate(priv); if (ret < 0) { @@ -985,6 +984,18 @@ out: lbs_deb_leave(LBS_DEB_CMD); } +static void lbs_sync_channel_worker(struct work_struct *work) +{ + struct lbs_private *priv = container_of(work, struct lbs_private, + sync_channel); + + lbs_deb_enter(LBS_DEB_MAIN); + if (lbs_update_channel(priv)) + lbs_pr_info("Channel synchronization failed."); + lbs_deb_leave(LBS_DEB_MAIN); +} + + static int lbs_init_adapter(struct lbs_private *priv) { size_t bufsize; @@ -1024,7 +1035,7 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; priv->mode = IW_MODE_INFRA; priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; - priv->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; + priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; priv->radioon = RADIO_ON; priv->auto_rate = 1; priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; @@ -1128,7 +1139,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) priv->work_thread = create_singlethread_workqueue("lbs_worker"); INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); - INIT_WORK(&priv->sync_channel, lbs_sync_channel); + INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker); sprintf(priv->mesh_ssid, "mesh"); priv->mesh_ssid_len = 4; @@ -1380,7 +1391,7 @@ static void lbs_remove_mesh(struct lbs_private *priv) * @param cfp_no A pointer to CFP number * @return A pointer to CFP */ -struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no) +struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no) { int i, end; @@ -1414,7 +1425,7 @@ int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band) memset(priv->region_channel, 0, sizeof(priv->region_channel)); - cfp = lbs_get_region_cfp_table(region, band, &cfp_no); + cfp = lbs_get_region_cfp_table(region, &cfp_no); if (cfp != NULL) { priv->region_channel[i].nrcfp = cfp_no; priv->region_channel[i].CFP = cfp; diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 149557a478a..09f023089ea 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -155,7 +155,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - if (priv->monitormode != LBS_MONITOR_OFF) + if (priv->monitormode) return process_rxed_802_11_packet(priv, skb); p_rx_pkt = (struct rxpackethdr *) skb->data; diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 69f94c92b32..3825b7979fc 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -20,6 +20,7 @@ #include "dev.h" #include "scan.h" #include "join.h" +#include "cmd.h" //! Approximate amount of data needed to pass a scan result back to iwlist #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ @@ -39,10 +40,9 @@ //! Memory needed to store a max number/size SSID TLV for a firmware scan #define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) -//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max -#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config) \ - + CHAN_TLV_MAX_SIZE \ - + SSID_TLV_MAX_SIZE) +//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max +#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ + + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE) //! The maximum number of channels the firmware can scan per command #define MRVDRV_MAX_CHANNELS_PER_SCAN 14 @@ -61,11 +61,8 @@ //! Scan time specified in the channel TLV for each channel for active scans #define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 -static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - - +static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, + struct cmd_header *resp); /*********************************************************************/ /* */ @@ -73,7 +70,24 @@ static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* */ /*********************************************************************/ -static inline void clear_bss_descriptor (struct bss_descriptor * bss) +/** + * @brief Unsets the MSB on basic rates + * + * Scan through an array and unset the MSB for basic data rates. + * + * @param rates buffer of data rates + * @param len size of buffer + */ +static void lbs_unset_basic_rate_flags(u8 *rates, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + rates[i] &= 0x7f; +} + + +static inline void clear_bss_descriptor(struct bss_descriptor *bss) { /* Don't blow away ->list, just BSS data */ memset(bss, 0, offsetof(struct bss_descriptor, list)); @@ -87,7 +101,8 @@ static inline void clear_bss_descriptor (struct bss_descriptor * bss) * * @return 0: ssid is same, otherwise is different */ -int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) +int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2, + uint8_t ssid2_len) { if (ssid1_len != ssid2_len) return -1; @@ -96,73 +111,66 @@ int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) } static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, - struct bss_descriptor * match_bss) + struct bss_descriptor *match_bss) { - if ( !secinfo->wep_enabled - && !secinfo->WPAenabled + if (!secinfo->wep_enabled && !secinfo->WPAenabled && !secinfo->WPA2enabled && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC && match_bss->rsn_ie[0] != MFIE_TYPE_RSN - && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { + && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; - } - return 0; + else + return 0; } static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, - struct bss_descriptor * match_bss) + struct bss_descriptor *match_bss) { - if ( secinfo->wep_enabled - && !secinfo->WPAenabled - && !secinfo->WPA2enabled - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { + if (secinfo->wep_enabled && !secinfo->WPAenabled + && !secinfo->WPA2enabled + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; - } - return 0; + else + return 0; } static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, - struct bss_descriptor * match_bss) + struct bss_descriptor *match_bss) { - if ( !secinfo->wep_enabled - && secinfo->WPAenabled - && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { - */ - ) { + if (!secinfo->wep_enabled && secinfo->WPAenabled + && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC) + /* privacy bit may NOT be set in some APs like LinkSys WRT54G + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ + ) return 1; - } - return 0; + else + return 0; } static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, - struct bss_descriptor * match_bss) + struct bss_descriptor *match_bss) { - if ( !secinfo->wep_enabled - && secinfo->WPA2enabled - && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { - */ - ) { + if (!secinfo->wep_enabled && secinfo->WPA2enabled + && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN) + /* privacy bit may NOT be set in some APs like LinkSys WRT54G + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ + ) return 1; - } - return 0; + else + return 0; } static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, - struct bss_descriptor * match_bss) + struct bss_descriptor *match_bss) { - if ( !secinfo->wep_enabled - && !secinfo->WPAenabled - && !secinfo->WPA2enabled - && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC) - && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN) - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { + if (!secinfo->wep_enabled && !secinfo->WPAenabled + && !secinfo->WPA2enabled + && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC) + && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN) + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; - } - return 0; + else + return 0; } static inline int is_same_network(struct bss_descriptor *src, @@ -197,7 +205,7 @@ static inline int is_same_network(struct bss_descriptor *src, * @return Index in scantable, or error code if negative */ static int is_network_compatible(struct lbs_private *priv, - struct bss_descriptor * bss, u8 mode) + struct bss_descriptor *bss, uint8_t mode) { int matched = 0; @@ -211,43 +219,39 @@ static int is_network_compatible(struct lbs_private *priv, } else if ((matched = match_bss_static_wep(&priv->secinfo, bss))) { goto done; } else if ((matched = match_bss_wpa(&priv->secinfo, bss))) { - lbs_deb_scan( - "is_network_compatible() WPA: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); + lbs_deb_scan("is_network_compatible() WPA: wpa_ie 0x%x " + "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " + "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], + priv->secinfo.wep_enabled ? "e" : "d", + priv->secinfo.WPAenabled ? "e" : "d", + priv->secinfo.WPA2enabled ? "e" : "d", + (bss->capability & WLAN_CAPABILITY_PRIVACY)); goto done; } else if ((matched = match_bss_wpa2(&priv->secinfo, bss))) { - lbs_deb_scan( - "is_network_compatible() WPA2: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); + lbs_deb_scan("is_network_compatible() WPA2: wpa_ie 0x%x " + "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " + "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], + priv->secinfo.wep_enabled ? "e" : "d", + priv->secinfo.WPAenabled ? "e" : "d", + priv->secinfo.WPA2enabled ? "e" : "d", + (bss->capability & WLAN_CAPABILITY_PRIVACY)); goto done; } else if ((matched = match_bss_dynamic_wep(&priv->secinfo, bss))) { - lbs_deb_scan( - "is_network_compatible() dynamic WEP: " - "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n", - bss->wpa_ie[0], bss->rsn_ie[0], - (bss->capability & WLAN_CAPABILITY_PRIVACY)); + lbs_deb_scan("is_network_compatible() dynamic WEP: " + "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n", + bss->wpa_ie[0], bss->rsn_ie[0], + (bss->capability & WLAN_CAPABILITY_PRIVACY)); goto done; } /* bss security settings don't match those configured on card */ - lbs_deb_scan( - "is_network_compatible() FAILED: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n", - bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); + lbs_deb_scan("is_network_compatible() FAILED: wpa_ie 0x%x " + "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n", + bss->wpa_ie[0], bss->rsn_ie[0], + priv->secinfo.wep_enabled ? "e" : "d", + priv->secinfo.WPAenabled ? "e" : "d", + priv->secinfo.WPA2enabled ? "e" : "d", + (bss->capability & WLAN_CAPABILITY_PRIVACY)); done: lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched); @@ -256,24 +260,12 @@ done: - /*********************************************************************/ /* */ /* Main scanning support */ /* */ /*********************************************************************/ -void lbs_scan_worker(struct work_struct *work) -{ - struct lbs_private *priv = - container_of(work, struct lbs_private, scan_work.work); - - lbs_deb_enter(LBS_DEB_SCAN); - lbs_scan_networks(priv, NULL, 0); - lbs_deb_leave(LBS_DEB_SCAN); -} - - /** * @brief Create a channel list for the driver to scan based on region info * @@ -285,25 +277,18 @@ void lbs_scan_worker(struct work_struct *work) * * @param priv A pointer to struct lbs_private structure * @param scanchanlist Output parameter: resulting channel list to scan - * @param filteredscan Flag indicating whether or not a BSSID or SSID filter - * is being sent in the command to firmware. Used to - * increase the number of channels sent in a scan - * command and to disable the firmware channel scan - * filter. * * @return void */ static int lbs_scan_create_channel_list(struct lbs_private *priv, - struct chanscanparamset * scanchanlist, - u8 filteredscan) + struct chanscanparamset *scanchanlist) { - struct region_channel *scanregion; struct chan_freq_power *cfp; int rgnidx; int chanidx; int nextchan; - u8 scantype; + uint8_t scantype; chanidx = 0; @@ -314,9 +299,8 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, scantype = CMD_SCAN_TYPE_ACTIVE; for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) { - if (priv->enable11d && - (priv->connect_status != LBS_CONNECTED) && - (priv->mesh_connect_status != LBS_CONNECTED)) { + if (priv->enable11d && (priv->connect_status != LBS_CONNECTED) + && (priv->mesh_connect_status != LBS_CONNECTED)) { /* Scan all the supported chan for the first scan */ if (!priv->universal_channel[rgnidx].valid) continue; @@ -331,45 +315,27 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, scanregion = &priv->region_channel[rgnidx]; } - for (nextchan = 0; - nextchan < scanregion->nrcfp; nextchan++, chanidx++) { + for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) { + struct chanscanparamset *chan = &scanchanlist[chanidx]; cfp = scanregion->CFP + nextchan; - if (priv->enable11d) { - scantype = - lbs_get_scan_type_11d(cfp->channel, - &priv-> - parsed_region_chan); - } + if (priv->enable11d) + scantype = lbs_get_scan_type_11d(cfp->channel, + &priv->parsed_region_chan); - switch (scanregion->band) { - case BAND_B: - case BAND_G: - default: - scanchanlist[chanidx].radiotype = - CMD_SCAN_RADIO_TYPE_BG; - break; - } + if (scanregion->band == BAND_B || scanregion->band == BAND_G) + chan->radiotype = CMD_SCAN_RADIO_TYPE_BG; if (scantype == CMD_SCAN_TYPE_PASSIVE) { - scanchanlist[chanidx].maxscantime = - cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); - scanchanlist[chanidx].chanscanmode.passivescan = - 1; + chan->maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); + chan->chanscanmode.passivescan = 1; } else { - scanchanlist[chanidx].maxscantime = - cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); - scanchanlist[chanidx].chanscanmode.passivescan = - 0; + chan->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); + chan->chanscanmode.passivescan = 0; } - scanchanlist[chanidx].channumber = cfp->channel; - - if (filteredscan) { - scanchanlist[chanidx].chanscanmode. - disablechanfilt = 1; - } + chan->channumber = cfp->channel; } } return chanidx; @@ -383,15 +349,14 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, * length 06 00 * ssid 4d 4e 54 45 53 54 */ -static int lbs_scan_add_ssid_tlv(u8 *tlv, - const struct lbs_ioctl_user_scan_cfg *user_cfg) +static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) { - struct mrvlietypes_ssidparamset *ssid_tlv = - (struct mrvlietypes_ssidparamset *)tlv; + struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; + ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); - ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len); - memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len); - return sizeof(ssid_tlv->header) + user_cfg->ssid_len; + ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); + memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len); + return sizeof(ssid_tlv->header) + priv->scan_ssid_len; } @@ -420,13 +385,12 @@ static int lbs_scan_add_ssid_tlv(u8 *tlv, * channel 13 00 0d 00 00 00 64 00 * */ -static int lbs_scan_add_chanlist_tlv(u8 *tlv, - struct chanscanparamset *chan_list, - int chan_count) +static int lbs_scan_add_chanlist_tlv(uint8_t *tlv, + struct chanscanparamset *chan_list, + int chan_count) { - size_t size = sizeof(struct chanscanparamset) * chan_count; - struct mrvlietypes_chanlistparamset *chan_tlv = - (struct mrvlietypes_chanlistparamset *) tlv; + size_t size = sizeof(struct chanscanparamset) *chan_count; + struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv; chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); memcpy(chan_tlv->chanscanparam, chan_list, size); @@ -445,11 +409,10 @@ static int lbs_scan_add_chanlist_tlv(u8 *tlv, * The rates are in lbs_bg_rates[], but for the 802.11b * rates the high bit isn't set. */ -static int lbs_scan_add_rates_tlv(u8 *tlv) +static int lbs_scan_add_rates_tlv(uint8_t *tlv) { int i; - struct mrvlietypes_ratesparamset *rate_tlv = - (struct mrvlietypes_ratesparamset *) tlv; + struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv; rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); tlv += sizeof(rate_tlv->header); @@ -475,44 +438,44 @@ static int lbs_scan_add_rates_tlv(u8 *tlv) * Generate the CMD_802_11_SCAN command with the proper tlv * for a bunch of channels. */ -static int lbs_do_scan(struct lbs_private *priv, - u8 bsstype, - struct chanscanparamset *chan_list, - int chan_count, - const struct lbs_ioctl_user_scan_cfg *user_cfg) +static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, + struct chanscanparamset *chan_list, int chan_count) { int ret = -ENOMEM; - struct lbs_scan_cmd_config *scan_cmd; - u8 *tlv; /* pointer into our current, growing TLV storage area */ + struct cmd_ds_802_11_scan *scan_cmd; + uint8_t *tlv; /* pointer into our current, growing TLV storage area */ - lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, " - "chan_count %d", - bsstype, chan_list[0].channumber, chan_count); + lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d", + bsstype, chan_list[0].channumber, chan_count); /* create the fixed part for scan command */ scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); if (scan_cmd == NULL) goto out; + tlv = scan_cmd->tlvbuffer; - if (user_cfg) - memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN); + /* TODO: do we need to scan for a specific BSSID? + memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */ scan_cmd->bsstype = bsstype; /* add TLVs */ - if (user_cfg && user_cfg->ssid_len) - tlv += lbs_scan_add_ssid_tlv(tlv, user_cfg); + if (priv->scan_ssid_len) + tlv += lbs_scan_add_ssid_tlv(priv, tlv); if (chan_list && chan_count) tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count); tlv += lbs_scan_add_rates_tlv(tlv); /* This is the final data we are about to send */ - scan_cmd->tlvbufferlen = tlv - scan_cmd->tlvbuffer; - lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 1+6); + scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd); + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, + sizeof(*scan_cmd)); lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, - scan_cmd->tlvbufferlen); + tlv - scan_cmd->tlvbuffer); + + ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, + le16_to_cpu(scan_cmd->hdr.size), + lbs_ret_80211_scan, 0); - ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0, - CMD_OPTION_WAITFORRSP, 0, scan_cmd); out: kfree(scan_cmd); lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); @@ -530,22 +493,18 @@ out: * update the internal driver scan table * * @param priv A pointer to struct lbs_private structure - * @param puserscanin Pointer to the input configuration for the requested - * scan. + * @param full_scan Do a full-scan (blocking) * * @return 0 or < 0 if error */ -int lbs_scan_networks(struct lbs_private *priv, - const struct lbs_ioctl_user_scan_cfg *user_cfg, - int full_scan) +static int lbs_scan_networks(struct lbs_private *priv, int full_scan) { int ret = -ENOMEM; struct chanscanparamset *chan_list; struct chanscanparamset *curr_chans; int chan_count; - u8 bsstype = CMD_BSS_TYPE_ANY; + uint8_t bsstype = CMD_BSS_TYPE_ANY; int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; - int filteredscan = 0; union iwreq_data wrqu; #ifdef CONFIG_LIBERTAS_DEBUG struct bss_descriptor *iter; @@ -553,8 +512,7 @@ int lbs_scan_networks(struct lbs_private *priv, DECLARE_MAC_BUF(mac); #endif - lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", - full_scan); + lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan); /* Cancel any partial outstanding partial scans if this scan * is a full scan. @@ -562,30 +520,27 @@ int lbs_scan_networks(struct lbs_private *priv, if (full_scan && delayed_work_pending(&priv->scan_work)) cancel_delayed_work(&priv->scan_work); - /* Determine same scan parameters */ + /* User-specified bsstype or channel list + TODO: this can be implemented if some user-space application + need the feature. Formerly, it was accessible from debugfs, + but then nowhere used. if (user_cfg) { if (user_cfg->bsstype) - bsstype = user_cfg->bsstype; - if (compare_ether_addr(user_cfg->bssid, &zeromac[0]) != 0) { - numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN; - filteredscan = 1; - } - } - lbs_deb_scan("numchannels %d, bsstype %d, " - "filteredscan %d\n", - numchannels, bsstype, filteredscan); + bsstype = user_cfg->bsstype; + } */ + + lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype); /* Create list of channels to scan */ chan_list = kzalloc(sizeof(struct chanscanparamset) * - LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); + LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); if (!chan_list) { lbs_pr_alert("SCAN: chan_list empty\n"); goto out; } /* We want to scan all channels */ - chan_count = lbs_scan_create_channel_list(priv, chan_list, - filteredscan); + chan_count = lbs_scan_create_channel_list(priv, chan_list); netif_stop_queue(priv->dev); netif_carrier_off(priv->dev); @@ -595,13 +550,13 @@ int lbs_scan_networks(struct lbs_private *priv, } /* Prepare to continue an interrupted scan */ - lbs_deb_scan("chan_count %d, last_scanned_channel %d\n", - chan_count, priv->last_scanned_channel); + lbs_deb_scan("chan_count %d, scan_channel %d\n", + chan_count, priv->scan_channel); curr_chans = chan_list; /* advance channel list by already-scanned-channels */ - if (priv->last_scanned_channel > 0) { - curr_chans += priv->last_scanned_channel; - chan_count -= priv->last_scanned_channel; + if (priv->scan_channel > 0) { + curr_chans += priv->scan_channel; + chan_count -= priv->scan_channel; } /* Send scan command(s) @@ -612,9 +567,9 @@ int lbs_scan_networks(struct lbs_private *priv, while (chan_count) { int to_scan = min(numchannels, chan_count); lbs_deb_scan("scanning %d of %d channels\n", - to_scan, chan_count); + to_scan, chan_count); ret = lbs_do_scan(priv, bsstype, curr_chans, - to_scan, user_cfg); + to_scan); if (ret) { lbs_pr_err("SCAN_CMD failed\n"); goto out2; @@ -623,17 +578,16 @@ int lbs_scan_networks(struct lbs_private *priv, chan_count -= to_scan; /* somehow schedule the next part of the scan */ - if (chan_count && - !full_scan && + if (chan_count && !full_scan && !priv->surpriseremoved) { /* -1 marks just that we're currently scanning */ - if (priv->last_scanned_channel < 0) - priv->last_scanned_channel = to_scan; + if (priv->scan_channel < 0) + priv->scan_channel = to_scan; else - priv->last_scanned_channel += to_scan; + priv->scan_channel += to_scan; cancel_delayed_work(&priv->scan_work); queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(300)); + msecs_to_jiffies(300)); /* skip over GIWSCAN event */ goto out; } @@ -648,13 +602,13 @@ int lbs_scan_networks(struct lbs_private *priv, lbs_deb_scan("scan table:\n"); list_for_each_entry(iter, &priv->network_list, list) lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n", - i++, print_mac(mac, iter->bssid), (s32) iter->rssi, - escape_essid(iter->ssid, iter->ssid_len)); + i++, print_mac(mac, iter->bssid), iter->rssi, + escape_essid(iter->ssid, iter->ssid_len)); mutex_unlock(&priv->lock); #endif out2: - priv->last_scanned_channel = 0; + priv->scan_channel = 0; out: if (priv->connect_status == LBS_CONNECTED) { @@ -676,6 +630,17 @@ out: +void lbs_scan_worker(struct work_struct *work) +{ + struct lbs_private *priv = + container_of(work, struct lbs_private, scan_work.work); + + lbs_deb_enter(LBS_DEB_SCAN); + lbs_scan_networks(priv, 0); + lbs_deb_leave(LBS_DEB_SCAN); +} + + /*********************************************************************/ /* */ /* Result interpretation */ @@ -694,7 +659,7 @@ out: * @return 0 or -1 */ static int lbs_process_bss(struct bss_descriptor *bss, - u8 ** pbeaconinfo, int *bytesleft) + uint8_t **pbeaconinfo, int *bytesleft) { struct ieeetypes_fhparamset *pFH; struct ieeetypes_dsparamset *pDS; @@ -702,9 +667,9 @@ static int lbs_process_bss(struct bss_descriptor *bss, struct ieeetypes_ibssparamset *pibss; DECLARE_MAC_BUF(mac); struct ieeetypes_countryinfoset *pcountryinfo; - u8 *pos, *end, *p; - u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; - u16 beaconsize = 0; + uint8_t *pos, *end, *p; + uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; + uint16_t beaconsize = 0; int ret; lbs_deb_enter(LBS_DEB_SCAN); @@ -776,12 +741,11 @@ static int lbs_process_bss(struct bss_descriptor *bss, /* process variable IE */ while (pos <= end - 2) { - struct ieee80211_info_element * elem = - (struct ieee80211_info_element *) pos; + struct ieee80211_info_element * elem = (void *)pos; if (pos + elem->len > end) { lbs_deb_scan("process_bss: error in processing IE, " - "bytes left < IE length\n"); + "bytes left < IE length\n"); break; } @@ -795,7 +759,7 @@ static int lbs_process_bss(struct bss_descriptor *bss, break; case MFIE_TYPE_RATES: - n_basic_rates = min_t(u8, MAX_RATES, elem->len); + n_basic_rates = min_t(uint8_t, MAX_RATES, elem->len); memcpy(bss->rates, elem->data, n_basic_rates); got_basic_rates = 1; lbs_deb_scan("got RATES IE\n"); @@ -836,19 +800,16 @@ static int lbs_process_bss(struct bss_descriptor *bss, lbs_deb_scan("got COUNTRY IE\n"); if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) || pcountryinfo->len > 254) { - lbs_deb_scan("process_bss: 11D- Err " - "CountryInfo len %d, min %zd, max 254\n", - pcountryinfo->len, - sizeof(pcountryinfo->countrycode)); + lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n", + pcountryinfo->len, sizeof(pcountryinfo->countrycode)); ret = -1; goto done; } - memcpy(&bss->countryinfo, - pcountryinfo, pcountryinfo->len + 2); + memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", - (u8 *) pcountryinfo, - (u32) (pcountryinfo->len + 2)); + (uint8_t *) pcountryinfo, + (int) (pcountryinfo->len + 2)); break; case MFIE_TYPE_RATES_EX: @@ -872,26 +833,19 @@ static int lbs_process_bss(struct bss_descriptor *bss, case MFIE_TYPE_GENERIC: if (elem->len >= 4 && - elem->data[0] == 0x00 && - elem->data[1] == 0x50 && - elem->data[2] == 0xf2 && - elem->data[3] == 0x01) { - bss->wpa_ie_len = min(elem->len + 2, - MAX_WPA_IE_LEN); + elem->data[0] == 0x00 && elem->data[1] == 0x50 && + elem->data[2] == 0xf2 && elem->data[3] == 0x01) { + bss->wpa_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); memcpy(bss->wpa_ie, elem, bss->wpa_ie_len); lbs_deb_scan("got WPA IE\n"); - lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, - elem->len); + lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, elem->len); } else if (elem->len >= MARVELL_MESH_IE_LENGTH && - elem->data[0] == 0x00 && - elem->data[1] == 0x50 && - elem->data[2] == 0x43 && - elem->data[3] == 0x04) { + elem->data[0] == 0x00 && elem->data[1] == 0x50 && + elem->data[2] == 0x43 && elem->data[3] == 0x04) { lbs_deb_scan("got mesh IE\n"); bss->mesh = 1; } else { - lbs_deb_scan("got generiec IE: " - "%02x:%02x:%02x:%02x, len %d\n", + lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n", elem->data[0], elem->data[1], elem->data[2], elem->data[3], elem->len); @@ -903,12 +857,12 @@ static int lbs_process_bss(struct bss_descriptor *bss, bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); memcpy(bss->rsn_ie, elem, bss->rsn_ie_len); lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", - bss->rsn_ie, elem->len); + bss->rsn_ie, elem->len); break; default: lbs_deb_scan("got IE 0x%04x, len %d\n", - elem->id, elem->len); + elem->id, elem->len); break; } @@ -938,18 +892,17 @@ done: * @return index in BSSID list, or error return code (< 0) */ struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv, - u8 * bssid, u8 mode) + uint8_t *bssid, uint8_t mode) { - struct bss_descriptor * iter_bss; - struct bss_descriptor * found_bss = NULL; + struct bss_descriptor *iter_bss; + struct bss_descriptor *found_bss = NULL; lbs_deb_enter(LBS_DEB_SCAN); if (!bssid) goto out; - lbs_deb_hex(LBS_DEB_SCAN, "looking for", - bssid, ETH_ALEN); + lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN); /* Look through the scan table for a compatible match. The loop will * continue past a matched bssid that is not compatible in case there @@ -991,10 +944,11 @@ out: * @return index in BSSID list */ struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv, - u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, - int channel) + uint8_t *ssid, uint8_t ssid_len, + uint8_t *bssid, uint8_t mode, + int channel) { - u8 bestrssi = 0; + u32 bestrssi = 0; struct bss_descriptor * iter_bss = NULL; struct bss_descriptor * found_bss = NULL; struct bss_descriptor * tmp_oldest = NULL; @@ -1009,7 +963,7 @@ struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv, tmp_oldest = iter_bss; if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, - ssid, ssid_len) != 0) + ssid, ssid_len) != 0) continue; /* ssid doesn't match */ if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) continue; /* bssid doesn't match */ @@ -1059,13 +1013,12 @@ out: * * @return index in BSSID list */ -static struct bss_descriptor *lbs_find_best_ssid_in_list( - struct lbs_private *priv, - u8 mode) +static struct bss_descriptor *lbs_find_best_ssid_in_list(struct lbs_private *priv, + uint8_t mode) { - u8 bestrssi = 0; - struct bss_descriptor * iter_bss; - struct bss_descriptor * best_bss = NULL; + uint8_t bestrssi = 0; + struct bss_descriptor *iter_bss; + struct bss_descriptor *best_bss = NULL; lbs_deb_enter(LBS_DEB_SCAN); @@ -1098,7 +1051,7 @@ static struct bss_descriptor *lbs_find_best_ssid_in_list( } /** - * @brief Find the AP with specific ssid in the scan list + * @brief Find the best AP * * Used from association worker. * @@ -1107,15 +1060,17 @@ static struct bss_descriptor *lbs_find_best_ssid_in_list( * * @return 0--success, otherwise--fail */ -int lbs_find_best_network_ssid(struct lbs_private *priv, - u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode) +int lbs_find_best_network_ssid(struct lbs_private *priv, uint8_t *out_ssid, + uint8_t *out_ssid_len, uint8_t preferred_mode, + uint8_t *out_mode) { int ret = -1; - struct bss_descriptor * found; + struct bss_descriptor *found; lbs_deb_enter(LBS_DEB_SCAN); - lbs_scan_networks(priv, NULL, 1); + priv->scan_ssid_len = 0; + lbs_scan_networks(priv, 1); if (priv->surpriseremoved) goto out; @@ -1141,29 +1096,24 @@ out: * @param priv A pointer to struct lbs_private structure * @param ssid A pointer to the SSID to scan for * @param ssid_len Length of the SSID - * @param clear_ssid Should existing scan results with this SSID - * be cleared? * * @return 0-success, otherwise fail */ -int lbs_send_specific_ssid_scan(struct lbs_private *priv, - u8 *ssid, u8 ssid_len, u8 clear_ssid) +int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, + uint8_t ssid_len) { - struct lbs_ioctl_user_scan_cfg scancfg; int ret = 0; - lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d", - escape_essid(ssid, ssid_len), clear_ssid); + lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n", + escape_essid(ssid, ssid_len)); if (!ssid_len) goto out; - memset(&scancfg, 0x00, sizeof(scancfg)); - memcpy(scancfg.ssid, ssid, ssid_len); - scancfg.ssid_len = ssid_len; - scancfg.clear_ssid = clear_ssid; + memcpy(priv->scan_ssid, ssid, ssid_len); + priv->scan_ssid_len = ssid_len; - lbs_scan_networks(priv, &scancfg, 1); + lbs_scan_networks(priv, 1); if (priv->surpriseremoved) { ret = -1; goto out; @@ -1187,17 +1137,17 @@ out: #define MAX_CUSTOM_LEN 64 static inline char *lbs_translate_scan(struct lbs_private *priv, - char *start, char *stop, - struct bss_descriptor *bss) + char *start, char *stop, + struct bss_descriptor *bss) { struct chan_freq_power *cfp; char *current_val; /* For rates */ struct iw_event iwe; /* Temporary buffer */ int j; -#define PERFECT_RSSI ((u8)50) -#define WORST_RSSI ((u8)0) -#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) - u8 rssi; +#define PERFECT_RSSI ((uint8_t)50) +#define WORST_RSSI ((uint8_t)0) +#define RSSI_DIFF ((uint8_t)(PERFECT_RSSI - WORST_RSSI)) + uint8_t rssi; lbs_deb_enter(LBS_DEB_SCAN); @@ -1217,7 +1167,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, /* SSID */ iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE); + iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE); start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); /* Mode */ @@ -1238,28 +1188,26 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; iwe.u.qual.qual = - (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * - (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / - (RSSI_DIFF * RSSI_DIFF); + (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * + (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / + (RSSI_DIFF * RSSI_DIFF); if (iwe.u.qual.qual > 100) iwe.u.qual.qual = 100; if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; } else { - iwe.u.qual.noise = - CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); + iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); } /* Locally created ad-hoc BSSs won't have beacons if this is the * only station in the adhoc network; so get signal strength * from receive statistics. */ - if ((priv->mode == IW_MODE_ADHOC) - && priv->adhoccreate + if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate && !lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - bss->ssid, bss->ssid_len)) { + priv->curbssparams.ssid_len, + bss->ssid, bss->ssid_len)) { int snr, nf; snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; @@ -1290,14 +1238,13 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); } - if ((bss->mode == IW_MODE_ADHOC) + if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate && !lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - bss->ssid, bss->ssid_len) - && priv->adhoccreate) { + priv->curbssparams.ssid_len, + bss->ssid, bss->ssid_len)) { iwe.u.bitrate.value = 22 * 500000; current_val = iwe_stream_add_value(start, current_val, - stop, &iwe, IW_EV_PARAM_LEN); + stop, &iwe, IW_EV_PARAM_LEN); } /* Check if we added any event */ if((current_val - start) > IW_EV_LCP_LEN) @@ -1326,8 +1273,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, char *p = custom; iwe.cmd = IWEVCUSTOM; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "mesh-type: olpc"); + p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); iwe.u.data.length = p - custom; if (iwe.u.data.length) start = iwe_stream_add_point(start, stop, &iwe, custom); @@ -1350,39 +1296,49 @@ out: * @return 0 --success, otherwise fail */ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_param *wrqu, char *extra) + union iwreq_data *wrqu, char *extra) { struct lbs_private *priv = dev->priv; + int ret = 0; - lbs_deb_enter(LBS_DEB_SCAN); + lbs_deb_enter(LBS_DEB_WEXT); - if (!netif_running(dev)) - return -ENETDOWN; + if (!netif_running(dev)) { + ret = -ENETDOWN; + goto out; + } /* mac80211 does this: struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_IF_TYPE_xxx) - return -EOPNOTSUPP; + if (sdata->type != IEEE80211_IF_TYPE_xxx) { + ret = -EOPNOTSUPP; + goto out; + } + */ if (wrqu->data.length == sizeof(struct iw_scan_req) && wrqu->data.flags & IW_SCAN_THIS_ESSID) { - req = (struct iw_scan_req *)extra; - ssid = req->essid; - ssid_len = req->essid_len; + struct iw_scan_req *req = (struct iw_scan_req *)extra; + priv->scan_ssid_len = req->essid_len; + memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); + lbs_deb_wext("set_scan, essid '%s'\n", + escape_essid(priv->scan_ssid, priv->scan_ssid_len)); + } else { + priv->scan_ssid_len = 0; } - */ if (!delayed_work_pending(&priv->scan_work)) queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(50)); + msecs_to_jiffies(50)); /* set marker that currently a scan is taking place */ - priv->last_scanned_channel = -1; + priv->scan_channel = -1; if (priv->surpriseremoved) - return -EIO; + ret = -EIO; - lbs_deb_leave(LBS_DEB_SCAN); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } @@ -1397,31 +1353,30 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, * @return 0 --success, otherwise fail */ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) + struct iw_point *dwrq, char *extra) { #define SCAN_ITEM_SIZE 128 struct lbs_private *priv = dev->priv; int err = 0; char *ev = extra; char *stop = ev + dwrq->length; - struct bss_descriptor * iter_bss; - struct bss_descriptor * safe; + struct bss_descriptor *iter_bss; + struct bss_descriptor *safe; - lbs_deb_enter(LBS_DEB_SCAN); + lbs_deb_enter(LBS_DEB_WEXT); /* iwlist should wait until the current scan is finished */ - if (priv->last_scanned_channel) + if (priv->scan_channel) return -EAGAIN; /* Update RSSI if current BSS is a locally created ad-hoc BSS */ - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) { + if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, - CMD_OPTION_WAITFORRSP, 0, NULL); - } + CMD_OPTION_WAITFORRSP, 0, NULL); mutex_lock(&priv->lock); list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { - char * next_ev; + char *next_ev; unsigned long stale_time; if (stop - ev < SCAN_ITEM_SIZE) { @@ -1436,8 +1391,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, /* Prune old an old scan result */ stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; if (time_after(jiffies, stale_time)) { - list_move_tail (&iter_bss->list, - &priv->network_free_list); + list_move_tail(&iter_bss->list, &priv->network_free_list); clear_bss_descriptor(iter_bss); continue; } @@ -1453,7 +1407,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, dwrq->length = (ev - extra); dwrq->flags = 0; - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", err); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err); return err; } @@ -1468,44 +1422,6 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, /** - * @brief Prepare a scan command to be sent to the firmware - * - * Called via lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, ...) - * from cmd.c - * - * Sends a fixed length data part (specifying the BSS type and BSSID filters) - * as well as a variable number/length of TLVs to the firmware. - * - * @param priv A pointer to struct lbs_private structure - * @param cmd A pointer to cmd_ds_command structure to be sent to - * firmware with the cmd_DS_801_11_SCAN structure - * @param pdata_buf Void pointer cast of a lbs_scan_cmd_config struct used - * to set the fields/TLVs for the command sent to firmware - * - * @return 0 or -1 - */ -int lbs_cmd_80211_scan(struct lbs_private *priv, - struct cmd_ds_command *cmd, void *pdata_buf) -{ - struct cmd_ds_802_11_scan *pscan = &cmd->params.scan; - struct lbs_scan_cmd_config *pscancfg = pdata_buf; - - lbs_deb_enter(LBS_DEB_SCAN); - - /* Set fixed field variables in scan command */ - pscan->bsstype = pscancfg->bsstype; - memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN); - memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen); - - /* size is equal to the sizeof(fixed portions) + the TLV len + header */ - cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN - + pscancfg->tlvbufferlen + S_DS_GEN); - - lbs_deb_leave(LBS_DEB_SCAN); - return 0; -} - -/** * @brief This function handles the command response of scan * * Called from handle_cmd_response() in cmdrespc. @@ -1531,13 +1447,14 @@ int lbs_cmd_80211_scan(struct lbs_private *priv, * * @return 0 or -1 */ -int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) +static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, + struct cmd_header *resp) { - struct cmd_ds_802_11_scan_rsp *pscan; - struct bss_descriptor * iter_bss; - struct bss_descriptor * safe; - u8 *pbssinfo; - u16 scanrespsize; + struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; + struct bss_descriptor *iter_bss; + struct bss_descriptor *safe; + uint8_t *bssinfo; + uint16_t scanrespsize; int bytesleft; int idx; int tlvbufsize; @@ -1554,48 +1471,45 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) clear_bss_descriptor(iter_bss); } - pscan = &resp->params.scanresp; - - if (pscan->nr_sets > MAX_NETWORK_COUNT) { - lbs_deb_scan( - "SCAN_RESP: too many scan results (%d, max %d)!!\n", - pscan->nr_sets, MAX_NETWORK_COUNT); + if (scanresp->nr_sets > MAX_NETWORK_COUNT) { + lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n", + scanresp->nr_sets, MAX_NETWORK_COUNT); ret = -1; goto done; } - bytesleft = le16_to_cpu(pscan->bssdescriptsize); + bytesleft = le16_to_cpu(scanresp->bssdescriptsize); lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); scanrespsize = le16_to_cpu(resp->size); - lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets); + lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets); - pbssinfo = pscan->bssdesc_and_tlvbuffer; + bssinfo = scanresp->bssdesc_and_tlvbuffer; /* The size of the TLV buffer is equal to the entire command response * size (scanrespsize) minus the fixed fields (sizeof()'s), the * BSS Descriptions (bssdescriptsize as bytesLef) and the command * response header (S_DS_GEN) */ - tlvbufsize = scanrespsize - (bytesleft + sizeof(pscan->bssdescriptsize) - + sizeof(pscan->nr_sets) + tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize) + + sizeof(scanresp->nr_sets) + S_DS_GEN); /* - * Process each scan response returned (pscan->nr_sets). Save + * Process each scan response returned (scanresp->nr_sets). Save * the information in the newbssentry and then insert into the * driver scan table either as an update to an existing entry * or as an addition at the end of the table */ - for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) { + for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) { struct bss_descriptor new; - struct bss_descriptor * found = NULL; - struct bss_descriptor * oldest = NULL; + struct bss_descriptor *found = NULL; + struct bss_descriptor *oldest = NULL; DECLARE_MAC_BUF(mac); /* Process the data fields and IEs returned for this BSS */ memset(&new, 0, sizeof (struct bss_descriptor)); - if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) { + if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) { /* error parsing the scan response, skipped */ lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); continue; @@ -1630,8 +1544,7 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) continue; } - lbs_deb_scan("SCAN_RESP: BSSID %s\n", - print_mac(mac, new.bssid)); + lbs_deb_scan("SCAN_RESP: BSSID %s\n", print_mac(mac, new.bssid)); /* Copy the locally created newbssentry to the scan table */ memcpy(found, &new, offsetof(struct bss_descriptor, list)); diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index 319f70dde35..b50cf1415e0 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h @@ -12,116 +12,19 @@ /** * @brief Maximum number of channels that can be sent in a setuserscan ioctl - * - * @sa lbs_ioctl_user_scan_cfg */ #define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 -//! Infrastructure BSS scan type in lbs_scan_cmd_config +//! Infrastructure BSS scan type in cmd_ds_802_11_scan #define LBS_SCAN_BSS_TYPE_BSS 1 -//! Adhoc BSS scan type in lbs_scan_cmd_config +//! Adhoc BSS scan type in cmd_ds_802_11_scan #define LBS_SCAN_BSS_TYPE_IBSS 2 -//! Adhoc or Infrastructure BSS scan type in lbs_scan_cmd_config, no filter +//! Adhoc or Infrastructure BSS scan type in cmd_ds_802_11_scan, no filter #define LBS_SCAN_BSS_TYPE_ANY 3 /** - * @brief Structure used internally in the wlan driver to configure a scan. - * - * Sent to the command processing module to configure the firmware - * scan command prepared by lbs_cmd_80211_scan. - * - * @sa lbs_scan_networks - * - */ -struct lbs_scan_cmd_config { - /** - * @brief BSS type to be sent in the firmware command - * - * Field can be used to restrict the types of networks returned in the - * scan. valid settings are: - * - * - LBS_SCAN_BSS_TYPE_BSS (infrastructure) - * - LBS_SCAN_BSS_TYPE_IBSS (adhoc) - * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) - */ - u8 bsstype; - - /** - * @brief Specific BSSID used to filter scan results in the firmware - */ - u8 bssid[ETH_ALEN]; - - /** - * @brief length of TLVs sent in command starting at tlvBuffer - */ - int tlvbufferlen; - - /** - * @brief SSID TLV(s) and ChanList TLVs to be sent in the firmware command - * - * @sa TLV_TYPE_CHANLIST, mrvlietypes_chanlistparamset_t - * @sa TLV_TYPE_SSID, mrvlietypes_ssidparamset_t - */ - u8 tlvbuffer[1]; //!< SSID TLV(s) and ChanList TLVs are stored here -}; - -/** - * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg - * - * Multiple instances of this structure are included in the IOCTL command - * to configure a instance of a scan on the specific channel. - */ -struct lbs_ioctl_user_scan_chan { - u8 channumber; //!< channel Number to scan - u8 radiotype; //!< Radio type: 'B/G' band = 0, 'A' band = 1 - u8 scantype; //!< Scan type: Active = 0, Passive = 1 - u16 scantime; //!< Scan duration in milliseconds; if 0 default used -}; - -/** - * @brief IOCTL input structure to configure an immediate scan cmd to firmware - * - * Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl. Specifies - * a number of parameters to be used in general for the scan as well - * as a channel list (lbs_ioctl_user_scan_chan) for each scan period - * desired. - * - * @sa lbs_set_user_scan_ioctl - */ -struct lbs_ioctl_user_scan_cfg { - /** - * @brief BSS type to be sent in the firmware command - * - * Field can be used to restrict the types of networks returned in the - * scan. valid settings are: - * - * - LBS_SCAN_BSS_TYPE_BSS (infrastructure) - * - LBS_SCAN_BSS_TYPE_IBSS (adhoc) - * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) - */ - u8 bsstype; - - /** - * @brief BSSID filter sent in the firmware command to limit the results - */ - u8 bssid[ETH_ALEN]; - - /* Clear existing scan results matching this BSSID */ - u8 clear_bssid; - - /** - * @brief SSID filter sent in the firmware command to limit the results - */ - char ssid[IW_ESSID_MAX_SIZE]; - u8 ssid_len; - - /* Clear existing scan results matching this SSID */ - u8 clear_ssid; -}; - -/** * @brief Structure used to store information for each beacon/probe response */ struct bss_descriptor { @@ -131,14 +34,9 @@ struct bss_descriptor { u8 ssid_len; u16 capability; - - /* receive signal strength in dBm */ - long rssi; - + u32 rssi; u32 channel; - u16 beaconperiod; - u32 atimwindow; /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ @@ -177,28 +75,12 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode); int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, - u8 ssid_len, u8 clear_ssid); - -int lbs_cmd_80211_scan(struct lbs_private *priv, - struct cmd_ds_command *cmd, - void *pdata_buf); - -int lbs_ret_80211_scan(struct lbs_private *priv, - struct cmd_ds_command *resp); - -int lbs_scan_networks(struct lbs_private *priv, - const struct lbs_ioctl_user_scan_cfg *puserscanin, - int full_scan); - -struct ifreq; + u8 ssid_len); -struct iw_point; -struct iw_param; -struct iw_request_info; int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra); int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra); + union iwreq_data *wrqu, char *extra); void lbs_scan_worker(struct work_struct *work); diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index 00d95f75bd8..77f1f9525b8 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -151,7 +151,7 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; - if (priv->monitormode != LBS_MONITOR_OFF) { + if (priv->monitormode) { /* Keep the skb to echo it back once Tx feedback is received from FW */ skb_orphan(skb); @@ -186,8 +186,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv) int txfail; int try_count; - if (priv->monitormode == LBS_MONITOR_OFF || - priv->currenttxskb == NULL) + if (!priv->monitormode || priv->currenttxskb == NULL) return; radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data; diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index f0d57958b34..4031be42086 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -239,4 +239,17 @@ struct mrvlietypes_ledgpio { struct led_pin ledpin[1]; } __attribute__ ((packed)); +struct led_bhv { + uint8_t firmwarestate; + uint8_t led; + uint8_t ledstate; + uint8_t ledarg; +} __attribute__ ((packed)); + + +struct mrvlietypes_ledbhv { + struct mrvlietypesheader header; + struct led_bhv ledbhv[1]; +} __attribute__ ((packed)); + #endif diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index e8bfc26b10a..738142e802d 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -579,6 +579,9 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, range->num_bitrates); range->num_frequency = 0; + + range->scan_capa = IW_SCAN_CAPA_ESSID; + if (priv->enable11d && (priv->connect_status == LBS_CONNECTED || priv->mesh_connect_status == LBS_CONNECTED)) { @@ -602,7 +605,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, lbs_deb_wext("chan_no %d\n", chan_no); range->freq[range->num_frequency].i = (long)chan_no; range->freq[range->num_frequency].m = - (long)lbs_chan_2_freq(chan_no, band) * 100000; + (long)lbs_chan_2_freq(chan_no) * 100000; range->freq[range->num_frequency].e = 1; range->num_frequency++; } @@ -653,13 +656,10 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, range->num_encoding_sizes = 2; range->max_encoding_tokens = 4; - range->min_pmp = 1000000; - range->max_pmp = 120000000; - range->min_pmt = 1000; - range->max_pmt = 1000000; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; + /* + * Right now we support only "iwconfig ethX power on|off" + */ + range->pm_capa = IW_POWER_ON; /* * Minimum version we recommend @@ -781,21 +781,14 @@ static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { struct lbs_private *priv = dev->priv; - int mode; lbs_deb_enter(LBS_DEB_WEXT); - mode = priv->psmode; - - if ((vwrq->disabled = (mode == LBS802_11POWERMODECAM)) - || priv->connect_status == LBS_DISCONNECTED) - { - goto out; - } - vwrq->value = 0; + vwrq->flags = 0; + vwrq->disabled = priv->psmode == LBS802_11POWERMODECAM + || priv->connect_status == LBS_DISCONNECTED; -out: lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -817,6 +810,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) int stats_valid = 0; u8 rssi; u32 tx_retries; + struct cmd_ds_802_11_get_log log; lbs_deb_enter(LBS_DEB_WEXT); @@ -860,7 +854,11 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) /* Quality by TX errors */ priv->wstats.discard.retries = priv->stats.tx_errors; - tx_retries = le32_to_cpu(priv->logmsg.retry); + memset(&log, 0, sizeof(log)); + log.hdr.size = cpu_to_le16(sizeof(log)); + lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log); + + tx_retries = le32_to_cpu(log.retry); if (tx_retries > 75) tx_qual = (90 - tx_retries) * POOR / 15; @@ -876,10 +874,9 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; quality = min(quality, tx_qual); - priv->wstats.discard.code = le32_to_cpu(priv->logmsg.wepundecryptable); - priv->wstats.discard.fragment = le32_to_cpu(priv->logmsg.rxfrag); + priv->wstats.discard.code = le32_to_cpu(log.wepundecryptable); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = le32_to_cpu(priv->logmsg.ackfailure); + priv->wstats.discard.misc = le32_to_cpu(log.ackfailure); /* Calculate quality */ priv->wstats.qual.qual = min_t(u8, quality, 100); @@ -889,8 +886,6 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) /* update stats asynchronously for future calls */ lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 0, 0, NULL); - lbs_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, - 0, 0, NULL); out: if (!stats_valid) { priv->wstats.miss.beacon = 0; diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h index a563d9a231b..f0f439a6ab4 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h @@ -15,8 +15,6 @@ struct lbs_ioctl_regrdwr { u32 value; }; -#define LBS_MONITOR_OFF 0 - extern struct iw_handler_def lbs_handler_def; extern struct iw_handler_def mesh_handler_def; |