diff options
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/commands.c')
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/commands.c | 220 |
1 files changed, 135 insertions, 85 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index 4206886b110c..b81f81bd1411 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -173,7 +173,6 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif) goto out; } - vif->bss_status |= QTNF_STATE_AP_START; netif_carrier_on(vif->netdev); out: @@ -181,62 +180,68 @@ out: return ret; } -int qtnf_cmd_send_config_ap(struct qtnf_vif *vif) +int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, + const struct cfg80211_ap_settings *s) { struct sk_buff *cmd_skb; - struct qtnf_bss_config *bss_cfg = &vif->bss_cfg; - struct cfg80211_chan_def *chandef = &vif->mac->chandef; - struct qlink_tlv_channel *qchan; - struct qlink_auth_encr aen; + struct qlink_cmd_config_ap *cmd; + struct qlink_auth_encr *aen; u16 res_code = QLINK_CMD_RESULT_OK; int ret; int i; cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, QLINK_CMD_CONFIG_AP, - sizeof(struct qlink_cmd)); + sizeof(*cmd)); if (unlikely(!cmd_skb)) return -ENOMEM; - qtnf_bus_lock(vif->mac->bus); - - qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid, - bss_cfg->ssid_len); - qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_BCN_PERIOD, - bss_cfg->bcn_period); - qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_DTIM, bss_cfg->dtim); - - qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); - qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); - qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - - sizeof(struct qlink_tlv_hdr)); - qchan->hw_value = cpu_to_le16( - ieee80211_frequency_to_channel(chandef->chan->center_freq)); - - memset(&aen, 0, sizeof(aen)); - aen.auth_type = bss_cfg->auth_type; - aen.privacy = !!bss_cfg->privacy; - aen.mfp = bss_cfg->mfp; - aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions); - aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group); - aen.n_ciphers_pairwise = cpu_to_le32( - bss_cfg->crypto.n_ciphers_pairwise); + cmd = (struct qlink_cmd_config_ap *)cmd_skb->data; + cmd->dtim_period = s->dtim_period; + cmd->beacon_interval = cpu_to_le16(s->beacon_interval); + cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid); + cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout); + cmd->smps_mode = s->smps_mode; + cmd->p2p_ctwindow = s->p2p_ctwindow; + cmd->p2p_opp_ps = s->p2p_opp_ps; + cmd->pbss = s->pbss; + cmd->ht_required = s->ht_required; + cmd->vht_required = s->vht_required; + + aen = &cmd->aen; + aen->auth_type = s->auth_type; + aen->privacy = !!s->privacy; + aen->mfp = 0; + aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions); + aen->cipher_group = cpu_to_le32(s->crypto.cipher_group); + aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise); for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) - aen.ciphers_pairwise[i] = cpu_to_le32( - bss_cfg->crypto.ciphers_pairwise[i]); - aen.n_akm_suites = cpu_to_le32( - bss_cfg->crypto.n_akm_suites); + aen->ciphers_pairwise[i] = + cpu_to_le32(s->crypto.ciphers_pairwise[i]); + aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites); for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) - aen.akm_suites[i] = cpu_to_le32( - bss_cfg->crypto.akm_suites[i]); - aen.control_port = bss_cfg->crypto.control_port; - aen.control_port_no_encrypt = - bss_cfg->crypto.control_port_no_encrypt; - aen.control_port_ethertype = cpu_to_le16(be16_to_cpu( - bss_cfg->crypto.control_port_ethertype)); + aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]); + aen->control_port = s->crypto.control_port; + aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt; + aen->control_port_ethertype = + cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype)); + + if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN) + qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid, + s->ssid_len); - qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen, - sizeof(aen)); + if (cfg80211_chandef_valid(&s->chandef)) { + struct qlink_tlv_chandef *chtlv = + (struct qlink_tlv_chandef *)skb_put(cmd_skb, + sizeof(*chtlv)); + + chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF); + chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) - + sizeof(chtlv->hdr)); + qlink_chandef_cfg2q(&s->chandef, &chtlv->chan); + } + + qtnf_bus_lock(vif->mac->bus); ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); @@ -250,8 +255,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif) goto out; } - vif->bss_status |= QTNF_STATE_AP_CONFIG; - out: qtnf_bus_unlock(vif->mac->bus); return ret; @@ -283,9 +286,6 @@ int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif) goto out; } - vif->bss_status &= ~QTNF_STATE_AP_START; - vif->bss_status &= ~QTNF_STATE_AP_CONFIG; - netif_carrier_off(vif->netdev); out: @@ -975,10 +975,11 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, return -EINVAL; } - pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u\n", + pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u, capab=0x%x\n", hwinfo->fw_ver, hwinfo->mac_bitmap, hwinfo->rd->alpha2[0], hwinfo->rd->alpha2[1], - hwinfo->total_tx_chain, hwinfo->total_rx_chain); + hwinfo->total_tx_chain, hwinfo->total_rx_chain, + hwinfo->hw_capab); return 0; } @@ -2037,11 +2038,11 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif, { struct sk_buff *cmd_skb; struct qlink_cmd_connect *cmd; - struct qtnf_bss_config *bss_cfg = &vif->bss_cfg; - struct qlink_auth_encr aen; + struct qlink_auth_encr *aen; u16 res_code = QLINK_CMD_RESULT_OK; int ret; int i; + u32 connect_flags = 0; cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, QLINK_CMD_CONNECT, @@ -2049,52 +2050,65 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif, if (unlikely(!cmd_skb)) return -ENOMEM; - qtnf_bus_lock(vif->mac->bus); - cmd = (struct qlink_cmd_connect *)cmd_skb->data; - ether_addr_copy(cmd->bssid, bss_cfg->bssid); + ether_addr_copy(cmd->bssid, vif->bssid); + + if (sme->channel) + cmd->channel = cpu_to_le16(sme->channel->hw_value); + else + cmd->channel = 0; + + if ((sme->bg_scan_period > 0) && + (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD)) + cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period); + else if (sme->bg_scan_period == -1) + cmd->bg_scan_period = cpu_to_le16(QTNF_DEFAULT_BG_SCAN_PERIOD); + else + cmd->bg_scan_period = 0; /* disabled */ - if (vif->mac->chandef.chan) - cmd->channel = cpu_to_le16(vif->mac->chandef.chan->hw_value); + if (sme->flags & ASSOC_REQ_DISABLE_HT) + connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; + if (sme->flags & ASSOC_REQ_DISABLE_VHT) + connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; + if (sme->flags & ASSOC_REQ_USE_RRM) + connect_flags |= QLINK_STA_CONNECT_USE_RRM; - cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period); + cmd->flags = cpu_to_le32(connect_flags); - memset(&aen, 0, sizeof(aen)); - aen.auth_type = bss_cfg->auth_type; - aen.privacy = !!bss_cfg->privacy; - aen.mfp = bss_cfg->mfp; - aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions); - aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group); - aen.n_ciphers_pairwise = cpu_to_le32( - bss_cfg->crypto.n_ciphers_pairwise); + aen = &cmd->aen; + aen->auth_type = sme->auth_type; + aen->privacy = !!sme->privacy; + aen->mfp = sme->mfp; + aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); + aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); + aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) - aen.ciphers_pairwise[i] = cpu_to_le32( - bss_cfg->crypto.ciphers_pairwise[i]); + aen->ciphers_pairwise[i] = + cpu_to_le32(sme->crypto.ciphers_pairwise[i]); - aen.n_akm_suites = cpu_to_le32(bss_cfg->crypto.n_akm_suites); + aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites); for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) - aen.akm_suites[i] = cpu_to_le32( - bss_cfg->crypto.akm_suites[i]); + aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]); - aen.control_port = bss_cfg->crypto.control_port; - aen.control_port_no_encrypt = - bss_cfg->crypto.control_port_no_encrypt; - aen.control_port_ethertype = cpu_to_le16(be16_to_cpu( - bss_cfg->crypto.control_port_ethertype)); + aen->control_port = sme->crypto.control_port; + aen->control_port_no_encrypt = + sme->crypto.control_port_no_encrypt; + aen->control_port_ethertype = + cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype)); - qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid, - bss_cfg->ssid_len); - qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen, - sizeof(aen)); + qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid, + sme->ssid_len); if (sme->ie_len != 0) qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, sme->ie, sme->ie_len); + qtnf_bus_lock(vif->mac->bus); + ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); if (unlikely(ret)) @@ -2304,15 +2318,16 @@ out: return ret; } -int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac, +int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif, struct cfg80211_csa_settings *params) { + struct qtnf_wmac *mac = vif->mac; struct qlink_cmd_chan_switch *cmd; struct sk_buff *cmd_skb; u16 res_code = QLINK_CMD_RESULT_OK; int ret; - cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0x0, + cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid, QLINK_CMD_CHAN_SWITCH, sizeof(*cmd)); @@ -2334,9 +2349,6 @@ int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac, switch (res_code) { case QLINK_CMD_RESULT_OK: - memcpy(&mac->csa_chandef, ¶ms->chandef, - sizeof(mac->csa_chandef)); - mac->status |= QTNF_MAC_CSA_ACTIVE; ret = 0; break; case QLINK_CMD_RESULT_ENOTFOUND: @@ -2358,3 +2370,41 @@ out: qtnf_bus_unlock(mac->bus); return ret; } + +int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef) +{ + struct qtnf_bus *bus = vif->mac->bus; + const struct qlink_resp_channel_get *resp; + struct sk_buff *cmd_skb; + struct sk_buff *resp_skb = NULL; + u16 res_code = QLINK_CMD_RESULT_OK; + int ret; + + cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, + QLINK_CMD_CHAN_GET, + sizeof(struct qlink_cmd)); + if (unlikely(!cmd_skb)) + return -ENOMEM; + + qtnf_bus_lock(bus); + + ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code, + sizeof(*resp), NULL); + + qtnf_bus_unlock(bus); + + if (unlikely(ret)) + goto out; + + if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { + ret = -ENODATA; + goto out; + } + + resp = (const struct qlink_resp_channel_get *)resp_skb->data; + qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef); + +out: + consume_skb(resp_skb); + return ret; +} |