diff options
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac')
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/commands.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/commands.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/core.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/event.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/qlink.h | 57 |
11 files changed, 274 insertions, 53 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index d90016125dfc..aa0ed0f2b973 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -897,6 +897,45 @@ static int qtnf_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return ret; } +static int qtnf_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, + int *dbm) +{ + struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev); + int ret; + + ret = qtnf_cmd_get_tx_power(vif, dbm); + if (ret) + pr_err("MAC%u: failed to get Tx power\n", vif->mac->macid); + + return ret; +} + +static int qtnf_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm) +{ + struct qtnf_vif *vif; + int ret; + + if (wdev) { + vif = qtnf_netdev_get_priv(wdev->netdev); + } else { + struct qtnf_wmac *mac = wiphy_priv(wiphy); + + vif = qtnf_mac_get_base_vif(mac); + if (!vif) { + pr_err("MAC%u: primary VIF is not configured\n", + mac->macid); + return -EFAULT; + } + } + + ret = qtnf_cmd_set_tx_power(vif, type, mbm); + if (ret) + pr_err("MAC%u: failed to set Tx power\n", vif->mac->macid); + + return ret; +} + #ifdef CONFIG_PM static int qtnf_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan) { @@ -991,6 +1030,8 @@ static struct cfg80211_ops qtn_cfg80211_ops = { .start_radar_detection = qtnf_start_radar_detection, .set_mac_acl = qtnf_set_mac_acl, .set_power_mgmt = qtnf_set_power_mgmt, + .get_tx_power = qtnf_get_tx_power, + .set_tx_power = qtnf_set_tx_power, #ifdef CONFIG_PM .suspend = qtnf_suspend, .resume = qtnf_resume, diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index dc0c7244b60e..61bda34e2ac2 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -83,6 +83,7 @@ static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus, struct qlink_cmd *cmd; struct qlink_resp *resp = NULL; struct sk_buff *resp_skb = NULL; + int resp_res = 0; u16 cmd_id; u8 mac_id; u8 vif_id; @@ -113,6 +114,7 @@ static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus, } resp = (struct qlink_resp *)resp_skb->data; + resp_res = le16_to_cpu(resp->result); ret = qtnf_cmd_check_reply_header(resp, cmd_id, mac_id, vif_id, const_resp_size); if (ret) @@ -128,8 +130,8 @@ out: else consume_skb(resp_skb); - if (!ret && resp) - return qtnf_cmd_resp_result_decode(le16_to_cpu(resp->result)); + if (!ret) + return qtnf_cmd_resp_result_decode(resp_res); pr_warn("VIF%u.%u: cmd 0x%.4X failed: %d\n", mac_id, vif_id, cmd_id, ret); @@ -2641,6 +2643,71 @@ out: return ret; } +int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm) +{ + struct qtnf_bus *bus = vif->mac->bus; + const struct qlink_resp_txpwr *resp; + struct sk_buff *resp_skb = NULL; + struct qlink_cmd_txpwr *cmd; + struct sk_buff *cmd_skb; + int ret = 0; + + cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, + QLINK_CMD_TXPWR, sizeof(*cmd)); + if (!cmd_skb) + return -ENOMEM; + + cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; + cmd->op_type = QLINK_TXPWR_GET; + + qtnf_bus_lock(bus); + + ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, + sizeof(*resp), NULL); + if (ret) + goto out; + + resp = (const struct qlink_resp_txpwr *)resp_skb->data; + *dbm = MBM_TO_DBM(le32_to_cpu(resp->txpwr)); + +out: + qtnf_bus_unlock(bus); + consume_skb(resp_skb); + + return ret; +} + +int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif, + enum nl80211_tx_power_setting type, int mbm) +{ + struct qtnf_bus *bus = vif->mac->bus; + const struct qlink_resp_txpwr *resp; + struct sk_buff *resp_skb = NULL; + struct qlink_cmd_txpwr *cmd; + struct sk_buff *cmd_skb; + int ret = 0; + + cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, + QLINK_CMD_TXPWR, sizeof(*cmd)); + if (!cmd_skb) + return -ENOMEM; + + cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; + cmd->op_type = QLINK_TXPWR_SET; + cmd->txpwr_setting = type; + cmd->txpwr = cpu_to_le32(mbm); + + qtnf_bus_lock(bus); + + ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, + sizeof(*resp), NULL); + + qtnf_bus_unlock(bus); + consume_skb(resp_skb); + + return ret; +} + int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif, const struct cfg80211_wowlan *wowl) { diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h index 88d7a3cd90d2..e0de65261213 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.h +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h @@ -70,6 +70,9 @@ int qtnf_cmd_start_cac(const struct qtnf_vif *vif, int qtnf_cmd_set_mac_acl(const struct qtnf_vif *vif, const struct cfg80211_acl_data *params); int qtnf_cmd_send_pm_set(const struct qtnf_vif *vif, u8 pm_mode, int timeout); +int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm); +int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif, + enum nl80211_tx_power_setting type, int mbm); int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif, const struct cfg80211_wowlan *wowl); diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index 8d699cc03d26..8116b224c946 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -67,6 +67,14 @@ static int qtnf_netdev_close(struct net_device *ndev) return 0; } +static void qtnf_packet_send_hi_pri(struct sk_buff *skb) +{ + struct qtnf_vif *vif = qtnf_netdev_get_priv(skb->dev); + + skb_queue_tail(&vif->high_pri_tx_queue, skb); + queue_work(vif->mac->bus->hprio_workqueue, &vif->high_pri_tx_work); +} + /* Netdev handler for data transmission. */ static netdev_tx_t @@ -107,6 +115,12 @@ qtnf_netdev_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* tx path is enabled: reset vif timeout */ vif->cons_tx_timeout_cnt = 0; + if (unlikely(skb->protocol == htons(ETH_P_PAE))) { + qtnf_packet_send_hi_pri(skb); + qtnf_update_tx_stats(ndev, skb); + return NETDEV_TX_OK; + } + return qtnf_bus_data_tx(mac->bus, skb); } @@ -841,15 +855,6 @@ void qtnf_update_tx_stats(struct net_device *ndev, const struct sk_buff *skb) } EXPORT_SYMBOL_GPL(qtnf_update_tx_stats); -void qtnf_packet_send_hi_pri(struct sk_buff *skb) -{ - struct qtnf_vif *vif = qtnf_netdev_get_priv(skb->dev); - - skb_queue_tail(&vif->high_pri_tx_queue, skb); - queue_work(vif->mac->bus->hprio_workqueue, &vif->high_pri_tx_work); -} -EXPORT_SYMBOL_GPL(qtnf_packet_send_hi_pri); - struct dentry *qtnf_get_debugfs_dir(void) { return qtnf_debugfs_dir; diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h index 322858df600c..e3feea31191e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.h +++ b/drivers/net/wireless/quantenna/qtnfmac/core.h @@ -152,7 +152,6 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev); void qtnf_netdev_updown(struct net_device *ndev, bool up); void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted); -void qtnf_packet_send_hi_pri(struct sk_buff *skb); struct dentry *qtnf_get_debugfs_dir(void); static inline struct qtnf_vif *qtnf_netdev_get_priv(struct net_device *dev) diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index b57c8c18a8d0..51af93bdf06e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -171,8 +171,9 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, return -EPROTO; } - pr_debug("VIF%u.%u: BSSID:%pM status:%u\n", - vif->mac->macid, vif->vifid, join_info->bssid, status); + pr_debug("VIF%u.%u: BSSID:%pM chan:%u status:%u\n", + vif->mac->macid, vif->vifid, join_info->bssid, + le16_to_cpu(join_info->chan.chan.center_freq), status); if (status != WLAN_STATUS_SUCCESS) goto done; @@ -181,7 +182,7 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, if (!cfg80211_chandef_valid(&chandef)) { pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", vif->mac->macid, vif->vifid, - chandef.chan->center_freq, + chandef.chan ? chandef.chan->center_freq : 0, chandef.center_freq1, chandef.center_freq2, chandef.width); @@ -617,6 +618,42 @@ qtnf_event_handle_external_auth(struct qtnf_vif *vif, return ret; } +static int +qtnf_event_handle_mic_failure(struct qtnf_vif *vif, + const struct qlink_event_mic_failure *mic_ev, + u16 len) +{ + struct wiphy *wiphy = priv_to_wiphy(vif->mac); + u8 pairwise; + + if (len < sizeof(*mic_ev)) { + pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", + vif->mac->macid, vif->vifid, len, + sizeof(struct qlink_event_mic_failure)); + return -EINVAL; + } + + if (!wiphy->registered || !vif->netdev) + return 0; + + if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { + pr_err("VIF%u.%u: MIC_FAILURE event when not in STA mode\n", + vif->mac->macid, vif->vifid); + return -EPROTO; + } + + pairwise = mic_ev->pairwise ? + NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP; + + pr_info("%s: MIC error: src=%pM key_index=%u pairwise=%u\n", + vif->netdev->name, mic_ev->src, mic_ev->key_index, pairwise); + + cfg80211_michael_mic_failure(vif->netdev, mic_ev->src, pairwise, + mic_ev->key_index, NULL, GFP_KERNEL); + + return 0; +} + static int qtnf_event_parse(struct qtnf_wmac *mac, const struct sk_buff *event_skb) { @@ -679,6 +716,10 @@ static int qtnf_event_parse(struct qtnf_wmac *mac, ret = qtnf_event_handle_external_auth(vif, (const void *)event, event_len); break; + case QLINK_EVENT_MIC_FAILURE: + ret = qtnf_event_handle_mic_failure(vif, (const void *)event, + event_len); + break; default: pr_warn("unknown event type: %x\n", event_id); break; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c index 8ae318b5fe54..5337e67092ca 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c @@ -33,7 +33,7 @@ static unsigned int tx_bd_size_param; module_param(tx_bd_size_param, uint, 0644); MODULE_PARM_DESC(tx_bd_size_param, "Tx descriptors queue size"); -static unsigned int rx_bd_size_param = 256; +static unsigned int rx_bd_size_param; module_param(rx_bd_size_param, uint, 0644); MODULE_PARM_DESC(rx_bd_size_param, "Rx descriptors queue size"); @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus) { + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + char card_id[64]; int ret; bus->fw_state = QTNF_FW_STATE_BOOT_DONE; @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus) if (ret) { pr_err("failed to attach core\n"); } else { - qtnf_debugfs_init(bus, DRV_NAME); + snprintf(card_id, sizeof(card_id), "%s:%s", + DRV_NAME, pci_name(priv->pdev)); + qtnf_debugfs_init(bus, card_id); qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); @@ -337,7 +341,6 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) bus->fw_state = QTNF_FW_STATE_DETACHED; pcie_priv->pdev = pdev; pcie_priv->tx_stopped = 0; - pcie_priv->rx_bd_num = rx_bd_size_param; pcie_priv->flashboot = flashboot; if (fw_blksize_param > QTN_PCIE_MAX_FW_BUFSZ) @@ -354,7 +357,6 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) pcie_priv->pcie_irq_count = 0; pcie_priv->tx_reclaim_done = 0; pcie_priv->tx_reclaim_req = 0; - pcie_priv->tx_eapol = 0; pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PCIE"); if (!pcie_priv->workqueue) { @@ -377,7 +379,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) pcie_priv->epmem_bar = epmem_bar; pci_save_state(pdev); - ret = pcie_priv->probe_cb(bus, tx_bd_size_param); + ret = pcie_priv->probe_cb(bus, tx_bd_size_param, rx_bd_size_param); if (ret) goto error; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h index 5e8b9cb68419..2a6a928e13bd 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h @@ -23,7 +23,8 @@ struct qtnf_pcie_bus_priv { struct pci_dev *pdev; - int (*probe_cb)(struct qtnf_bus *bus, unsigned int tx_bd_size); + int (*probe_cb)(struct qtnf_bus *bus, unsigned int tx_bd_size, + unsigned int rx_bd_size); void (*remove_cb)(struct qtnf_bus *bus); int (*suspend_cb)(struct qtnf_bus *bus); int (*resume_cb)(struct qtnf_bus *bus); @@ -62,7 +63,6 @@ struct qtnf_pcie_bus_priv { u32 tx_done_count; u32 tx_reclaim_done; u32 tx_reclaim_req; - u32 tx_eapol; u8 msi_enabled; u8 tx_stopped; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 3aa3714d4dfd..a501a1fd5332 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -24,6 +24,7 @@ #include "debug.h" #define PEARL_TX_BD_SIZE_DEFAULT 32 +#define PEARL_RX_BD_SIZE_DEFAULT 256 struct qtnf_pearl_bda { __le16 bda_len; @@ -244,8 +245,6 @@ static int pearl_alloc_bd_table(struct qtnf_pcie_pearl_state *ps) /* tx bd */ - memset(vaddr, 0, len); - ps->bd_table_vaddr = vaddr; ps->bd_table_paddr = paddr; ps->bd_table_len = len; @@ -399,7 +398,8 @@ static int pearl_hhbm_init(struct qtnf_pcie_pearl_state *ps) } static int qtnf_pcie_pearl_init_xfer(struct qtnf_pcie_pearl_state *ps, - unsigned int tx_bd_size) + unsigned int tx_bd_size, + unsigned int rx_bd_size) { struct qtnf_pcie_bus_priv *priv = &ps->base; int ret; @@ -411,28 +411,29 @@ static int qtnf_pcie_pearl_init_xfer(struct qtnf_pcie_pearl_state *ps, val = tx_bd_size * sizeof(struct qtnf_pearl_tx_bd); if (!is_power_of_2(tx_bd_size) || val > PCIE_HHBM_MAX_SIZE) { - pr_warn("bad tx_bd_size value %u\n", tx_bd_size); + pr_warn("invalid tx_bd_size value %u, use default %u\n", + tx_bd_size, PEARL_TX_BD_SIZE_DEFAULT); priv->tx_bd_num = PEARL_TX_BD_SIZE_DEFAULT; } else { priv->tx_bd_num = tx_bd_size; } - priv->rx_bd_w_index = 0; - priv->rx_bd_r_index = 0; + if (rx_bd_size == 0) + rx_bd_size = PEARL_RX_BD_SIZE_DEFAULT; - if (!priv->rx_bd_num || !is_power_of_2(priv->rx_bd_num)) { - pr_err("rx_bd_size_param %u is not power of two\n", - priv->rx_bd_num); - return -EINVAL; - } + val = rx_bd_size * sizeof(dma_addr_t); - val = priv->rx_bd_num * sizeof(dma_addr_t); - if (val > PCIE_HHBM_MAX_SIZE) { - pr_err("rx_bd_size_param %u is too large\n", - priv->rx_bd_num); - return -EINVAL; + if (!is_power_of_2(rx_bd_size) || val > PCIE_HHBM_MAX_SIZE) { + pr_warn("invalid rx_bd_size value %u, use default %u\n", + rx_bd_size, PEARL_RX_BD_SIZE_DEFAULT); + priv->rx_bd_num = PEARL_RX_BD_SIZE_DEFAULT; + } else { + priv->rx_bd_num = rx_bd_size; } + priv->rx_bd_w_index = 0; + priv->rx_bd_r_index = 0; + ret = pearl_hhbm_init(ps); if (ret) { pr_err("failed to init h/w queues\n"); @@ -1066,7 +1067,8 @@ static u64 qtnf_pearl_dma_mask_get(void) #endif } -static int qtnf_pcie_pearl_probe(struct qtnf_bus *bus, unsigned int tx_bd_size) +static int qtnf_pcie_pearl_probe(struct qtnf_bus *bus, unsigned int tx_bd_size, + unsigned int rx_bd_size) { struct qtnf_shm_ipc_int ipc_int; struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); @@ -1081,7 +1083,7 @@ static int qtnf_pcie_pearl_probe(struct qtnf_bus *bus, unsigned int tx_bd_size) ps->bda = ps->base.epmem_bar; writel(ps->base.msi_enabled, &ps->bda->bda_rc_msi_enabled); - ret = qtnf_pcie_pearl_init_xfer(ps, tx_bd_size); + ret = qtnf_pcie_pearl_init_xfer(ps, tx_bd_size, rx_bd_size); if (ret) { pr_err("PCIE xfer init failed\n"); return ret; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c index 9a4380ed7f1b..a0587472736f 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c @@ -23,6 +23,7 @@ #include "debug.h" #define TOPAZ_TX_BD_SIZE_DEFAULT 128 +#define TOPAZ_RX_BD_SIZE_DEFAULT 256 struct qtnf_topaz_tx_bd { __le32 addr; @@ -199,8 +200,6 @@ static int topaz_alloc_bd_table(struct qtnf_pcie_topaz_state *ts, if (!vaddr) return -ENOMEM; - memset(vaddr, 0, len); - /* tx bd */ ts->tx_bd_vbase = vaddr; @@ -333,7 +332,8 @@ static void qtnf_topaz_free_xfer_buffers(struct qtnf_pcie_topaz_state *ts) } static int qtnf_pcie_topaz_init_xfer(struct qtnf_pcie_topaz_state *ts, - unsigned int tx_bd_size) + unsigned int tx_bd_size, + unsigned int rx_bd_size) { struct qtnf_topaz_bda __iomem *bda = ts->bda; struct qtnf_pcie_bus_priv *priv = &ts->base; @@ -351,6 +351,17 @@ static int qtnf_pcie_topaz_init_xfer(struct qtnf_pcie_topaz_state *ts, priv->tx_bd_num = tx_bd_size; qtnf_non_posted_write(priv->tx_bd_num, &bda->bda_rc_tx_bd_num); + + if (rx_bd_size == 0) + rx_bd_size = TOPAZ_RX_BD_SIZE_DEFAULT; + + if (rx_bd_size > TOPAZ_RX_BD_SIZE_DEFAULT) { + pr_warn("RX BD queue cannot exceed %d\n", + TOPAZ_RX_BD_SIZE_DEFAULT); + rx_bd_size = TOPAZ_RX_BD_SIZE_DEFAULT; + } + + priv->rx_bd_num = rx_bd_size; qtnf_non_posted_write(priv->rx_bd_num, &bda->bda_rc_rx_bd_num); priv->rx_bd_w_index = 0; @@ -498,13 +509,6 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) int len; int i; - if (unlikely(skb->protocol == htons(ETH_P_PAE))) { - qtnf_packet_send_hi_pri(skb); - qtnf_update_tx_stats(skb->dev, skb); - priv->tx_eapol++; - return NETDEV_TX_OK; - } - spin_lock_irqsave(&priv->tx_lock, flags); if (!qtnf_tx_queue_ready(ts)) { @@ -768,7 +772,6 @@ static int qtnf_dbg_pkt_stats(struct seq_file *s, void *data) seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count); seq_printf(s, "tx_reclaim_done(%u)\n", priv->tx_reclaim_done); seq_printf(s, "tx_reclaim_req(%u)\n", priv->tx_reclaim_req); - seq_printf(s, "tx_eapol(%u)\n", priv->tx_eapol); seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index); seq_printf(s, "tx_done_index(%u)\n", tx_done_index); @@ -1113,7 +1116,8 @@ static u64 qtnf_topaz_dma_mask_get(void) return DMA_BIT_MASK(32); } -static int qtnf_pcie_topaz_probe(struct qtnf_bus *bus, unsigned int tx_bd_num) +static int qtnf_pcie_topaz_probe(struct qtnf_bus *bus, + unsigned int tx_bd_num, unsigned int rx_bd_num) { struct qtnf_pcie_topaz_state *ts = get_bus_priv(bus); struct pci_dev *pdev = ts->base.pdev; @@ -1147,7 +1151,7 @@ static int qtnf_pcie_topaz_probe(struct qtnf_bus *bus, unsigned int tx_bd_num) return ret; } - ret = qtnf_pcie_topaz_init_xfer(ts, tx_bd_num); + ret = qtnf_pcie_topaz_init_xfer(ts, tx_bd_num, rx_bd_num); if (ret) { pr_err("PCIE xfer init failed\n"); return ret; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index 8a3c6344fa8e..59c69c0a6e06 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -217,6 +217,8 @@ struct qlink_sta_info_state { * command is supported only if device reports QLINK_HW_SUPPORTS_REG_UPDATE * capability. * @QLINK_CMD_START_CAC: start radar detection procedure on a specified channel. + * @QLINK_CMD_TXPWR: get or set current channel transmit power for + * the specified MAC. */ enum qlink_cmd_type { QLINK_CMD_FW_INIT = 0x0001, @@ -254,6 +256,7 @@ enum qlink_cmd_type { QLINK_CMD_PM_SET = 0x0062, QLINK_CMD_WOWLAN_SET = 0x0063, QLINK_CMD_EXTERNAL_AUTH = 0x0066, + QLINK_CMD_TXPWR = 0x0067, }; /** @@ -719,6 +722,32 @@ struct qlink_cmd_pm_set { } __packed; /** + * enum qlink_txpwr_op - transmit power operation type + * @QLINK_TXPWR_SET: set tx power + * @QLINK_TXPWR_GET: get current tx power setting + */ +enum qlink_txpwr_op { + QLINK_TXPWR_SET, + QLINK_TXPWR_GET +}; + +/** + * struct qlink_cmd_txpwr - get or set current transmit power + * + * @txpwr: new transmit power setting, in mBm + * @txpwr_setting: transmit power setting type, one of + * &enum nl80211_tx_power_setting + * @op_type: type of operation, one of &enum qlink_txpwr_op + */ +struct qlink_cmd_txpwr { + struct qlink_cmd chdr; + __le32 txpwr; + u8 txpwr_setting; + u8 op_type; + u8 rsvd[2]; +} __packed; + +/** * enum qlink_wowlan_trigger * * @QLINK_WOWLAN_TRIG_DISCONNECT: wakeup on disconnect @@ -944,6 +973,19 @@ struct qlink_resp_channel_get { struct qlink_chandef chan; } __packed; +/** + * struct qlink_resp_txpwr - response for QLINK_CMD_TXPWR command + * + * This response is intended for QLINK_TXPWR_GET operation and does not + * contain any meaningful information in case of QLINK_TXPWR_SET operation. + * + * @txpwr: current transmit power setting, in mBm + */ +struct qlink_resp_txpwr { + struct qlink_resp rhdr; + __le32 txpwr; +} __packed; + /* QLINK Events messages related definitions */ @@ -958,6 +1000,7 @@ enum qlink_event_type { QLINK_EVENT_FREQ_CHANGE = 0x0028, QLINK_EVENT_RADAR = 0x0029, QLINK_EVENT_EXTERNAL_AUTH = 0x0030, + QLINK_EVENT_MIC_FAILURE = 0x0031, }; /** @@ -1151,6 +1194,20 @@ struct qlink_event_external_auth { u8 action; } __packed; +/** + * struct qlink_event_mic_failure - data for QLINK_EVENT_MIC_FAILURE event + * + * @src: source MAC address of the frame + * @key_index: index of the key being reported + * @pairwise: whether the key is pairwise or group + */ +struct qlink_event_mic_failure { + struct qlink_event ehdr; + u8 src[ETH_ALEN]; + u8 key_index; + u8 pairwise; +} __packed; + /* QLINK TLVs (Type-Length Values) definitions */ |