summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/quantenna/qtnfmac/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/commands.c')
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/commands.c220
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, &params->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;
+}