int ath6kl_wmi_set_customer_scan_cmd(struct ath6kl_vif *vif) { //athcfg_wcmd_sta_t *cmd; int ret; int left; set_bit(SONY_WMI_SCAN, &vif->flag); //printk("%s[%d]Start sony scan,vif=0x%x\n\r",__func__,__LINE__,(int*)vif); ret = ath6kl_wmi_bssfilter_cmd( vif, ALL_BSS_FILTER, 0); if (ret) { return ret; } total_bss_info = 0; memset(&scaninfor_db[0],0x00,sizeof(scaninfor_db)); ret = ath6kl_wmi_startscan_cmd(vif, WMI_LONG_SCAN, 0, false, 0, 0, 0, NULL); left = wait_event_interruptible_timeout(vif->event_wq, !test_bit(SONY_WMI_SCAN, &vif->flag), WMI_TIMEOUT*10); ath6kl_wmi_bssfilter_cmd(vif, NONE_BSS_FILTER, 0); return ret; }
int ath6kl_wmi_get_customer_stainfo_cmd(struct ath6kl_vif *vif, athcfg_wcmd_sta_t *val) { struct sk_buff *skb; athcfg_wcmd_sta_t *cmd; int ret; int left; skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); if (!skb) return -ENOMEM; cmd = (athcfg_wcmd_sta_t *) skb->data; set_bit(SONY_WMI_UPDATE, &vif->flag); ret = ath6kl_wmi_cmd_send(vif, skb, WMI_GET_CUSTOM_STAINFO, NO_SYNC_WMIFLAG); left = wait_event_interruptible_timeout(vif->event_wq, !test_bit(SONY_WMI_UPDATE, &vif->flag), WMI_TIMEOUT); if (left == 0) return -ETIMEDOUT; //get beacon RSSI if(test_bit(CONNECTED, &vif->flag)) { if(vif->nw_type != AP_NETWORK) { set_bit(SONY_WMI_UPDATE, &vif->flag); //printk("%s[%d]Start get beacon rssi,vif=0x%x\n\r",__func__,__LINE__,(int*)vif); ret = ath6kl_wmi_bssfilter_cmd( vif, CURRENT_BSS_FILTER, 0); if (ret) { return ret; } left = wait_event_interruptible_timeout(vif->event_wq, !test_bit(SONY_WMI_UPDATE, &vif->flag), WMI_TIMEOUT*10); ath6kl_wmi_bssfilter_cmd(vif, NONE_BSS_FILTER, 0); } } //printk("%s[%d]vif->nw_type=%d\n\r",__func__,__LINE__,vif->nw_type); memcpy(val ,&stainfo_private,sizeof(athcfg_wcmd_sta_t)); return ret; }
int ath6kl_wmi_get_customer_scan_time_cmd(struct ath6kl_vif *vif,athcfg_wcmd_scantime_t *val) { struct sk_buff *skb; athcfg_wcmd_sta_t *cmd; int ret; int left; unsigned long start_scan_timestamp; unsigned long end_scan_timestamp; unsigned long scan_time_msec; skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); if (!skb) return -ENOMEM; cmd = (athcfg_wcmd_sta_t *) skb->data; //set_bit(SONY_WMI_UPDATE, &vif->flag); set_bit(SONY_WMI_SCAN, &vif->flag); // printk("%s[%d]Start sony scan\n\r",__func__,__LINE__); ret = ath6kl_wmi_bssfilter_cmd( vif, ALL_BSS_FILTER, 0); if (ret) { return ret; } start_scan_timestamp = jiffies; ret = ath6kl_wmi_startscan_cmd(vif, WMI_LONG_SCAN, 0, false, 0, 0, 0, NULL); left = wait_event_interruptible_timeout(vif->event_wq, !test_bit(SONY_WMI_SCAN, &vif->flag), WMI_TIMEOUT*10); end_scan_timestamp = jiffies; scan_time_msec = jiffies_to_msecs(end_scan_timestamp-start_scan_timestamp); if(val) val->scan_time = scan_time_msec; //printk("%s[%d]scan_time_msec = %d msec \n\r",__func__,__LINE__,scan_time_msec); ath6kl_wmi_bssfilter_cmd(vif, NONE_BSS_FILTER, 0); //printk("%s[%d]\n\r",__func__,__LINE__); //memcpy(val ,&stainfo_private,sizeof(athcfg_wcmd_sta_t)); return ret; }
void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, u16 listen_int, u16 beacon_int, enum network_type net_type, u8 beacon_ie_len, u8 assoc_req_len, u8 assoc_resp_len, u8 *assoc_info) { struct ath6kl *ar = vif->ar; ath6kl_cfg80211_connect_event(vif, channel, bssid, listen_int, beacon_int, net_type, beacon_ie_len, assoc_req_len, assoc_resp_len, assoc_info); memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; if ((vif->nw_type == INFRA_NETWORK)) ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, ar->listen_intvl_t, ar->listen_intvl_b); netif_wake_queue(vif->ndev); /* Update connect & link status atomically */ spin_lock_bh(&vif->if_lock); set_bit(CONNECTED, &vif->flags); clear_bit(CONNECT_PEND, &vif->flags); netif_carrier_on(vif->ndev); spin_unlock_bh(&vif->if_lock); aggr_reset_state(vif->aggr_cntxt); vif->reconnect_flag = 0; if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { memset(ar->node_map, 0, sizeof(ar->node_map)); ar->node_num = 0; ar->next_ep_id = ENDPOINT_2; } if (!ar->usr_bss_filter) { set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, CURRENT_BSS_FILTER, 0); } }
void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) { struct ath6kl *ar = vif->ar; bool aborted = false; if (status != WMI_SCAN_STATUS_SUCCESS) aborted = true; ath6kl_cfg80211_scan_complete_event(vif, aborted); if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); } ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); }
void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) { struct ath6kl *ar = vif->ar; struct ath6kl_req_key *ik; int res; u8 key_rsc[ATH6KL_KEY_SEQ_LEN]; ik = &ar->ap_mode_bkey; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel); switch (vif->auth_mode) { case NONE_AUTH: if (vif->prwise_crypto == WEP_CRYPT) ath6kl_install_static_wep_keys(vif); if (!ik->valid || ik->key_type != WAPI_CRYPT) break; /* for WAPI, we need to set the delayed group key, continue: */ case WPA_PSK_AUTH: case WPA2_PSK_AUTH: case (WPA_PSK_AUTH | WPA2_PSK_AUTH): if (!ik->valid) break; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for " "the initial group key for AP mode\n"); memset(key_rsc, 0, sizeof(key_rsc)); res = ath6kl_wmi_addkey_cmd( ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, GROUP_USAGE, ik->key_len, key_rsc, ATH6KL_KEY_SEQ_LEN, ik->key, KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); if (res) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed " "addkey failed: %d\n", res); } break; } ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); set_bit(CONNECTED, &vif->flags); netif_carrier_on(vif->ndev); }
static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) { struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); s8 n_channels = 0; u16 *channels = NULL; int ret = 0; if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); ret = ath6kl_wmi_bssfilter_cmd( ar->wmi, (test_bit(CONNECTED, &ar->flag) ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0); if (ret) { ath6kl_err("couldn't set bss filtering\n"); return ret; } } if (request->n_ssids && request->ssids[0].ssid_len) { u8 i; if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) request->n_ssids = MAX_PROBED_SSID_INDEX - 1; for (i = 0; i < request->n_ssids; i++) ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1, SPECIFIC_SSID_FLAG, request->ssids[i].ssid_len, request->ssids[i].ssid); } if (request->ie) { ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { ath6kl_err("failed to set Probe Request appie for " "scan"); return ret; } } /* * Scan only the requested channels if the request specifies a set of * channels. If the list is longer than the target supports, do not * configure the list and instead, scan all available channels. */ if (request->n_channels > 0 && request->n_channels <= WMI_MAX_CHANNELS) { u8 i; n_channels = request->n_channels; channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); if (channels == NULL) { ath6kl_warn("failed to set scan channels, " "scan all channels"); n_channels = 0; } for (i = 0; i < n_channels; i++) channels[i] = request->channels[i]->center_freq; } ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0, false, 0, 0, n_channels, channels); if (ret) ath6kl_err("wmi_startscan_cmd failed\n"); else ar->scan_req = request; kfree(channels); return ret; }
static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { struct ath6kl *ar = ath6kl_priv(dev); int status; ar->sme_state = SME_CONNECTING; if (!ath6kl_cfg80211_ready(ar)) return -EIO; if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { ath6kl_err("destroy in progress\n"); return -EBUSY; } if (test_bit(SKIP_SCAN, &ar->flag) && ((sme->channel && sme->channel->center_freq == 0) || (sme->bssid && is_zero_ether_addr(sme->bssid)))) { ath6kl_err("SkipScan: channel or bssid invalid\n"); return -EINVAL; } if (down_interruptible(&ar->sem)) { ath6kl_err("busy, couldn't get access\n"); return -ERESTARTSYS; } if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { ath6kl_err("busy, destroy in progress\n"); up(&ar->sem); return -EBUSY; } if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) { /* * sleep until the command queue drains */ wait_event_interruptible_timeout(ar->event_wq, ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0, WMI_TIMEOUT); if (signal_pending(current)) { ath6kl_err("cmd queue drain timeout\n"); up(&ar->sem); return -EINTR; } } if (test_bit(CONNECTED, &ar->flag) && ar->ssid_len == sme->ssid_len && !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) { ar->reconnect_flag = true; status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid, ar->ch_hint); up(&ar->sem); if (status) { ath6kl_err("wmi_reconnect_cmd failed\n"); return -EIO; } return 0; } else if (ar->ssid_len == sme->ssid_len && !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) { ath6kl_disconnect(ar); } memset(ar->ssid, 0, sizeof(ar->ssid)); ar->ssid_len = sme->ssid_len; memcpy(ar->ssid, sme->ssid, sme->ssid_len); if (sme->channel) ar->ch_hint = sme->channel->center_freq; memset(ar->req_bssid, 0, sizeof(ar->req_bssid)); if (sme->bssid && !is_broadcast_ether_addr(sme->bssid)) memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid)); ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions); status = ath6kl_set_auth_type(ar, sme->auth_type); if (status) { up(&ar->sem); return status; } if (sme->crypto.n_ciphers_pairwise) ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true); else ath6kl_set_cipher(ar, 0, true); ath6kl_set_cipher(ar, sme->crypto.cipher_group, false); if (sme->crypto.n_akm_suites) ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]); if ((sme->key_len) && (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) { struct ath6kl_key *key = NULL; if (sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) { ath6kl_err("key index %d out of bounds\n", sme->key_idx); up(&ar->sem); return -ENOENT; } key = &ar->keys[sme->key_idx]; key->key_len = sme->key_len; memcpy(key->key, sme->key, key->key_len); key->cipher = ar->prwise_crypto; ar->def_txkey_index = sme->key_idx; ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx, ar->prwise_crypto, GROUP_USAGE | TX_USAGE, key->key_len, NULL, key->key, KEY_OP_INIT_VAL, NULL, NO_SYNC_WMIFLAG); } if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag); if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) { ath6kl_err("couldn't set bss filtering\n"); up(&ar->sem); return -EIO; } } ar->nw_type = ar->next_mode; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: connect called with authmode %d dot11 auth %d" " PW crypto %d PW crypto len %d GRP crypto %d" " GRP crypto len %d channel hint %u\n", __func__, ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto, ar->prwise_crypto_len, ar->grp_crypto, ar->grp_crypto_len, ar->ch_hint); ar->reconnect_flag = 0; status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type, ar->dot11_auth_mode, ar->auth_mode, ar->prwise_crypto, ar->prwise_crypto_len, ar->grp_crypto, ar->grp_crypto_len, ar->ssid_len, ar->ssid, ar->req_bssid, ar->ch_hint, ar->connect_ctrl_flags); up(&ar->sem); if (status == -EINVAL) { memset(ar->ssid, 0, sizeof(ar->ssid)); ar->ssid_len = 0; ath6kl_err("invalid request\n"); return -ENOENT; } else if (status) { ath6kl_err("ath6kl_wmi_connect_cmd failed\n"); return -EIO; } if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) && ((ar->auth_mode == WPA_PSK_AUTH) || (ar->auth_mode == WPA2_PSK_AUTH))) { mod_timer(&ar->disconnect_timer, jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); } ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD; set_bit(CONNECT_PEND, &ar->flag); return 0; }
int ath6kl_wmi_set_customer_testmode_cmd(struct ath6kl_vif *vif, athcfg_wcmd_testmode_t *val) { struct sk_buff *skb; struct WMI_CUSTOMER_TESTMODE_STRUCT *cmd; int ret = 0; bool send_wmi_flag = false; switch(val->operation) { case ATHCFG_WCMD_TESTMODE_BSSID: { if(memcmp(testmode_private.bssid,val->bssid,sizeof(testmode_private.bssid)) != 0) { memcpy(testmode_private.bssid,val->bssid,sizeof(testmode_private.bssid)); send_wmi_flag = true; } //printk("%s[%d] testmode_private.bssid=\"%pM\"\n",__func__,__LINE__,testmode_private.bssid); } break; case ATHCFG_WCMD_TESTMODE_CHAN: { if(testmode_private.chan != val->chan) { testmode_private.chan = val->chan; send_wmi_flag = true; } //printk("%s[%d] testmode_private.chan=%d\n",__func__,__LINE__,testmode_private.chan); } break; case ATHCFG_WCMD_TESTMODE_RX: { if(testmode_private.rx != val->rx) { testmode_private.rx = val->rx; send_wmi_flag = true; } } break; case ATHCFG_WCMD_TESTMODE_ANT: default: printk("%s[%d]Not support\n",__func__,__LINE__); return -1; } //send WMI to target if(send_wmi_flag) { testmode_private.rx = val->rx; skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); if (!skb) return -ENOMEM; cmd = (struct WMI_CUSTOMER_TESTMODE_STRUCT *) skb->data; //transfer to little endian memcpy(cmd->bssid, val->bssid, sizeof(cmd->bssid)); cmd->chan = cpu_to_le32(val->chan); cmd->operation = cpu_to_le16(val->operation); cmd->antenna = val->antenna; cmd->rx = val->rx; cmd->rssi_combined = cpu_to_le32(val->rssi_combined); cmd->rssi0 = cpu_to_le32(val->rssi0); cmd->rssi1 = cpu_to_le32(val->rssi1); cmd->rssi2 = cpu_to_le32(val->rssi2); ret = ath6kl_wmi_cmd_send(vif, skb, WMI_SET_CUSTOM_TESTMODE, NO_SYNC_WMIFLAG); } if(val->operation == ATHCFG_WCMD_TESTMODE_RX) { if(val->rx == 1) { s8 n_channels = 1; u16 *channels = NULL; int i; set_bit(SONY_WMI_TESTMODE_RX, &vif->flag); //set scan param ath6kl_wmi_scanparams_cmd( vif, 0, 0xffff, 0, vif->sc_params.minact_chdwell_time, vif->sc_params.maxact_chdwell_time,//0xffff, 1000,//vif->sc_params.pas_chdwell_time, msec vif->sc_params.short_scan_ratio, (vif->sc_params.scan_ctrl_flags & ~ACTIVE_SCAN_CTRL_FLAGS), //vif->sc_params.scan_ctrl_flags, vif->sc_params.max_dfsch_act_time, vif->sc_params.maxact_scan_per_ssid); //assign request channel channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); if (channels == NULL) { n_channels = 0; } for (i = 0; i < n_channels; i++) { channels[i] = ieee80211_channel_to_frequency_ath6kl((testmode_private.chan == 0 ? 1:testmode_private.chan),IEEE80211_NUM_BANDS); //printk("%s[%d]channels[%d]=%d,testmode_private.chan=%d\n",__func__,__LINE__,i,channels[i],testmode_private.chan); } ret = ath6kl_wmi_bssfilter_cmd( vif, ALL_BSS_FILTER, 0); if (ret) { printk("%s[%d] Fail\n",__func__,__LINE__); goto rx_fail; } ret = ath6kl_wmi_startscan_cmd(vif, WMI_LONG_SCAN, 1, false, 0, 0, n_channels, channels); if (ret) { printk("%s[%d] Fail\n",__func__,__LINE__); goto rx_fail; } rx_fail: kfree(channels); } else { //cancel test mode scan clear_bit(SONY_WMI_TESTMODE_RX, &vif->flag); ath6kl_wmi_scanparams_cmd(vif, vif->sc_params.fg_start_period, vif->sc_params.fg_end_period, vif->sc_params.bg_period, vif->sc_params.minact_chdwell_time, vif->sc_params.maxact_chdwell_time, vif->sc_params.pas_chdwell_time, vif->sc_params.short_scan_ratio, vif->sc_params.scan_ctrl_flags, vif->sc_params.max_dfsch_act_time, vif->sc_params.maxact_scan_per_ssid); } } return ret; }