diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h index 163ddc49f951..0b76a615708e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h @@ -71,6 +71,7 @@ struct brcmf_bus_dcmd { * @wowl_config: specify if dongle is configured for wowl when going to suspend * @get_ramsize: obtain size of device memory. * @get_memdump: obtain device memory dump in provided buffer. + * @get_fwname: obtain firmware name. * * This structure provides an abstract interface towards the * bus specific driver. For control messages to common driver @@ -87,6 +88,8 @@ struct brcmf_bus_ops { void (*wowl_config)(struct device *dev, bool enabled); size_t (*get_ramsize)(struct device *dev); int (*get_memdump)(struct device *dev, void *data, size_t len); + int (*get_fwname)(struct device *dev, uint chip, uint chiprev, + unsigned char *fw_name); }; @@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len) return bus->ops->get_memdump(bus->dev, data, len); } +static inline +int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, + unsigned char *fw_name) +{ + return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); +} + /* * interface functions from common layer */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 4bfd43a80273..6e70df978159 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -472,47 +472,6 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key) return err; } -static s32 -brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) -{ - s32 err; - u32 mode; - - if (enable) - mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; - else - mode = 0; - - /* Try to set and enable ARP offload feature, this may fail, then it */ - /* is simply not supported and err 0 will be returned */ - err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); - if (err) { - brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", - mode, err); - err = 0; - } else { - err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); - if (err) { - brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", - enable, err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", - enable, mode); - } - - err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); - if (err) { - brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", - enable, err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", - enable, mode); - - return err; -} - static void brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) { @@ -1084,7 +1043,6 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) { struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err; - u32 passive_scan; struct brcmf_scan_results *results; struct escan_info *escan = &cfg->escan_info; @@ -1092,13 +1050,7 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) escan->ifp = ifp; escan->wiphy = cfg->wiphy; escan->escan_state = WL_ESCAN_STATE_SCANNING; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); - if (err) { - brcmf_err("error (%d)\n", err); - return err; - } + brcmf_scan_config_mpc(ifp, 0); results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; results->version = 0; @@ -1112,21 +1064,16 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) } static s32 -brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, - struct cfg80211_scan_request *request, - struct cfg80211_ssid *this_ssid) +brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { - struct brcmf_if *ifp = vif->ifp; struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct cfg80211_ssid *ssids; - u32 passive_scan; - bool escan_req; - bool spec_scan; - s32 err; - struct brcmf_ssid_le ssid_le; - u32 SSID_len; + struct brcmf_cfg80211_vif *vif; + s32 err = 0; - brcmf_dbg(SCAN, "START ESCAN\n"); + brcmf_dbg(TRACE, "Enter\n"); + vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); + if (!check_vif_up(vif)) + return -EIO; if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); @@ -1142,8 +1089,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, cfg->scan_status); return -EAGAIN; } - if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { - brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); + if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { + brcmf_err("Connecting: status (%lu)\n", vif->sme_state); return -EAGAIN; } @@ -1151,96 +1098,38 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; - escan_req = false; - if (request) { - /* scan bss */ - ssids = request->ssids; - escan_req = true; - } else { - /* scan in ibss */ - /* we don't do escan in ibss */ - ssids = this_ssid; - } + brcmf_dbg(SCAN, "START ESCAN\n"); cfg->scan_request = request; set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); - if (escan_req) { - cfg->escan_info.run = brcmf_run_escan; - err = brcmf_p2p_scan_prep(wiphy, request, vif); - if (err) - goto scan_out; - err = brcmf_do_escan(vif->ifp, request); - if (err) - goto scan_out; - } else { - brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n", - ssids->ssid, ssids->ssid_len); - memset(&ssid_le, 0, sizeof(ssid_le)); - SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len); - ssid_le.SSID_len = cpu_to_le32(0); - spec_scan = false; - if (SSID_len) { - memcpy(ssid_le.SSID, ssids->ssid, SSID_len); - ssid_le.SSID_len = cpu_to_le32(SSID_len); - spec_scan = true; - } else - brcmf_dbg(SCAN, "Broadcast scan\n"); + cfg->escan_info.run = brcmf_run_escan; + err = brcmf_p2p_scan_prep(wiphy, request, vif); + if (err) + goto scan_out; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); - if (err) { - brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); - goto scan_out; - } - brcmf_scan_config_mpc(ifp, 0); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le, - sizeof(ssid_le)); - if (err) { - if (err == -EBUSY) - brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n", - ssid_le.SSID); - else - brcmf_err("WLC_SCAN error (%d)\n", err); + err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, + request->ie, request->ie_len); + if (err) + goto scan_out; - brcmf_scan_config_mpc(ifp, 1); - goto scan_out; - } - } + err = brcmf_do_escan(vif->ifp, request); + if (err) + goto scan_out; /* Arm scan timeout timer */ - mod_timer(&cfg->escan_timeout, jiffies + - BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); + mod_timer(&cfg->escan_timeout, + jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS)); return 0; scan_out: + brcmf_err("scan error (%d)\n", err); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); cfg->scan_request = NULL; return err; } -static s32 -brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -{ - struct brcmf_cfg80211_vif *vif; - s32 err = 0; - - brcmf_dbg(TRACE, "Enter\n"); - vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); - if (!check_vif_up(vif)) - return -EIO; - - err = brcmf_cfg80211_escan(wiphy, vif, request, NULL); - - if (err) - brcmf_err("scan error (%d)\n", err); - - brcmf_dbg(TRACE, "Exit\n"); - return err; -} - static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) { s32 err = 0; @@ -5876,7 +5765,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) cfg->scan_request = NULL; cfg->pwr_save = true; - cfg->active_scan = true; /* we do active scan per default */ cfg->dongle_up = false; /* dongle is not up yet */ err = brcmf_init_priv_mem(cfg); if (err) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index 7b2835e5e434..b5b5f0f10b63 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -283,7 +283,6 @@ struct brcmf_cfg80211_wowl { * @scan_status: scan activity on the dongle. * @pub: common driver information. * @channel: current channel. - * @active_scan: current scan mode. * @int_escan_map: bucket map for which internal e-scan is done. * @ibss_starter: indicates this sta is ibss starter. * @pwr_save: indicate whether dongle to support power save mode. @@ -316,7 +315,6 @@ struct brcmf_cfg80211_info { unsigned long scan_status; struct brcmf_pub *pub; u32 channel; - bool active_scan; u32 int_escan_map; bool ibss_starter; bool pwr_save; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 7a2b49587b4d..6a59d0609d30 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "core.h" @@ -28,6 +29,7 @@ #include "tracepoint.h" #include "common.h" #include "of.h" +#include "firmware.h" MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); @@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp) brcmf_err("Set join_pref error (%d)\n", err); } +static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, + struct brcmf_dload_data_le *dload_buf, + u32 len) +{ + s32 err; + + flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT); + dload_buf->flag = cpu_to_le16(flag); + dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM); + dload_buf->len = cpu_to_le32(len); + dload_buf->crc = cpu_to_le32(0); + len = sizeof(*dload_buf) + len - 1; + + err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len); + + return err; +} + +static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) +{ + struct brcmf_bus *bus = ifp->drvr->bus_if; + struct brcmf_rev_info *ri = &ifp->drvr->revinfo; + u8 fw_name[BRCMF_FW_NAME_LEN]; + u8 *ptr; + size_t len; + s32 err; + + memset(fw_name, 0, BRCMF_FW_NAME_LEN); + err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); + if (err) { + brcmf_err("get firmware name failed (%d)\n", err); + goto done; + } + + /* generate CLM blob file name */ + ptr = strrchr(fw_name, '.'); + if (!ptr) { + err = -ENOENT; + goto done; + } + + len = ptr - fw_name + 1; + if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { + err = -E2BIG; + } else { + strlcpy(clm_name, fw_name, len); + strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); + } +done: + return err; +} + +static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) +{ + struct device *dev = ifp->drvr->bus_if->dev; + struct brcmf_dload_data_le *chunk_buf; + const struct firmware *clm = NULL; + u8 clm_name[BRCMF_FW_NAME_LEN]; + u32 chunk_len; + u32 datalen; + u32 cumulative_len; + u16 dl_flag = DL_BEGIN; + u32 status; + s32 err; + + brcmf_dbg(TRACE, "Enter\n"); + + memset(clm_name, 0, BRCMF_FW_NAME_LEN); + err = brcmf_c_get_clm_name(ifp, clm_name); + if (err) { + brcmf_err("get CLM blob file name failed (%d)\n", err); + return err; + } + + err = request_firmware(&clm, clm_name, dev); + if (err) { + if (err == -ENOENT) { + brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n"); + return 0; + } + brcmf_err("request CLM blob file failed (%d)\n", err); + return err; + } + + chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL); + if (!chunk_buf) { + err = -ENOMEM; + goto done; + } + + datalen = clm->size; + cumulative_len = 0; + do { + if (datalen > MAX_CHUNK_LEN) { + chunk_len = MAX_CHUNK_LEN; + } else { + chunk_len = datalen; + dl_flag |= DL_END; + } + memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len); + + err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len); + + dl_flag &= ~DL_BEGIN; + + cumulative_len += chunk_len; + datalen -= chunk_len; + } while ((datalen > 0) && (err == 0)); + + if (err) { + brcmf_err("clmload (%zu byte file) failed (%d); ", + clm->size, err); + /* Retrieve clmload_status and print */ + err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); + if (err) + brcmf_err("get clmload_status failed (%d)\n", err); + else + brcmf_dbg(INFO, "clmload_status=%d\n", status); + err = -EIO; + } + + kfree(chunk_buf); +done: + release_firmware(clm); + return err; +} + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) { s8 eventmask[BRCMF_EVENTING_MASK_LEN]; u8 buf[BRCMF_DCMD_SMLEN]; struct brcmf_rev_info_le revinfo; struct brcmf_rev_info *ri; + char *clmver; char *ptr; s32 err; @@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) } ri->result = err; + /* Do any CLM downloading */ + err = brcmf_c_process_clm_blob(ifp); + if (err < 0) { + brcmf_err("download CLM blob file failed, %d\n", err); + goto done; + } + /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); strcpy(buf, "ver"); @@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) ptr = strrchr(buf, ' ') + 1; strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); + /* Query for 'clmver' to get CLM version info from firmware */ + memset(buf, 0, sizeof(buf)); + err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf)); + if (err) { + brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err); + } else { + clmver = (char *)buf; + /* store CLM version for adding it to revinfo debugfs file */ + memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); + + /* Replace all newline/linefeed characters with space + * character + */ + ptr = clmver; + while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL) + *ptr = ' '; + + brcmf_dbg(INFO, "CLM version = %s\n", clmver); + } + /* set mpc */ err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); if (err) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 5cc3a07dda9e..930e423f83a8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx) return ifp; } +void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) +{ + s32 err; + u32 mode; + + if (enable) + mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; + else + mode = 0; + + /* Try to set and enable ARP offload feature, this may fail, then it */ + /* is simply not supported and err 0 will be returned */ + err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); + if (err) { + brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", + mode, err); + } else { + err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); + if (err) { + brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", + enable, err); + } else { + brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", + enable, mode); + } + } + + err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); + if (err) { + brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", + enable, err); + } else { + brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", + enable, mode); + } +} + static void _brcmf_set_multicast_list(struct work_struct *work) { struct brcmf_if *ifp; @@ -134,6 +171,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work) if (err < 0) brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n", err); + brcmf_configure_arp_nd_offload(ifp, !cmd_value); } #if IS_ENABLED(CONFIG_IPV6) @@ -950,6 +988,8 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data) seq_printf(s, "anarev: %u\n", ri->anarev); seq_printf(s, "nvramrev: %08x\n", ri->nvramrev); + seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver); + return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index a4dd313140f3..df8a1ecb9924 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -141,6 +141,8 @@ struct brcmf_pub { struct notifier_block inetaddr_notifier; struct notifier_block inet6addr_notifier; struct brcmf_mp_device *settings; + + u8 clmver[BRCMF_DCMD_SMLEN]; }; /* forward declarations */ @@ -203,6 +205,7 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); /* Return pointer to interface name */ char *brcmf_ifname(struct brcmf_if *ifp); struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); +void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable); int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, const char *name, u8 *mac_addr); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index e0d22fedb2b4..4b290705e3e6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -155,6 +155,21 @@ #define BRCMF_MFP_CAPABLE 1 #define BRCMF_MFP_REQUIRED 2 +/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each + * ioctl. It is relatively small because firmware has small maximum size input + * playload restriction for ioctls. + */ +#define MAX_CHUNK_LEN 1400 + +#define DLOAD_HANDLER_VER 1 /* Downloader version */ +#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ +#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ + +#define DL_BEGIN 0x0002 +#define DL_END 0x0004 + +#define DL_TYPE_CLM 2 + /* join preference types for join_pref iovar */ enum brcmf_join_pref_types { BRCMF_JOIN_PREF_RSSI = 1, @@ -826,6 +841,22 @@ struct brcmf_pno_macaddr_le { u8 mac[ETH_ALEN]; }; +/** + * struct brcmf_dload_data_le - data passing to firmware for downloading + * @flag: flags related to download data. + * @dload_type: type of download data. + * @len: length in bytes of download data. + * @crc: crc of download data. + * @data: download data. + */ +struct brcmf_dload_data_le { + __le16 flag; + __le16 dload_type; + __le32 len; + __le32 crc; + u8 data[1]; +}; + /** * struct brcmf_pno_bssid_le - bssid configuration for PNO scan. * diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 1c450c0727cb..2ee54133efa1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -692,10 +692,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans, /* determine the scan engine parameters */ sparams->bss_type = DOT11_BSSTYPE_ANY; - if (p2p->cfg->active_scan) - sparams->scan_type = 0; - else - sparams->scan_type = 1; + sparams->scan_type = BRCMF_SCANTYPE_ACTIVE; eth_broadcast_addr(sparams->bssid); sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS); @@ -884,7 +881,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy, { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_p2p_info *p2p = &cfg->p2p; - int err = 0; + int err; if (brcmf_p2p_scan_is_p2p_request(request)) { /* find my listen channel */ @@ -907,9 +904,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy, /* override .run_escan() callback. */ cfg->escan_info.run = brcmf_p2p_run_escan; } - err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, - request->ie, request->ie_len); - return err; + return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index e6e9b00b79d7..3c87157f5b85 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len) return 0; } +static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, + u8 *fw_name) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; + struct brcmf_pciedev_info *devinfo = buspub->devinfo; + int ret = 0; + + if (devinfo->fw_name[0] != '\0') + strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); + else + ret = brcmf_fw_map_chip_to_name(chip, chiprev, + brcmf_pcie_fwnames, + ARRAY_SIZE(brcmf_pcie_fwnames), + fw_name, NULL); + + return ret; +} static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { .txdata = brcmf_pcie_tx, @@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { .wowl_config = brcmf_pcie_wowl_config, .get_ramsize = brcmf_pcie_get_ramsize, .get_memdump = brcmf_pcie_get_memdump, + .get_fwname = brcmf_pcie_get_fwname, }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 5adce0e36fe5..b2256aa76eb6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -260,10 +260,11 @@ struct rte_console { #define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */ /* tohostmailboxdata */ -#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */ -#define HMB_DATA_DEVREADY 2 /* talk to host after enable */ -#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */ -#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */ +#define HMB_DATA_NAKHANDLED 0x0001 /* retransmit NAK'd frame */ +#define HMB_DATA_DEVREADY 0x0002 /* talk to host after enable */ +#define HMB_DATA_FC 0x0004 /* per prio flowcontrol update flag */ +#define HMB_DATA_FWREADY 0x0008 /* fw ready for protocol activity */ +#define HMB_DATA_FWHALT 0x0010 /* firmware halted */ #define HMB_DATA_FCDATA_MASK 0xff000000 #define HMB_DATA_FCDATA_SHIFT 24 @@ -1094,6 +1095,10 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) offsetof(struct sdpcmd_regs, tosbmailbox)); bus->sdcnt.f1regdata += 2; + /* dongle indicates the firmware has halted/crashed */ + if (hmb_data & HMB_DATA_FWHALT) + brcmf_err("mailbox indicates firmware halted\n"); + /* Dongle recomposed rx frames, accept them again */ if (hmb_data & HMB_DATA_NAKHANDLED) { brcmf_dbg(SDIO, "Dongle reports NAK handled, expect rtx of %d\n", @@ -1151,6 +1156,7 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) HMB_DATA_NAKHANDLED | HMB_DATA_FC | HMB_DATA_FWREADY | + HMB_DATA_FWHALT | HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) brcmf_err("Unknown mailbox data content: 0x%02x\n", hmb_data); @@ -3979,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data) } } +static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, + u8 *fw_name) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + int ret = 0; + + if (sdiodev->fw_name[0] != '\0') + strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); + else + ret = brcmf_fw_map_chip_to_name(chip, chiprev, + brcmf_sdio_fwnames, + ARRAY_SIZE(brcmf_sdio_fwnames), + fw_name, NULL); + + return ret; +} + static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdio_bus_stop, .preinit = brcmf_sdio_bus_preinit, @@ -3989,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .wowl_config = brcmf_sdio_wowl_config, .get_ramsize = brcmf_sdio_bus_get_ramsize, .get_memdump = brcmf_sdio_bus_get_memdump, + .get_fwname = brcmf_sdio_get_fwname, }; static void brcmf_sdio_firmware_callback(struct device *dev, int err, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 11ffaa01599e..b27170c12482 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled) device_set_wakeup_enable(devinfo->dev, false); } +static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, + u8 *fw_name) +{ + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + int ret = 0; + + if (devinfo->fw_name[0] != '\0') + strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); + else + ret = brcmf_fw_map_chip_to_name(chip, chiprev, + brcmf_usb_fwnames, + ARRAY_SIZE(brcmf_usb_fwnames), + fw_name, NULL); + + return ret; +} + static const struct brcmf_bus_ops brcmf_usb_bus_ops = { .txdata = brcmf_usb_tx, .stop = brcmf_usb_down, .txctl = brcmf_usb_tx_ctlpkt, .rxctl = brcmf_usb_rx_ctlpkt, .wowl_config = brcmf_usb_wowl_config, + .get_fwname = brcmf_usb_get_fwname, }; static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index c055f6da11c6..365a4187fc37 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -2154,13 +2154,11 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, u8 use_green; u8 active_tbl = 0; u8 valid_tx_ant; - struct il_station_priv *sta_priv; if (!sta || !lq_sta) return; use_green = il4965_rs_use_green(il, sta); - sta_priv = (void *)sta->drv_priv; i = lq_sta->last_txrate_idx; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index 1dce74afcd75..9bb7c19d48eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -100,14 +100,6 @@ #define NVM_HW_SECTION_NUM_FAMILY_8000 10 #define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C" -/* Max SDIO RX/TX aggregation sizes of the ADDBA request/response */ -#define MAX_RX_AGG_SIZE_8260_SDIO 21 -#define MAX_TX_AGG_SIZE_8260_SDIO 40 - -/* Max A-MPDU exponent for HT and VHT */ -#define MAX_HT_AMPDU_EXPONENT_8260_SDIO IEEE80211_HT_MAX_AMPDU_32K -#define MAX_VHT_AMPDU_EXPONENT_8260_SDIO IEEE80211_VHT_MAX_AMPDU_32K - static const struct iwl_base_params iwl8000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000, .num_of_queues = 31, @@ -234,48 +226,5 @@ const struct iwl_cfg iwl4165_2ac_cfg = { .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, }; -const struct iwl_cfg iwl8260_2ac_sdio_cfg = { - .name = "Intel(R) Dual Band Wireless-AC 8260", - .fw_name_pre = IWL8000_FW_PRE, - IWL_DEVICE_8260, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, - .nvm_calib_ver = IWL8000_TX_POWER_VERSION, - .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, - .max_tx_agg_size = MAX_TX_AGG_SIZE_8260_SDIO, - .disable_dummy_notification = true, - .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, - .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, -}; - -const struct iwl_cfg iwl8265_2ac_sdio_cfg = { - .name = "Intel(R) Dual Band Wireless-AC 8265", - .fw_name_pre = IWL8265_FW_PRE, - IWL_DEVICE_8265, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, - .nvm_calib_ver = IWL8000_TX_POWER_VERSION, - .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, - .max_tx_agg_size = MAX_TX_AGG_SIZE_8260_SDIO, - .disable_dummy_notification = true, - .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, - .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, -}; - -const struct iwl_cfg iwl4165_2ac_sdio_cfg = { - .name = "Intel(R) Dual Band Wireless-AC 4165", - .fw_name_pre = IWL8000_FW_PRE, - IWL_DEVICE_8000, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, - .nvm_calib_ver = IWL8000_TX_POWER_VERSION, - .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, - .max_tx_agg_size = MAX_TX_AGG_SIZE_8260_SDIO, - .bt_shared_single_ant = true, - .disable_dummy_notification = true, - .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, - .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, -}; - MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL8265_MODULE_FIRMWARE(IWL8265_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h b/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h index e76f9cd4473d..721b9fed7201 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h @@ -81,28 +81,4 @@ struct iwl_fw_paging_cmd { __le32 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS]; } __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_1 */ -/** - * enum iwl_fw_item_id - FW item IDs - * - * @IWL_FW_ITEM_ID_PAGING: Address of the pages that the FW will upload - * download - */ -enum iwl_fw_item_id { - IWL_FW_ITEM_ID_PAGING = 3, -}; - -/** - * struct iwl_fw_get_item_cmd - get an item from the fw - * @item_id: ID of item to obtain, see &enum iwl_fw_item_id - */ -struct iwl_fw_get_item_cmd { - __le32 item_id; -} __packed; /* FW_GET_ITEM_CMD_API_S_VER_1 */ - -struct iwl_fw_get_item_resp { - __le32 item_id; - __le32 item_byte_cnt; - __le32 item_val; -} __packed; /* FW_GET_ITEM_RSP_S_VER_1 */ - #endif /* __iwl_fw_api_paging_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index efd7fb65de8b..740d97093d1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -136,7 +136,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, IWL_UCODE_TLV_PAGING = 32, IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, - IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, + /* 35 is unused */ IWL_UCODE_TLV_FW_VERSION = 36, IWL_UCODE_TLV_FW_DBG_DEST = 38, IWL_UCODE_TLV_FW_DBG_CONF = 39, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index e6bc9cb60700..985496cc01d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -138,11 +138,6 @@ struct fw_img { u32 paging_mem_size; }; -struct iwl_sf_region { - u32 addr; - u32 size; -}; - /* * Block paging calculations */ @@ -257,7 +252,6 @@ enum iwl_fw_type { * @type: firmware type (&enum iwl_fw_type) * @cipher_scheme: optional external cipher scheme. * @human_readable: human readable version - * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until * we get the ALIVE from the uCode * @dbg_dest_tlv: points to the destination TLV for debug * @dbg_conf_tlv: array of pointers to configuration TLVs for debug @@ -290,8 +284,6 @@ struct iwl_fw { struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS]; u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; - u32 sdio_adma_addr; - struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX]; size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX]; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c index 1610722b8099..1fec8e3a6b35 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c @@ -87,9 +87,6 @@ void iwl_free_fw_paging(struct iwl_fw_runtime *fwrt) get_order(paging->fw_paging_size)); paging->fw_paging_block = NULL; } - kfree(fwrt->trans->paging_download_buf); - fwrt->trans->paging_download_buf = NULL; - fwrt->trans->paging_db = NULL; memset(fwrt->fw_paging_db, 0, sizeof(fwrt->fw_paging_db)); } @@ -100,13 +97,11 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt, { struct page *block; dma_addr_t phys = 0; - int blk_idx, order, num_of_pages, size, dma_enabled; + int blk_idx, order, num_of_pages, size; if (fwrt->fw_paging_db[0].fw_paging_block) return 0; - dma_enabled = is_device_dma_capable(fwrt->trans->dev); - /* ensure BLOCK_2_EXP_SIZE is power of 2 of PAGING_BLOCK_SIZE */ BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE); @@ -139,24 +134,18 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt, fwrt->fw_paging_db[blk_idx].fw_paging_block = block; fwrt->fw_paging_db[blk_idx].fw_paging_size = size; - if (dma_enabled) { - phys = dma_map_page(fwrt->trans->dev, block, 0, - PAGE_SIZE << order, - DMA_BIDIRECTIONAL); - if (dma_mapping_error(fwrt->trans->dev, phys)) { - /* - * free the previous pages and the current one - * since we failed to map_page. - */ - iwl_free_fw_paging(fwrt); - return -ENOMEM; - } - fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys; - } else { - fwrt->fw_paging_db[blk_idx].fw_paging_phys = - PAGING_ADDR_SIG | - blk_idx << BLOCK_2_EXP_SIZE; + phys = dma_map_page(fwrt->trans->dev, block, 0, + PAGE_SIZE << order, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(fwrt->trans->dev, phys)) { + /* + * free the previous pages and the current one + * since we failed to map_page. + */ + iwl_free_fw_paging(fwrt); + return -ENOMEM; } + fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys; if (!blk_idx) IWL_DEBUG_FW(fwrt, @@ -312,60 +301,6 @@ static int iwl_send_paging_cmd(struct iwl_fw_runtime *fwrt, return iwl_trans_send_cmd(fwrt->trans, &hcmd); } -/* - * Send paging item cmd to FW in case CPU2 has paging image - */ -static int iwl_trans_get_paging_item(struct iwl_fw_runtime *fwrt) -{ - int ret; - struct iwl_fw_get_item_cmd fw_get_item_cmd = { - .item_id = cpu_to_le32(IWL_FW_ITEM_ID_PAGING), - }; - struct iwl_fw_get_item_resp *item_resp; - struct iwl_host_cmd cmd = { - .id = iwl_cmd_id(FW_GET_ITEM_CMD, IWL_ALWAYS_LONG_GROUP, 0), - .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL, - .data = { &fw_get_item_cmd, }, - .len = { sizeof(fw_get_item_cmd), }, - }; - - ret = iwl_trans_send_cmd(fwrt->trans, &cmd); - if (ret) { - IWL_ERR(fwrt, - "Paging: Failed to send FW_GET_ITEM_CMD cmd (err = %d)\n", - ret); - return ret; - } - - item_resp = (void *)((struct iwl_rx_packet *)cmd.resp_pkt)->data; - if (item_resp->item_id != cpu_to_le32(IWL_FW_ITEM_ID_PAGING)) { - IWL_ERR(fwrt, - "Paging: got wrong item in FW_GET_ITEM_CMD resp (item_id = %u)\n", - le32_to_cpu(item_resp->item_id)); - ret = -EIO; - goto exit; - } - - /* Add an extra page for headers */ - fwrt->trans->paging_download_buf = kzalloc(PAGING_BLOCK_SIZE + - FW_PAGING_SIZE, - GFP_KERNEL); - if (!fwrt->trans->paging_download_buf) { - ret = -ENOMEM; - goto exit; - } - fwrt->trans->paging_req_addr = le32_to_cpu(item_resp->item_val); - fwrt->trans->paging_db = fwrt->fw_paging_db; - IWL_DEBUG_FW(fwrt, - "Paging: got paging request address (paging_req_addr 0x%08x)\n", - fwrt->trans->paging_req_addr); - -exit: - iwl_free_resp(&cmd); - - return ret; -} - int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) { const struct fw_img *fw = &fwrt->fw->img[type]; @@ -382,20 +317,6 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) if (!fw->paging_mem_size) return 0; - /* - * When dma is not enabled, the driver needs to copy / write - * the downloaded / uploaded page to / from the smem. - * This gets the location of the place were the pages are - * stored. - */ - if (!is_device_dma_capable(fwrt->trans->dev)) { - ret = iwl_trans_get_paging_item(fwrt); - if (ret) { - IWL_ERR(fwrt, "failed to get FW paging item\n"); - return ret; - } - } - ret = iwl_save_fw_paging(fwrt, fw); if (ret) { IWL_ERR(fwrt, "failed to save the FW paging image\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 86a796025750..d1263a554420 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -467,9 +467,6 @@ extern const struct iwl_cfg iwl8260_2ac_cfg; extern const struct iwl_cfg iwl8265_2ac_cfg; extern const struct iwl_cfg iwl8275_2ac_cfg; extern const struct iwl_cfg iwl4165_2ac_cfg; -extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; -extern const struct iwl_cfg iwl8265_2ac_sdio_cfg; -extern const struct iwl_cfg iwl4165_2ac_sdio_cfg; extern const struct iwl_cfg iwl9160_2ac_cfg; extern const struct iwl_cfg iwl9260_2ac_cfg; extern const struct iwl_cfg iwl9270_2ac_cfg; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index b03e0f975b5a..4f0d070eda54 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -218,7 +218,6 @@ #define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ #define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */ #define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ -#define CSR_INT_BIT_PAGING (1 << 24) /* SDIO PAGING */ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ #define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */ @@ -229,7 +228,6 @@ CSR_INT_BIT_HW_ERR | \ CSR_INT_BIT_FH_TX | \ CSR_INT_BIT_SW_ERR | \ - CSR_INT_BIT_PAGING | \ CSR_INT_BIT_RF_KILL | \ CSR_INT_BIT_SW_RX | \ CSR_INT_BIT_WAKEUP | \ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index ccdb247d68c5..4b224d7d967c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1039,12 +1039,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, drv->fw.img[usniffer_img].paging_mem_size = paging_mem_size; break; - case IWL_UCODE_TLV_SDIO_ADMA_ADDR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - drv->fw.sdio_adma_addr = - le32_to_cpup((__le32 *)tlv_data); - break; case IWL_UCODE_TLV_FW_GSCAN_CAPA: /* * Don't return an error in case of a shorter tlv_len diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index bba4f54cbbbb..ca0b5536a8a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -398,8 +398,6 @@ struct iwl_hcmd_arr { * @command_groups: array of command groups, each member is an array of the * commands in the group; for debugging only * @command_groups_size: number of command groups, to avoid illegal access - * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until - * we get the ALIVE from the uCode * @cb_data_offs: offset inside skb->cb to store transport data at, must have * space for at least two pointers */ @@ -419,8 +417,6 @@ struct iwl_trans_config { const struct iwl_hcmd_arr *command_groups; int command_groups_size; - u32 sdio_adma_addr; - u8 cb_data_offs; }; @@ -524,6 +520,9 @@ struct iwl_trans_txq_scd_cfg { * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last * TX'ed commands and similar. The buffer will be vfree'd by the caller. * Note that the transport must fill in the proper file headers. + * @dump_regs: dump using IWL_ERR configuration space and memory mapped + * registers of the device to diagnose failure, e.g., when HW becomes + * inaccessible. */ struct iwl_trans_ops { @@ -531,8 +530,6 @@ struct iwl_trans_ops { void (*op_mode_leave)(struct iwl_trans *iwl_trans); int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill); - int (*update_sf)(struct iwl_trans *trans, - struct iwl_sf_region *st_fwrd_space); void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); void (*stop_device)(struct iwl_trans *trans, bool low_power); @@ -593,6 +590,8 @@ struct iwl_trans_ops { struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans, const struct iwl_fw_dbg_trigger_tlv *trigger); + + void (*dump_regs)(struct iwl_trans *trans); }; /** @@ -700,12 +699,6 @@ enum iwl_plat_pm_mode { * @dbg_conf_tlv: array of pointers to configuration TLVs for debug * @dbg_trigger_tlv: array of pointers to triggers TLVs for debug * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv - * @paging_req_addr: The location were the FW will upload / download the pages - * from. The address is set by the opmode - * @paging_db: Pointer to the opmode paging data base, the pointer is set by - * the opmode. - * @paging_download_buf: Buffer used for copying all of the pages before - * downloading them to the FW. The buffer is allocated in the opmode * @system_pm_mode: the system-wide power management mode in use. * This mode is set dynamically, depending on the WoWLAN values * configured from the userspace at runtime. @@ -754,14 +747,6 @@ struct iwl_trans { struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv; u8 dbg_dest_reg_num; - /* - * Paging parameters - All of the parameters should be set by the - * opmode when paging is enabled - */ - u32 paging_req_addr; - struct iwl_fw_paging *paging_db; - void *paging_download_buf; - enum iwl_plat_pm_mode system_pm_mode; enum iwl_plat_pm_mode runtime_pm_mode; bool suspending; @@ -828,17 +813,6 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, return trans->ops->start_fw(trans, fw, run_in_rfkill); } -static inline int iwl_trans_update_sf(struct iwl_trans *trans, - struct iwl_sf_region *st_fwrd_space) -{ - might_sleep(); - - if (trans->ops->update_sf) - return trans->ops->update_sf(trans, st_fwrd_space); - - return 0; -} - static inline void _iwl_trans_stop_device(struct iwl_trans *trans, bool low_power) { @@ -896,6 +870,12 @@ iwl_trans_dump_data(struct iwl_trans *trans, return trans->ops->dump_data(trans, trigger); } +static inline void iwl_trans_dump_regs(struct iwl_trans *trans) +{ + if (trans->ops->dump_regs) + trans->ops->dump_regs(trans); +} + static inline struct iwl_device_cmd * iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 0296df625cd5..c0de7bb86cf7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -196,8 +196,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, mvm->error_event_table[1] = le32_to_cpu(lmac2->error_event_table_ptr); mvm->log_event_table = le32_to_cpu(lmac1->log_event_table_ptr); - mvm->sf_space.addr = le32_to_cpu(lmac1->st_fwrd_addr); - mvm->sf_space.size = le32_to_cpu(lmac1->st_fwrd_size); umac_error_event_table = le32_to_cpu(umac->error_info_addr); @@ -266,7 +264,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, int ret, i; enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; static const u16 alive_cmd[] = { MVM_ALIVE }; - struct iwl_sf_region st_fwrd_space; if (ucode_type == IWL_UCODE_REGULAR && iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) && @@ -320,18 +317,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, return -EIO; } - /* - * update the sdio allocation according to the pointer we get in the - * alive notification. - */ - st_fwrd_space.addr = mvm->sf_space.addr; - st_fwrd_space.size = mvm->sf_space.size; - ret = iwl_trans_update_sf(mvm->trans, &st_fwrd_space); - if (ret) { - IWL_ERR(mvm, "Failed to update SF size. ret %d\n", ret); - return ret; - } - iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr); /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 0b3d275fe177..3e92a117c0b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4002,39 +4002,36 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop) { - if (drop) { - if (iwl_mvm_has_new_tx_api(mvm)) - /* TODO new tx api */ - WARN_ONCE(1, - "Need to implement flush TX queue\n"); - else - iwl_mvm_flush_tx_path(mvm, - iwl_mvm_flushable_queues(mvm) & queues, - 0); - } else { - if (iwl_mvm_has_new_tx_api(mvm)) { - struct ieee80211_sta *sta; - int i; + int i; + if (!iwl_mvm_has_new_tx_api(mvm)) { + if (drop) { mutex_lock(&mvm->mutex); - - for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { - sta = rcu_dereference_protected( - mvm->fw_id_to_mac_id[i], - lockdep_is_held(&mvm->mutex)); - if (IS_ERR_OR_NULL(sta)) - continue; - - iwl_mvm_wait_sta_queues_empty(mvm, - iwl_mvm_sta_from_mac80211(sta)); - } - + iwl_mvm_flush_tx_path(mvm, + iwl_mvm_flushable_queues(mvm) & queues, 0); mutex_unlock(&mvm->mutex); } else { - iwl_trans_wait_tx_queues_empty(mvm->trans, - queues); + iwl_trans_wait_tx_queues_empty(mvm->trans, queues); } + return; } + + mutex_lock(&mvm->mutex); + for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { + struct ieee80211_sta *sta; + + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(sta)) + continue; + + if (drop) + iwl_mvm_flush_sta_tids(mvm, i, 0xFF, 0); + else + iwl_mvm_wait_sta_queues_empty(mvm, + iwl_mvm_sta_from_mac80211(sta)); + } + mutex_unlock(&mvm->mutex); } static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, @@ -4294,9 +4291,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, lockdep_assert_held(&mvm->mutex); - /* TODO - remove a000 disablement when we have RXQ config API */ - if (!iwl_mvm_has_new_rx_api(mvm) || - mvm->trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) + if (!iwl_mvm_has_new_rx_api(mvm)) return; notif->cookie = mvm->queue_sync_cookie; @@ -4305,6 +4300,13 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, atomic_set(&mvm->queue_sync_counter, mvm->trans->num_rx_queues); + /* TODO - remove this when we have RXQ config API */ + if (mvm->trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) { + qmask = BIT(0); + if (notif->sync) + atomic_set(&mvm->queue_sync_counter, 1); + } + ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size); if (ret) { IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index e34b3eb8e08b..0e18c5066f04 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -652,6 +652,7 @@ struct iwl_mvm_baid_data { u16 entries_per_queue; unsigned long last_rx; struct timer_list session_timer; + struct iwl_mvm_baid_data __rcu **rcu_ptr; struct iwl_mvm *mvm; struct iwl_mvm_reorder_buffer reorder_buf[IWL_MAX_RX_HW_QUEUES]; struct iwl_mvm_reorder_buf_entry entries[]; @@ -754,7 +755,6 @@ struct iwl_mvm { u32 log_event_table; u32 umac_error_event_table; bool support_umac_log; - struct iwl_sf_region sf_space; u32 ampdu_ref; bool ampdu_toggle; @@ -1854,7 +1854,7 @@ void iwl_mvm_tdls_ch_switch_work(struct work_struct *work); void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, struct iwl_mvm_internal_rxq_notif *notif, u32 size); -void iwl_mvm_reorder_timer_expired(unsigned long data); +void iwl_mvm_reorder_timer_expired(struct timer_list *t); struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e82b4462722b..ce718e9c63ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -703,7 +703,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info, driver_data[2]); - trans_cfg.sdio_adma_addr = fw->sdio_adma_addr; trans_cfg.sw_csum_tx = IWL_MVM_SW_TX_CSUM_OFFLOAD; /* Set a short watchdog for the command queue */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 0fe723ca844e..c69515ed72df 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -67,12 +67,8 @@ static u8 rs_ht_to_legacy[] = { static const u8 ant_toggle_lookup[] = { [ANT_NONE] = ANT_NONE, [ANT_A] = ANT_B, - [ANT_B] = ANT_C, - [ANT_AB] = ANT_BC, - [ANT_C] = ANT_A, - [ANT_AC] = ANT_AB, - [ANT_BC] = ANT_AC, - [ANT_ABC] = ANT_ABC, + [ANT_B] = ANT_A, + [ANT_AB] = ANT_AB, }; #define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ @@ -975,7 +971,7 @@ static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate) { u8 new_ant_type; - if (!rate->ant || rate->ant > ANT_ABC) + if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C)) return 0; if (!rs_is_valid_ant(valid_ant, rate->ant)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index b84756dc9d6c..76dc58381e1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -460,9 +460,9 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm, } } -void iwl_mvm_reorder_timer_expired(unsigned long data) +void iwl_mvm_reorder_timer_expired(struct timer_list *t) { - struct iwl_mvm_reorder_buffer *buf = (void *)data; + struct iwl_mvm_reorder_buffer *buf = from_timer(buf, t, reorder_timer); struct iwl_mvm_baid_data *baid_data = iwl_mvm_baid_data_from_reorder_buf(buf); struct iwl_mvm_reorder_buf_entry *entries = @@ -719,6 +719,22 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, return false; } + /* + * release immediately if there are no stored frames, and the sn is + * equal to the head. + * This can happen due to reorder timer, where NSSN is behind head_sn. + * When we released everything, and we got the next frame in the + * sequence, according to the NSSN we can't release immediately, + * while technically there is no hole and we can move forward. + */ + if (!buffer->num_stored && sn == buffer->head_sn) { + if (!amsdu || last_subframe) + buffer->head_sn = ieee80211_sn_inc(buffer->head_sn); + /* No need to update AMSDU last SN - we are moving the head */ + spin_unlock_bh(&buffer->lock); + return false; + } + index = sn % buffer->buf_size; /* @@ -818,6 +834,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct sk_buff *skb; u8 crypt_len = 0; + if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) + return; + /* Dont use dev_alloc_skb(), we'll have enough headroom once * ieee80211_hdr pulled. */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 23787cc9c89e..c19f98489d4e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -252,9 +252,11 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, return ret; } -static void iwl_mvm_rx_agg_session_expired(unsigned long data) +static void iwl_mvm_rx_agg_session_expired(struct timer_list *t) { - struct iwl_mvm_baid_data __rcu **rcu_ptr = (void *)data; + struct iwl_mvm_baid_data *data = + from_timer(data, t, session_timer); + struct iwl_mvm_baid_data __rcu **rcu_ptr = data->rcu_ptr; struct iwl_mvm_baid_data *ba_data; struct ieee80211_sta *sta; struct iwl_mvm_sta *mvm_sta; @@ -644,8 +646,7 @@ int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, /* Redirect to lower AC */ iwl_mvm_reconfig_scd(mvm, queue, iwl_mvm_ac_to_tx_fifo[ac], - cmd.sta_id, tid, LINK_QUAL_AGG_FRAME_LIMIT_DEF, - ssn); + cmd.sta_id, tid, IWL_FRAME_LIMIT, ssn); /* Update AC marking of the queue */ spin_lock_bh(&mvm->queue_info_lock); @@ -1258,6 +1259,14 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm, mvm_sta->sta_id, i, wdg_timeout); tid_data->txq_id = txq_id; + + /* + * Since we don't set the seq number after reset, and HW + * sets it now, FW reset will cause the seq num to start + * at 0 again, so driver will need to update it + * internally as well, so it keeps in sync with real val + */ + tid_data->seq_number = 0; } else { u16 seq = IEEE80211_SEQ_TO_SN(tid_data->seq_number); @@ -2153,10 +2162,8 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm, reorder_buf->head_sn = ssn; reorder_buf->buf_size = buf_size; /* rx reorder timer */ - reorder_buf->reorder_timer.function = - iwl_mvm_reorder_timer_expired; - reorder_buf->reorder_timer.data = (unsigned long)reorder_buf; - init_timer(&reorder_buf->reorder_timer); + timer_setup(&reorder_buf->reorder_timer, + iwl_mvm_reorder_timer_expired, 0); spin_lock_init(&reorder_buf->lock); reorder_buf->mvm = mvm; reorder_buf->queue = i; @@ -2279,9 +2286,9 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, baid_data->baid = baid; baid_data->timeout = timeout; baid_data->last_rx = jiffies; - setup_timer(&baid_data->session_timer, - iwl_mvm_rx_agg_session_expired, - (unsigned long)&mvm->baid_map[baid]); + baid_data->rcu_ptr = &mvm->baid_map[baid]; + timer_setup(&baid_data->session_timer, + iwl_mvm_rx_agg_session_expired, 0); baid_data->mvm = mvm; baid_data->tid = tid; baid_data->sta_id = mvm_sta->sta_id; @@ -2544,12 +2551,6 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE) != IWL_MAX_TID_COUNT); - if (!mvm->trans->cfg->gen2) - buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); - else - buf_size = min_t(int, buf_size, - LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF); - spin_lock_bh(&mvmsta->lock); ssn = tid_data->ssn; queue = tid_data->txq_id; @@ -2561,10 +2562,17 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (iwl_mvm_has_new_tx_api(mvm)) { /* - * If no queue iwl_mvm_sta_tx_agg_start() would have failed so - * no need to check queue's status + * If there is no queue for this tid, iwl_mvm_sta_tx_agg_start() + * would have failed, so if we are here there is no need to + * allocate a queue. + * However, if aggregation size is different than the default + * size, the scheduler should be reconfigured. + * We cannot do this with the new TX API, so return unsupported + * for now, until it will be offloaded to firmware.. + * Note that if SCD default value changes - this condition + * should be updated as well. */ - if (buf_size < mvmsta->max_agg_bufsize) + if (buf_size < IWL_FRAME_LIMIT) return -ENOTSUPP; ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true); @@ -2587,7 +2595,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * Only reconfig the SCD for the queue if the window size has * changed from current (become smaller) */ - if (!alloc_queue && buf_size < mvmsta->max_agg_bufsize) { + if (!alloc_queue && buf_size < IWL_FRAME_LIMIT) { /* * If reconfiguring an existing queue, it first must be * drained diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 00a0efab20e3..d88c3685a6dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1594,8 +1594,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, mvmsta->tid_data[tid].tx_time = le16_to_cpu(tx_resp->wireless_media_time); mvmsta->tid_data[tid].lq_color = - (tx_resp->tlc_info & TX_RES_RATE_TABLE_COLOR_MSK) >> - TX_RES_RATE_TABLE_COLOR_POS; + TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info); } rcu_read_unlock(); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index aa3c07192624..4a21c12276d7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -467,6 +467,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0xC030, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0xD030, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8260_2ac_cfg)}, @@ -485,6 +487,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x4010, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, @@ -510,6 +513,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24FD, 0x3E01, iwl8275_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x1012, iwl8275_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0012, iwl8275_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0014, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, /* 9000 Series */ {IWL_PCI_DEVICE(0x2526, 0x0000, iwl9260_2ac_cfg)}, @@ -581,6 +586,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0030, iwla000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0090, iwla000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x2720, 0x0310, iwla000_2ac_cfg_hr_cdb)}, + {IWL_PCI_DEVICE(0x40C0, 0x0000, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwla000_2ax_cfg_hr)}, + #endif /* CONFIG_IWLMVM */ {0} diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 0008ea323be3..8d992d5ba064 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -88,7 +88,7 @@ #define IWL_FW_MEM_EXTENDED_START 0x40000 #define IWL_FW_MEM_EXTENDED_END 0x57FFF -static void iwl_trans_pcie_err_dump(struct iwl_trans *trans) +static void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) { #define PCI_DUMP_SIZE 64 #define PREFIX_LEN 32 @@ -736,7 +736,7 @@ static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, trans_pcie->ucode_write_complete, 5 * HZ); if (!ret) { IWL_ERR(trans, "Failed to load firmware chunk!\n"); - iwl_trans_pcie_err_dump(trans); + iwl_trans_pcie_dump_regs(trans); return -ETIMEDOUT; } @@ -1956,7 +1956,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (unlikely(ret < 0)) { - iwl_trans_pcie_err_dump(trans); + iwl_trans_pcie_dump_regs(trans); iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); WARN_ONCE(1, "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", @@ -3021,6 +3021,7 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans) .ref = iwl_trans_pcie_ref, \ .unref = iwl_trans_pcie_unref, \ .dump_data = iwl_trans_pcie_dump_data, \ + .dump_regs = iwl_trans_pcie_dump_regs, \ .d3_suspend = iwl_trans_pcie_d3_suspend, \ .d3_resume = iwl_trans_pcie_d3_resume diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index e93c471ef9bf..b5c459cd70ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1909,6 +1909,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, } if (test_bit(STATUS_FW_ERROR, &trans->status)) { + iwl_trans_dump_regs(trans); IWL_ERR(trans, "FW error in SYNC CMD %s\n", iwl_get_cmd_string(trans, cmd->id)); dump_stack(); diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c index 56f6e3b71f48..501180584b4b 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c @@ -1457,7 +1457,6 @@ static void ezusb_bulk_in_callback(struct urb *urb) static inline void ezusb_delete(struct ezusb_priv *upriv) { - struct net_device *dev; struct list_head *item; struct list_head *tmp_item; unsigned long flags; @@ -1465,7 +1464,6 @@ static inline void ezusb_delete(struct ezusb_priv *upriv) BUG_ON(in_interrupt()); BUG_ON(!upriv); - dev = upriv->dev; mutex_lock(&upriv->mtx); upriv->udev = NULL; /* No timer will be rearmed from here */ diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index e70f5bd5e498..7d6dc76c930a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -217,10 +217,10 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, int ret = 0; if (!info->beacon_ies || !info->beacon_ies_len) { - ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON, + ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES, NULL, 0); } else { - ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON, + ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES, info->beacon_ies, info->beacon_ies_len); } @@ -230,11 +230,11 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, if (!info->proberesp_ies || !info->proberesp_ies_len) { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_PROBE_RESP, + QLINK_IE_SET_PROBE_RESP_IES, NULL, 0); } else { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_PROBE_RESP, + QLINK_IE_SET_PROBE_RESP_IES, info->proberesp_ies, info->proberesp_ies_len); } @@ -244,11 +244,11 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, if (!info->assocresp_ies || !info->assocresp_ies_len) { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_ASSOC_RESP, + QLINK_IE_SET_ASSOC_RESP, NULL, 0); } else { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_ASSOC_RESP, + QLINK_IE_SET_ASSOC_RESP, info->assocresp_ies, info->assocresp_ies_len); } @@ -271,26 +271,11 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev, struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); int ret; - ret = qtnf_cmd_send_config_ap(vif, settings); - if (ret) { - pr_err("VIF%u.%u: failed to push config to FW\n", - vif->mac->macid, vif->vifid); - goto out; - } - - ret = qtnf_mgmt_set_appie(vif, &settings->beacon); - if (ret) { - pr_err("VIF%u.%u: failed to add IEs to beacon\n", - vif->mac->macid, vif->vifid); - goto out; - } - - ret = qtnf_cmd_send_start_ap(vif); + ret = qtnf_cmd_send_start_ap(vif, settings); if (ret) pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid, vif->vifid); -out: return ret; } @@ -823,8 +808,7 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in, if (!wiphy->bands[band]) continue; - ret = qtnf_cmd_get_mac_chan_info(mac, - wiphy->bands[band]); + ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]); if (ret) pr_err("failed to get chan info for mac %u band %u\n", mac_idx, band); @@ -832,33 +816,6 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in, } } -void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo, - struct ieee80211_supported_band *band) -{ - struct ieee80211_sta_ht_cap *ht_cap; - struct ieee80211_sta_vht_cap *vht_cap; - - ht_cap = &band->ht_cap; - ht_cap->ht_supported = true; - memcpy(&ht_cap->cap, &macinfo->ht_cap.cap_info, - sizeof(u16)); - ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; - memcpy(&ht_cap->mcs, &macinfo->ht_cap.mcs, - sizeof(ht_cap->mcs)); - - if (macinfo->phymode_cap & QLINK_PHYMODE_AC) { - vht_cap = &band->vht_cap; - vht_cap->vht_supported = true; - memcpy(&vht_cap->cap, - &macinfo->vht_cap.vht_cap_info, sizeof(u32)); - /* Update MCS support for VHT */ - memcpy(&vht_cap->vht_mcs, - &macinfo->vht_cap.supp_mcs, - sizeof(struct ieee80211_vht_mcs_info)); - } -} - struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus) { struct wiphy *wiphy; @@ -919,9 +876,6 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) if (ret) goto out; - pr_info("MAC%u: phymode=%#x radar=%#x\n", mac->macid, - mac->macinfo.phymode_cap, mac->macinfo.radar_detect_widths); - wiphy->frag_threshold = mac->macinfo.frag_thr; wiphy->rts_threshold = mac->macinfo.rts_thr; wiphy->retry_short = mac->macinfo.sretry_limit; @@ -953,6 +907,8 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) wiphy->available_antennas_rx = mac->macinfo.num_rx_chain; wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta; + wiphy->ht_capa_mod_mask = &mac->macinfo.ht_cap_mod_mask; + wiphy->vht_capa_mod_mask = &mac->macinfo.vht_cap_mod_mask; ether_addr_copy(wiphy->perm_addr, mac->macaddr); diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index b81f81bd1411..8bc8dd637315 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -147,56 +147,66 @@ static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no, return cmd_skb; } -int qtnf_cmd_send_start_ap(struct qtnf_vif *vif) +static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type, + const u8 *buf, size_t len) { - struct sk_buff *cmd_skb; - u16 res_code = QLINK_CMD_RESULT_OK; - int ret; + struct qlink_tlv_ie_set *tlv; - cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, - QLINK_CMD_START_AP, - sizeof(struct qlink_cmd)); - if (unlikely(!cmd_skb)) - return -ENOMEM; + tlv = (struct qlink_tlv_ie_set *)skb_put(cmd_skb, sizeof(*tlv) + len); + tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_IE_SET); + tlv->hdr.len = cpu_to_le16(len + sizeof(*tlv) - sizeof(tlv->hdr)); + tlv->type = frame_type; + tlv->flags = 0; - qtnf_bus_lock(vif->mac->bus); - - ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); - - if (unlikely(ret)) - goto out; - - if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { - pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, - vif->vifid, res_code); - ret = -EFAULT; - goto out; - } - - netif_carrier_on(vif->netdev); - -out: - qtnf_bus_unlock(vif->mac->bus); - return ret; + if (len && buf) + memcpy(tlv->ie_data, buf, len); } -int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, - const struct cfg80211_ap_settings *s) +static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif *vif, + const struct cfg80211_ap_settings *s) +{ + unsigned int len = sizeof(struct qlink_cmd_start_ap); + + len += s->ssid_len; + len += s->beacon.head_len; + len += s->beacon.tail_len; + len += s->beacon.beacon_ies_len; + len += s->beacon.proberesp_ies_len; + len += s->beacon.assocresp_ies_len; + len += s->beacon.probe_resp_len; + + if (cfg80211_chandef_valid(&s->chandef)) + len += sizeof(struct qlink_tlv_chandef); + + if (len > (sizeof(struct qlink_cmd) + QTNF_MAX_CMD_BUF_SIZE)) { + pr_err("VIF%u.%u: can not fit AP settings: %u\n", + vif->mac->macid, vif->vifid, len); + return false; + } + + return true; +} + +int qtnf_cmd_send_start_ap(struct qtnf_vif *vif, + const struct cfg80211_ap_settings *s) { struct sk_buff *cmd_skb; - struct qlink_cmd_config_ap *cmd; + struct qlink_cmd_start_ap *cmd; struct qlink_auth_encr *aen; u16 res_code = QLINK_CMD_RESULT_OK; int ret; int i; + if (!qtnf_cmd_start_ap_can_fit(vif, s)) + return -E2BIG; + cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, - QLINK_CMD_CONFIG_AP, + QLINK_CMD_START_AP, sizeof(*cmd)); if (unlikely(!cmd_skb)) return -ENOMEM; - cmd = (struct qlink_cmd_config_ap *)cmd_skb->data; + cmd = (struct qlink_cmd_start_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); @@ -211,7 +221,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, 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); @@ -241,6 +250,39 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, qlink_chandef_cfg2q(&s->chandef, &chtlv->chan); } + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_HEAD, + s->beacon.head, s->beacon.head_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_TAIL, + s->beacon.tail, s->beacon.tail_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_IES, + s->beacon.beacon_ies, s->beacon.beacon_ies_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP, + s->beacon.probe_resp, s->beacon.probe_resp_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP_IES, + s->beacon.proberesp_ies, + s->beacon.proberesp_ies_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_RESP, + s->beacon.assocresp_ies, + s->beacon.assocresp_ies_len); + + if (s->ht_cap) { + struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *) + skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->ht_cap)); + + tlv->type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); + tlv->len = cpu_to_le16(sizeof(*s->ht_cap)); + memcpy(tlv->val, s->ht_cap, sizeof(*s->ht_cap)); + } + + if (s->vht_cap) { + struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *) + skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->vht_cap)); + + tlv->type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY); + tlv->len = cpu_to_le16(sizeof(*s->vht_cap)); + memcpy(tlv->val, s->vht_cap, sizeof(*s->vht_cap)); + } + qtnf_bus_lock(vif->mac->bus); ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); @@ -255,6 +297,8 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, goto out; } + netif_carrier_on(vif->netdev); + out: qtnf_bus_unlock(vif->mac->bus); return ret; @@ -380,11 +424,10 @@ int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type, const u8 *buf, size_t len) { struct sk_buff *cmd_skb; - struct qlink_cmd_mgmt_append_ie *cmd; u16 res_code = QLINK_CMD_RESULT_OK; int ret; - if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) { + if (len > QTNF_MAX_CMD_BUF_SIZE) { pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid, vif->vifid, frame_type, len); return -E2BIG; @@ -392,22 +435,14 @@ int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type, cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, QLINK_CMD_MGMT_SET_APPIE, - sizeof(*cmd)); + sizeof(struct qlink_cmd)); if (unlikely(!cmd_skb)) return -ENOMEM; + qtnf_cmd_tlv_ie_set_add(cmd_skb, frame_type, buf, len); + qtnf_bus_lock(vif->mac->bus); - cmd = (struct qlink_cmd_mgmt_append_ie *)cmd_skb->data; - cmd->type = frame_type; - cmd->flags = 0; - - /* If len == 0 then IE buf for specified frame type - * should be cleared on EP. - */ - if (len && buf) - qtnf_cmd_skb_put_buffer(cmd_skb, buf, len); - ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); if (unlikely(ret)) @@ -1090,7 +1125,6 @@ qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, mac_info = &mac->macinfo; mac_info->bands_cap = resp_info->bands_cap; - mac_info->phymode_cap = resp_info->phymode_cap; memcpy(&mac_info->dev_mac, &resp_info->dev_mac, sizeof(mac_info->dev_mac)); @@ -1110,24 +1144,56 @@ qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, qlink_chan_width_mask_to_nl(le16_to_cpu( resp_info->radar_detect_widths)); - memcpy(&mac_info->ht_cap, &resp_info->ht_cap, sizeof(mac_info->ht_cap)); - memcpy(&mac_info->vht_cap, &resp_info->vht_cap, - sizeof(mac_info->vht_cap)); + memcpy(&mac_info->ht_cap_mod_mask, &resp_info->ht_cap_mod_mask, + sizeof(mac_info->ht_cap_mod_mask)); + memcpy(&mac_info->vht_cap_mod_mask, &resp_info->vht_cap_mod_mask, + sizeof(mac_info->vht_cap_mod_mask)); +} + +static void qtnf_cmd_resp_band_fill_htcap(const u8 *info, + struct ieee80211_sta_ht_cap *bcap) +{ + const struct ieee80211_ht_cap *ht_cap = + (const struct ieee80211_ht_cap *)info; + + bcap->ht_supported = true; + bcap->cap = le16_to_cpu(ht_cap->cap_info); + bcap->ampdu_factor = + ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR; + bcap->ampdu_density = + (ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> + IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; + memcpy(&bcap->mcs, &ht_cap->mcs, sizeof(bcap->mcs)); +} + +static void qtnf_cmd_resp_band_fill_vhtcap(const u8 *info, + struct ieee80211_sta_vht_cap *bcap) +{ + const struct ieee80211_vht_cap *vht_cap = + (const struct ieee80211_vht_cap *)info; + + bcap->vht_supported = true; + bcap->cap = le32_to_cpu(vht_cap->vht_cap_info); + memcpy(&bcap->vht_mcs, &vht_cap->supp_mcs, sizeof(bcap->vht_mcs)); } static int -qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, - struct qlink_resp_get_chan_info *resp, - size_t payload_len) +qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band, + struct qlink_resp_band_info_get *resp, + size_t payload_len) { u16 tlv_type; size_t tlv_len; + size_t tlv_dlen; const struct qlink_tlv_hdr *tlv; const struct qlink_tlv_channel *qchan; struct ieee80211_channel *chan; unsigned int chidx = 0; u32 qflags; + memset(&band->ht_cap, 0, sizeof(band->ht_cap)); + memset(&band->vht_cap, 0, sizeof(band->vht_cap)); + if (band->channels) { if (band->n_channels == resp->num_chans) { memset(band->channels, 0, @@ -1155,7 +1221,8 @@ qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, while (payload_len >= sizeof(*tlv)) { tlv_type = le16_to_cpu(tlv->type); - tlv_len = le16_to_cpu(tlv->len) + sizeof(*tlv); + tlv_dlen = le16_to_cpu(tlv->len); + tlv_len = tlv_dlen + sizeof(*tlv); if (tlv_len > payload_len) { pr_warn("malformed TLV 0x%.2X; LEN: %zu\n", @@ -1241,13 +1308,32 @@ qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, chan->hw_value, chan->flags, chan->max_power, chan->max_reg_power); break; + case WLAN_EID_HT_CAPABILITY: + if (unlikely(tlv_dlen != + sizeof(struct ieee80211_ht_cap))) { + pr_err("bad HTCAP TLV len %zu\n", tlv_dlen); + goto error_ret; + } + + qtnf_cmd_resp_band_fill_htcap(tlv->val, &band->ht_cap); + break; + case WLAN_EID_VHT_CAPABILITY: + if (unlikely(tlv_dlen != + sizeof(struct ieee80211_vht_cap))) { + pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen); + goto error_ret; + } + + qtnf_cmd_resp_band_fill_vhtcap(tlv->val, + &band->vht_cap); + break; default: pr_warn("unknown TLV type: %#x\n", tlv_type); break; } payload_len -= tlv_len; - tlv = (struct qlink_tlv_hdr *)((u8 *)tlv + tlv_len); + tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_dlen); } if (payload_len) { @@ -1469,13 +1555,13 @@ int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) return ret; } -int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, - struct ieee80211_supported_band *band) +int qtnf_cmd_band_info_get(struct qtnf_wmac *mac, + struct ieee80211_supported_band *band) { struct sk_buff *cmd_skb, *resp_skb = NULL; size_t info_len; - struct qlink_cmd_chans_info_get *cmd; - struct qlink_resp_get_chan_info *resp; + struct qlink_cmd_band_info_get *cmd; + struct qlink_resp_band_info_get *resp; u16 res_code = QLINK_CMD_RESULT_OK; int ret = 0; u8 qband; @@ -1495,12 +1581,12 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, } cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, - QLINK_CMD_CHANS_INFO_GET, + QLINK_CMD_BAND_INFO_GET, sizeof(*cmd)); if (!cmd_skb) return -ENOMEM; - cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data; + cmd = (struct qlink_cmd_band_info_get *)cmd_skb->data; cmd->band = qband; qtnf_bus_lock(mac->bus); @@ -1517,7 +1603,7 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, goto out; } - resp = (struct qlink_resp_get_chan_info *)resp_skb->data; + resp = (struct qlink_resp_band_info_get *)resp_skb->data; if (resp->band != qband) { pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, resp->band, qband); @@ -1525,7 +1611,7 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, goto out; } - ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len); + ret = qtnf_cmd_resp_fill_band_info(band, resp, info_len); out: qtnf_bus_unlock(mac->bus); @@ -1942,17 +2028,36 @@ int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, return ret; } +static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb, + const struct ieee80211_channel *sc) +{ + struct qlink_tlv_channel *qchan; + u32 flags = 0; + + 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(qchan->hdr)); + qchan->center_freq = cpu_to_le16(sc->center_freq); + qchan->hw_value = cpu_to_le16(sc->hw_value); + + if (sc->flags & IEEE80211_CHAN_NO_IR) + flags |= QLINK_CHAN_NO_IR; + + if (sc->flags & IEEE80211_CHAN_RADAR) + flags |= QLINK_CHAN_RADAR; + + qchan->flags = cpu_to_le32(flags); +} + int qtnf_cmd_send_scan(struct qtnf_wmac *mac) { struct sk_buff *cmd_skb; u16 res_code = QLINK_CMD_RESULT_OK; struct ieee80211_channel *sc; struct cfg80211_scan_request *scan_req = mac->scan_req; - struct qlink_tlv_channel *qchan; int n_channels; int count = 0; int ret; - u32 flags; if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) { pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid); @@ -1977,9 +2082,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac) } if (scan_req->ie_len != 0) - qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, - scan_req->ie, - scan_req->ie_len); + qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ, + scan_req->ie, scan_req->ie_len); if (scan_req->n_channels) { n_channels = scan_req->n_channels; @@ -1995,22 +2099,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac) pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", mac->macid, sc->hw_value, sc->center_freq, sc->flags); - qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); - flags = 0; - qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); - qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - - sizeof(struct qlink_tlv_hdr)); - qchan->center_freq = cpu_to_le16(sc->center_freq); - qchan->hw_value = cpu_to_le16(sc->hw_value); - - if (sc->flags & IEEE80211_CHAN_NO_IR) - flags |= QLINK_CHAN_NO_IR; - - if (sc->flags & IEEE80211_CHAN_RADAR) - flags |= QLINK_CHAN_RADAR; - - qchan->flags = cpu_to_le32(flags); + qtnf_cmd_channel_tlv_add(cmd_skb, sc); n_channels--; count++; } @@ -2054,10 +2144,15 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif, ether_addr_copy(cmd->bssid, vif->bssid); - if (sme->channel) - cmd->channel = cpu_to_le16(sme->channel->hw_value); + if (sme->bssid_hint) + ether_addr_copy(cmd->bssid_hint, sme->bssid_hint); else - cmd->channel = 0; + eth_zero_addr(cmd->bssid_hint); + + if (sme->prev_bssid) + ether_addr_copy(cmd->prev_bssid, sme->prev_bssid); + else + eth_zero_addr(cmd->prev_bssid); if ((sme->bg_scan_period > 0) && (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD)) @@ -2075,11 +2170,18 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif, connect_flags |= QLINK_STA_CONNECT_USE_RRM; cmd->flags = cpu_to_le32(connect_flags); + memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa)); + memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask, + sizeof(cmd->ht_capa_mask)); + memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa)); + memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask, + sizeof(cmd->vht_capa_mask)); + cmd->pbss = sme->pbss; aen = &cmd->aen; aen->auth_type = sme->auth_type; aen->privacy = !!sme->privacy; - aen->mfp = sme->mfp; + cmd->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); @@ -2103,9 +2205,11 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif, 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_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ, + sme->ie, sme->ie_len); + + if (sme->channel) + qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel); qtnf_bus_lock(vif->mac->bus); diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h index e87c4a484dd4..d981a76e5835 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.h +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h @@ -30,12 +30,11 @@ int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, enum nl80211_iftype iftype, int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif, enum nl80211_iftype iftype, u8 *mac_addr); int qtnf_cmd_send_del_intf(struct qtnf_vif *vif); -int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, - struct ieee80211_supported_band *band); +int qtnf_cmd_band_info_get(struct qtnf_wmac *mac, + struct ieee80211_supported_band *band); int qtnf_cmd_send_regulatory_config(struct qtnf_wmac *mac, const char *alpha2); -int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, - const struct cfg80211_ap_settings *s); -int qtnf_cmd_send_start_ap(struct qtnf_vif *vif); +int qtnf_cmd_send_start_ap(struct qtnf_vif *vif, + const struct cfg80211_ap_settings *s); int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif); int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg); int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags, diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index 6a6e5ffb0348..2d2c1ea65cb2 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -171,7 +171,7 @@ static int qtnf_mac_init_single_band(struct wiphy *wiphy, wiphy->bands[band]->band = band; - ret = qtnf_cmd_get_mac_chan_info(mac, wiphy->bands[band]); + ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]); if (ret) { pr_err("MAC%u: band %u: failed to get chans info: %d\n", mac->macid, band, ret); @@ -179,7 +179,6 @@ static int qtnf_mac_init_single_band(struct wiphy *wiphy, } qtnf_band_init_rates(wiphy->bands[band]); - qtnf_band_setup_htvht_caps(&mac->macinfo, wiphy->bands[band]); return 0; } diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h index da2c24e2271d..1b7bc0318f3e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.h +++ b/drivers/net/wireless/quantenna/qtnfmac/core.h @@ -92,7 +92,6 @@ struct qtnf_vif { struct qtnf_mac_info { u8 bands_cap; - u8 phymode_cap; u8 dev_mac[ETH_ALEN]; u8 num_tx_chain; u8 num_rx_chain; @@ -103,8 +102,8 @@ struct qtnf_mac_info { u8 sretry_limit; u8 coverage_class; u8 radar_detect_widths; - struct ieee80211_ht_cap ht_cap; - struct ieee80211_vht_cap vht_cap; + struct ieee80211_ht_cap ht_cap_mod_mask; + struct ieee80211_vht_cap vht_cap_mod_mask; struct ieee80211_iface_limit *limits; size_t n_limits; }; diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 4b29f9fb9c3c..4abc6d9ed560 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -65,34 +65,39 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif, sinfo.assoc_req_ies_len = 0; payload_len = len - sizeof(*sta_assoc); - tlv = (struct qlink_tlv_hdr *)sta_assoc->ies; + tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies; - while (payload_len >= sizeof(struct qlink_tlv_hdr)) { + while (payload_len >= sizeof(*tlv)) { tlv_type = le16_to_cpu(tlv->type); tlv_value_len = le16_to_cpu(tlv->len); tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); - if (tlv_full_len > payload_len) { - pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n", - mac->macid, vif->vifid, tlv_type, - tlv_value_len); + if (tlv_full_len > payload_len) return -EINVAL; - } if (tlv_type == QTN_TLV_ID_IE_SET) { - sinfo.assoc_req_ies = tlv->val; - sinfo.assoc_req_ies_len = tlv_value_len; + const struct qlink_tlv_ie_set *ie_set; + unsigned int ie_len; + + if (payload_len < sizeof(*ie_set)) + return -EINVAL; + + ie_set = (const struct qlink_tlv_ie_set *)tlv; + ie_len = tlv_value_len - + (sizeof(*ie_set) - sizeof(ie_set->hdr)); + + if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) { + sinfo.assoc_req_ies = ie_set->ie_data; + sinfo.assoc_req_ies_len = ie_len; + } } payload_len -= tlv_full_len; tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); } - if (payload_len) { - pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n", - mac->macid, vif->vifid, payload_len); + if (payload_len) return -EINVAL; - } cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo, GFP_KERNEL); @@ -247,13 +252,12 @@ qtnf_event_handle_scan_results(struct qtnf_vif *vif, struct cfg80211_bss *bss; struct ieee80211_channel *channel; struct wiphy *wiphy = priv_to_wiphy(vif->mac); - enum cfg80211_bss_frame_type frame_type; + enum cfg80211_bss_frame_type frame_type = CFG80211_BSS_FTYPE_UNKNOWN; size_t payload_len; u16 tlv_type; u16 tlv_value_len; size_t tlv_full_len; const struct qlink_tlv_hdr *tlv; - const u8 *ies = NULL; size_t ies_len = 0; @@ -270,17 +274,6 @@ qtnf_event_handle_scan_results(struct qtnf_vif *vif, return -EINVAL; } - switch (sr->frame_type) { - case QLINK_BSS_FTYPE_BEACON: - frame_type = CFG80211_BSS_FTYPE_BEACON; - break; - case QLINK_BSS_FTYPE_PRESP: - frame_type = CFG80211_BSS_FTYPE_PRESP; - break; - default: - frame_type = CFG80211_BSS_FTYPE_UNKNOWN; - } - payload_len = len - sizeof(*sr); tlv = (struct qlink_tlv_hdr *)sr->payload; @@ -289,27 +282,43 @@ qtnf_event_handle_scan_results(struct qtnf_vif *vif, tlv_value_len = le16_to_cpu(tlv->len); tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); - if (tlv_full_len > payload_len) { - pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n", - vif->mac->macid, vif->vifid, tlv_type, - tlv_value_len); + if (tlv_full_len > payload_len) return -EINVAL; - } if (tlv_type == QTN_TLV_ID_IE_SET) { - ies = tlv->val; - ies_len = tlv_value_len; + const struct qlink_tlv_ie_set *ie_set; + unsigned int ie_len; + + if (payload_len < sizeof(*ie_set)) + return -EINVAL; + + ie_set = (const struct qlink_tlv_ie_set *)tlv; + ie_len = tlv_value_len - + (sizeof(*ie_set) - sizeof(ie_set->hdr)); + + switch (ie_set->type) { + case QLINK_IE_SET_BEACON_IES: + frame_type = CFG80211_BSS_FTYPE_BEACON; + break; + case QLINK_IE_SET_PROBE_RESP_IES: + frame_type = CFG80211_BSS_FTYPE_PRESP; + break; + default: + frame_type = CFG80211_BSS_FTYPE_UNKNOWN; + } + + if (ie_len) { + ies = ie_set->ie_data; + ies_len = ie_len; + } } payload_len -= tlv_full_len; tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); } - if (payload_len) { - pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n", - vif->mac->macid, vif->vifid, payload_len); + if (payload_len) return -EINVAL; - } bss = cfg80211_inform_bss(wiphy, channel, frame_type, sr->bssid, get_unaligned_le64(&sr->tsf), diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index 0f582782682f..a432fb001c41 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -19,7 +19,7 @@ #include -#define QLINK_PROTO_VER 5 +#define QLINK_PROTO_VER 6 #define QLINK_MACID_RSVD 0xFF #define QLINK_VIFID_RSVD 0xFF @@ -74,12 +74,6 @@ enum qlink_hw_capab { QLINK_HW_CAPAB_STA_INACT_TIMEOUT = BIT(1), }; -enum qlink_phy_mode { - QLINK_PHYMODE_BGN = BIT(0), - QLINK_PHYMODE_AN = BIT(1), - QLINK_PHYMODE_AC = BIT(2), -}; - enum qlink_iface_type { QLINK_IFTYPE_AP = 1, QLINK_IFTYPE_STATION = 2, @@ -154,9 +148,9 @@ struct qlink_auth_encr { __le16 control_port_ethertype; u8 auth_type; u8 privacy; - u8 mfp; u8 control_port; u8 control_port_no_encrypt; + u8 rsvd[2]; } __packed; /* QLINK Command messages related definitions @@ -168,11 +162,12 @@ struct qlink_auth_encr { * Commands are QLINK messages of type @QLINK_MSG_TYPE_CMD, sent by driver to * wireless network device for processing. Device is expected to send back a * reply message of type &QLINK_MSG_TYPE_CMDRSP, containing at least command - * execution status (one of &enum qlink_cmd_result) at least. Reply message + * execution status (one of &enum qlink_cmd_result). Reply message * may also contain data payload specific to the command type. * - * @QLINK_CMD_CHANS_INFO_GET: for the specified MAC and specified band, get - * number of operational channels and information on each of the channel. + * @QLINK_CMD_BAND_INFO_GET: for the specified MAC and specified band, get + * the band's description including number of operational channels and + * info on each channel, HT/VHT capabilities, supported rates etc. * This command is generic to a specified MAC, interface index must be set * to QLINK_VIFID_RSVD in command header. * @QLINK_CMD_REG_NOTIFY: notify device about regulatory domain change. This @@ -194,10 +189,9 @@ enum qlink_cmd_type { QLINK_CMD_CHANGE_INTF = 0x0017, QLINK_CMD_UPDOWN_INTF = 0x0018, QLINK_CMD_REG_NOTIFY = 0x0019, - QLINK_CMD_CHANS_INFO_GET = 0x001A, + QLINK_CMD_BAND_INFO_GET = 0x001A, QLINK_CMD_CHAN_SWITCH = 0x001B, QLINK_CMD_CHAN_GET = 0x001C, - QLINK_CMD_CONFIG_AP = 0x0020, QLINK_CMD_START_AP = 0x0021, QLINK_CMD_STOP_AP = 0x0022, QLINK_CMD_GET_STA_INFO = 0x0030, @@ -303,21 +297,6 @@ struct qlink_cmd_mgmt_frame_tx { u8 frame_data[0]; } __packed; -/** - * struct qlink_cmd_mgmt_append_ie - data for QLINK_CMD_MGMT_SET_APPIE command - * - * @type: type of MGMT frame to appent requested IEs to, one of - * &enum qlink_mgmt_frame_type. - * @flags: for future use. - * @ie_data: IEs data to append. - */ -struct qlink_cmd_mgmt_append_ie { - struct qlink_cmd chdr; - u8 type; - u8 flags; - u8 ie_data[0]; -} __packed; - /** * struct qlink_cmd_get_sta_info - data for QLINK_CMD_GET_STA_INFO command * @@ -425,20 +404,36 @@ enum qlink_sta_connect_flags { /** * struct qlink_cmd_connect - data for QLINK_CMD_CONNECT command * - * @flags: for future use. - * @channel: channel which should be used to connect. - * @bg_scan_period: period of background scan. - * @aen: authentication information. * @bssid: BSSID of the BSS to connect to. + * @bssid_hint: recommended AP BSSID for initial connection to the BSS or + * 00:00:00:00:00:00 if not specified. + * @prev_bssid: previous BSSID, if specified (not 00:00:00:00:00:00) indicates + * a request to reassociate. + * @bg_scan_period: period of background scan. + * @flags: one of &enum qlink_sta_connect_flags. + * @ht_capa: HT Capabilities overrides. + * @ht_capa_mask: The bits of ht_capa which are to be used. + * @vht_capa: VHT Capability overrides + * @vht_capa_mask: The bits of vht_capa which are to be used. + * @aen: authentication information. + * @mfp: whether to use management frame protection. * @payload: variable portion of connection request. */ struct qlink_cmd_connect { struct qlink_cmd chdr; - __le32 flags; - __le16 channel; - __le16 bg_scan_period; - struct qlink_auth_encr aen; u8 bssid[ETH_ALEN]; + u8 bssid_hint[ETH_ALEN]; + u8 prev_bssid[ETH_ALEN]; + __le16 bg_scan_period; + __le32 flags; + struct ieee80211_ht_cap ht_capa; + struct ieee80211_ht_cap ht_capa_mask; + struct ieee80211_vht_cap vht_capa; + struct ieee80211_vht_cap vht_capa_mask; + struct qlink_auth_encr aen; + u8 mfp; + u8 pbss; + u8 rsvd[2]; u8 payload[0]; } __packed; @@ -477,11 +472,11 @@ enum qlink_band { }; /** - * struct qlink_cmd_chans_info_get - data for QLINK_CMD_CHANS_INFO_GET command + * struct qlink_cmd_band_info_get - data for QLINK_CMD_BAND_INFO_GET command * - * @band: a PHY band for which channels info is needed, one of @enum qlink_band + * @band: a PHY band for which information is queried, one of @enum qlink_band */ -struct qlink_cmd_chans_info_get { +struct qlink_cmd_band_info_get { struct qlink_cmd chdr; u8 band; } __packed; @@ -562,7 +557,7 @@ enum qlink_hidden_ssid { }; /** - * struct qlink_cmd_config_ap - data for QLINK_CMD_CONFIG_AP command + * struct qlink_cmd_start_ap - data for QLINK_CMD_START_AP command * * @beacon_interval: beacon interval * @inactivity_timeout: station's inactivity period in seconds @@ -574,7 +569,7 @@ enum qlink_hidden_ssid { * @aen: encryption info * @info: variable configurations */ -struct qlink_cmd_config_ap { +struct qlink_cmd_start_ap { struct qlink_cmd chdr; __le16 beacon_interval; __le16 inactivity_timeout; @@ -635,10 +630,9 @@ struct qlink_resp { * specified WMAC). * @num_tx_chain: Number of transmit chains used by WMAC. * @num_rx_chain: Number of receive chains used by WMAC. - * @vht_cap: VHT capabilities. - * @ht_cap: HT capabilities. + * @vht_cap_mod_mask: mask specifying which VHT capabilities can be altered. + * @ht_cap_mod_mask: mask specifying which HT capabilities can be altered. * @bands_cap: wireless bands WMAC can operate in, bitmap of &enum qlink_band. - * @phymode_cap: PHY modes WMAC can operate in, bitmap of &enum qlink_phy_mode. * @max_ap_assoc_sta: Maximum number of associations supported by WMAC. * @radar_detect_widths: bitmask of channels BW for which WMAC can detect radar. * @var_info: variable-length WMAC info data. @@ -648,12 +642,12 @@ struct qlink_resp_get_mac_info { u8 dev_mac[ETH_ALEN]; u8 num_tx_chain; u8 num_rx_chain; - struct ieee80211_vht_cap vht_cap; - struct ieee80211_ht_cap ht_cap; - u8 bands_cap; - u8 phymode_cap; + struct ieee80211_vht_cap vht_cap_mod_mask; + struct ieee80211_ht_cap ht_cap_mod_mask; __le16 max_ap_assoc_sta; __le16 radar_detect_widths; + u8 bands_cap; + u8 rsvd[1]; u8 var_info[0]; } __packed; @@ -730,17 +724,19 @@ struct qlink_resp_get_sta_info { } __packed; /** - * struct qlink_resp_get_chan_info - response for QLINK_CMD_CHANS_INFO_GET cmd + * struct qlink_resp_band_info_get - response for QLINK_CMD_BAND_INFO_GET cmd * - * @band: frequency band to which channels belong to, one of @enum qlink_band. - * @num_chans: total number of channels info data contained in reply data. - * @info: variable-length channels info. + * @band: frequency band that the response describes, one of @enum qlink_band. + * @num_chans: total number of channels info TLVs contained in reply. + * @num_bitrates: total number of bitrate TLVs contained in reply. + * @info: variable-length info portion. */ -struct qlink_resp_get_chan_info { +struct qlink_resp_band_info_get { struct qlink_resp rhdr; u8 band; u8 num_chans; - u8 rsvd[2]; + u8 num_bitrates; + u8 rsvd[1]; u8 info[0]; } __packed; @@ -885,12 +881,6 @@ struct qlink_event_rxmgmt { u8 frame_data[0]; } __packed; -enum qlink_frame_type { - QLINK_BSS_FTYPE_UNKNOWN, - QLINK_BSS_FTYPE_BEACON, - QLINK_BSS_FTYPE_PRESP, -}; - /** * struct qlink_event_scan_result - data for QLINK_EVENT_SCAN_RESULTS event * @@ -900,7 +890,6 @@ enum qlink_frame_type { * @capab: capabilities field. * @bintval: beacon interval announced by discovered BSS. * @signal: signal strength. - * @frame_type: frame type used to get scan result, see &enum qlink_frame_type. * @bssid: BSSID announced by discovered BSS. * @ssid_len: length of SSID announced by BSS. * @ssid: SSID announced by discovered BSS. @@ -913,10 +902,10 @@ struct qlink_event_scan_result { __le16 capab; __le16 bintval; s8 signal; - u8 frame_type; - u8 bssid[ETH_ALEN]; u8 ssid_len; u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 bssid[ETH_ALEN]; + u8 rsvd[2]; u8 payload[0]; } __packed; @@ -1151,6 +1140,33 @@ struct qlink_tlv_chandef { struct qlink_chandef chan; } __packed; +enum qlink_ie_set_type { + QLINK_IE_SET_UNKNOWN, + QLINK_IE_SET_ASSOC_REQ, + QLINK_IE_SET_ASSOC_RESP, + QLINK_IE_SET_PROBE_REQ, + QLINK_IE_SET_SCAN, + QLINK_IE_SET_BEACON_HEAD, + QLINK_IE_SET_BEACON_TAIL, + QLINK_IE_SET_BEACON_IES, + QLINK_IE_SET_PROBE_RESP, + QLINK_IE_SET_PROBE_RESP_IES, +}; + +/** + * struct qlink_tlv_ie_set - data for QTN_TLV_ID_IE_SET + * + * @type: type of MGMT frame IEs belong to, one of &enum qlink_ie_set_type. + * @flags: for future use. + * @ie_data: IEs data. + */ +struct qlink_tlv_ie_set { + struct qlink_tlv_hdr hdr; + u8 type; + u8 flags; + u8 ie_data[0]; +} __packed; + struct qlink_chan_stats { __le32 chan_num; __le32 cca_tx; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index 51520a0e2138..f4fdad2ed319 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c @@ -164,13 +164,13 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct sk_buff *skbcopy; struct rt2x00dump_hdr *dump_hdr; - struct timeval timestamp; + struct timespec64 timestamp; u32 data_len; if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))) return; - do_gettimeofday(×tamp); + ktime_get_ts64(×tamp); if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n"); @@ -200,7 +200,8 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, dump_hdr->queue_index = entry->queue->qid; dump_hdr->entry_index = entry->entry_idx; dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); - dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); + dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_nsec / + NSEC_PER_USEC); if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB)) skb_put_data(skbcopy, skbdesc->desc, skbdesc->desc_len); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dump.h b/drivers/net/wireless/ralink/rt2x00/rt2x00dump.h index 4c0e01b5d515..3b14eef0b646 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dump.h @@ -106,7 +106,7 @@ enum rt2x00_dump_type { */ struct rt2x00dump_hdr { __le32 version; -#define DUMP_HEADER_VERSION 2 +#define DUMP_HEADER_VERSION 3 __le32 header_length; __le32 desc_length; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c index e2f4f5778267..086aad22743d 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c @@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, if (status >= 0) return 0; - if (status == -ENODEV) { + if (status == -ENODEV || status == -ENOENT) { /* Device has disappeared. */ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); break; @@ -321,7 +321,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (status) { - if (status == -ENODEV) + if (status == -ENODEV || status == -ENOENT) clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); @@ -410,7 +410,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data) status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (status) { - if (status == -ENODEV) + if (status == -ENODEV || status == -ENOENT) clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 7e3107f9e37f..cad2272ae21b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -1630,7 +1630,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_tid_data *tid_data; struct rtl_sta_info *sta_entry = NULL; if (sta == NULL) @@ -1643,7 +1642,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -EINVAL; sta_entry = (struct rtl_sta_info *)sta->drv_priv; - tid_data = &sta_entry->tids[tid]; sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c index 1147327e6f52..3cb88825473e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/core.c +++ b/drivers/net/wireless/realtek/rtlwifi/core.c @@ -550,15 +550,13 @@ static int rtl_op_suspend(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct timeval ts; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); if (WARN_ON(!wow)) return -EINVAL; /* to resolve s4 can not wake up*/ - do_gettimeofday(&ts); - rtlhal->last_suspend_sec = ts.tv_sec; + rtlhal->last_suspend_sec = ktime_get_real_seconds(); if ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) && wow->n_patterns) _rtl_add_wowlan_patterns(hw, wow); @@ -577,7 +575,7 @@ static int rtl_op_resume(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct timeval ts; + time64_t now; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); rtlhal->driver_is_goingto_unload = false; @@ -585,8 +583,8 @@ static int rtl_op_resume(struct ieee80211_hw *hw) rtlhal->wake_from_pnp_sleep = true; /* to resovle s4 can not wake up*/ - do_gettimeofday(&ts); - if (ts.tv_sec - rtlhal->last_suspend_sec < 5) + now = ktime_get_real_seconds(); + if (now - rtlhal->last_suspend_sec < 5) return -1; rtl_op_start(hw); @@ -1748,7 +1746,7 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, u8 faversion, u8 interface_type, struct wlan_pwr_cfg pwrcfgcmd[]) { - struct wlan_pwr_cfg cfg_cmd = {0}; + struct wlan_pwr_cfg cfg_cmd; bool polling_bit = false; u32 ary_idx = 0; u8 value = 0; diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index eb12818b46b3..c2575b0b9440 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -54,8 +54,7 @@ static const u8 ac_to_hwq[] = { BK_QUEUE }; -static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, - struct sk_buff *skb) +static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); __le16 fc = rtl_get_fc(skb); @@ -104,20 +103,18 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) break; case 3: - /* - * Always enable ASPM and Clock Req + /* Always enable ASPM and Clock Req * from initialization to halt. - * */ + */ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM); ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM | RT_RF_OFF_LEVL_CLK_REQ); break; case 4: - /* - * Always enable ASPM without Clock Req + /* Always enable ASPM without Clock Req * from initialization to halt. - * */ + */ ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM | RT_RF_OFF_LEVL_CLK_REQ); ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM; @@ -146,32 +143,19 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) /*Set HW definition to determine if it supports ASPM. */ switch (rtlpci->const_support_pciaspm) { - case 0:{ - /*Not support ASPM. */ - bool support_aspm = false; - ppsc->support_aspm = support_aspm; - break; - } - case 1:{ - /*Support ASPM. */ - bool support_aspm = true; - bool support_backdoor = true; - ppsc->support_aspm = support_aspm; - - /*if (priv->oem_id == RT_CID_TOSHIBA && - !priv->ndis_adapter.amd_l1_patch) - support_backdoor = false; */ - - ppsc->support_backdoor = support_backdoor; - - break; - } + case 0: + /*Not support ASPM. */ + ppsc->support_aspm = false; + break; + case 1: + /*Support ASPM. */ + ppsc->support_aspm = true; + ppsc->support_backdoor = true; + break; case 2: /*ASPM value set by chipset. */ - if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { - bool support_aspm = true; - ppsc->support_aspm = support_aspm; - } + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) + ppsc->support_aspm = true; break; default: pr_err("switch case %#x not processed\n", @@ -180,10 +164,11 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) } /* toshiba aspm issue, toshiba will set aspm selfly - * so we should not set aspm in driver */ + * so we should not set aspm in driver + */ pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm); if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE && - init_aspm == 0x43) + init_aspm == 0x43) ppsc->support_aspm = false; } @@ -263,8 +248,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) udelay(50); } -/* - *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for +/*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for *power saving We should follow the sequence to enable *RTL8192SE first then enable Pci Bridge ASPM *or the system will show bluescreen. @@ -334,7 +318,7 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) bool status = false; u8 offset_e0; - unsigned offset_e4; + unsigned int offset_e4; pci_write_config_byte(rtlpci->pdev, 0xe0, 0xa0); @@ -369,12 +353,12 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, "tpcipriv->ndis_adapter.funcnumber %x\n", tpcipriv->ndis_adapter.funcnumber); - if ((pcipriv->ndis_adapter.busnumber == - tpcipriv->ndis_adapter.busnumber) && - (pcipriv->ndis_adapter.devnumber == - tpcipriv->ndis_adapter.devnumber) && - (pcipriv->ndis_adapter.funcnumber != - tpcipriv->ndis_adapter.funcnumber)) { + if (pcipriv->ndis_adapter.busnumber == + tpcipriv->ndis_adapter.busnumber && + pcipriv->ndis_adapter.devnumber == + tpcipriv->ndis_adapter.devnumber && + pcipriv->ndis_adapter.funcnumber != + tpcipriv->ndis_adapter.funcnumber) { find_buddy_priv = true; break; } @@ -407,7 +391,7 @@ static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) } static void rtl_pci_parse_configuration(struct pci_dev *pdev, - struct ieee80211_hw *hw) + struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); @@ -441,7 +425,6 @@ static void rtl_pci_init_aspm(struct ieee80211_hw *hw) rtl_pci_enable_aspm(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM); } - } static void _rtl_pci_io_handler_init(struct device *dev, @@ -458,11 +441,11 @@ static void _rtl_pci_io_handler_init(struct device *dev, rtlpriv->io.read8_sync = pci_read8_sync; rtlpriv->io.read16_sync = pci_read16_sync; rtlpriv->io.read32_sync = pci_read32_sync; - } static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw, - struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid) + struct sk_buff *skb, + struct rtl_tcb_desc *tcb_desc, u8 tid) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -520,13 +503,15 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) (rtlpriv->buddy_priv && rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process))) return; - /* we juse use em for BE/BK/VI/VO */ + /* we just use em for BE/BK/VI/VO */ for (tid = 7; tid >= 0; tid--) { u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + while (!mac->act_scanning && rtlpriv->psc.rfpwr_state == ERFON) { struct rtl_tcb_desc tcb_desc; + memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); spin_lock_bh(&rtlpriv->locks.waitq_lock); @@ -541,7 +526,8 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) spin_unlock_bh(&rtlpriv->locks.waitq_lock); /* Some macaddr can't do early mode. like - * multicast/broadcast/no_qos data */ + * multicast/broadcast/no_qos data + */ info = IEEE80211_SKB_CB(skb); if (info->flags & IEEE80211_TX_CTL_AMPDU) _rtl_update_earlymode_info(hw, skb, @@ -552,7 +538,6 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) } } - static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -603,7 +588,6 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); goto tx_status_ok; - } /* for sw LPS, just after NULL skb send out, we can @@ -643,15 +627,12 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) ieee80211_tx_status_irqsafe(hw, skb); if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", prio, ring->idx, skb_queue_len(&ring->queue)); - ieee80211_wake_queue(hw, - skb_get_queue_mapping - (skb)); + ieee80211_wake_queue(hw, skb_get_queue_mapping(skb)); } tx_status_ok: skb = NULL; @@ -659,7 +640,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || - (rtlpriv->link_info.num_rx_inperiod > 2)) + rtlpriv->link_info.num_rx_inperiod > 2) rtl_lps_leave(hw); } @@ -817,7 +798,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) new_skb = dev_alloc_skb(rtlpci->rxbuffersize); if (unlikely(!new_skb)) goto no_new; - memset(&rx_status , 0 , sizeof(rx_status)); + memset(&rx_status, 0, sizeof(rx_status)); rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, (u8 *)pdesc, skb); @@ -847,12 +828,11 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /* handle command packet here */ if (rtlpriv->cfg->ops->rx_command_packet && rtlpriv->cfg->ops->rx_command_packet(hw, &stats, skb)) { - dev_kfree_skb_any(skb); - goto new_trx_end; + dev_kfree_skb_any(skb); + goto new_trx_end; } - /* - * NOTICE This can not be use for mac80211, + /* NOTICE This can not be use for mac80211, * this is done in mac80211 code, * if done here sec DHCP will fail * skb_trim(skb, skb->len - 4); @@ -889,9 +869,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /* for sw lps */ rtl_swlps_beacon(hw, (void *)skb->data, skb->len); rtl_recognize_peer(hw, (void *)skb->data, skb->len); - if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && - (rtlpriv->rtlhal.current_bandtype == - BAND_ON_2_4G) && + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP && + rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G && (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc))) { dev_kfree_skb_any(skb); @@ -913,7 +892,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) } if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || - (rtlpriv->link_info.num_rx_inperiod > 2)) + rtlpriv->link_info.num_rx_inperiod > 2) rtl_lps_leave(hw); skb = new_skb; no_new: @@ -947,35 +926,34 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) unsigned long flags; u32 inta = 0; u32 intb = 0; + u32 intc = 0; + u32 intd = 0; irqreturn_t ret = IRQ_HANDLED; if (rtlpci->irq_enabled == 0) return ret; - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock , flags); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); rtlpriv->cfg->ops->disable_interrupt(hw); /*read ISR: 4/8bytes */ - rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb); + rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb, &intc, &intd); - /*Shared IRQ or HW disappared */ + /*Shared IRQ or HW disappeared */ if (!inta || inta == 0xffff) goto done; /*<1> beacon related */ - if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) { + if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon ok interrupt!\n"); - } - if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) { + if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon err interrupt!\n"); - } - if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) { + if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); - } if (inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, @@ -1031,6 +1009,16 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) _rtl_pci_tx_isr(hw, VO_QUEUE); } + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { + if (intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { + rtlpriv->link_info.num_tx_inperiod++; + + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, + "H2C TX OK interrupt!\n"); + _rtl_pci_tx_isr(hw, H2C_QUEUE); + } + } + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { rtlpriv->link_info.num_tx_inperiod++; @@ -1130,7 +1118,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) /*NB: the beacon data buffer must be 32-bit aligned. */ pskb = ieee80211_beacon_get(hw, mac->vif); - if (pskb == NULL) + if (!pskb) return; hdr = rtl_get_hdr(pskb); info = IEEE80211_SKB_CB(pskb); @@ -1152,7 +1140,6 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, &temp_one); } - return; } static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) @@ -1165,14 +1152,15 @@ static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) desc_num = TX_DESC_NUM_92E; + else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) + desc_num = TX_DESC_NUM_8822B; else desc_num = RT_TXDESC_NUM; for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) rtlpci->txringcount[i] = desc_num; - /* - *we just alloc 2 desc for beacon queue, + /*we just alloc 2 desc for beacon queue, *because we just need first desc in hw beacon. */ rtlpci->txringcount[BEACON_QUEUE] = 2; @@ -1189,7 +1177,7 @@ static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw) } static void _rtl_pci_init_struct(struct ieee80211_hw *hw, - struct pci_dev *pdev) + struct pci_dev *pdev) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -1361,7 +1349,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) } static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, - unsigned int prio) + unsigned int prio) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -1378,8 +1366,7 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, entry = (u8 *)(&ring->desc[ring->idx]); pci_unmap_single(rtlpci->pdev, - rtlpriv->cfg-> - ops->get_desc(hw, (u8 *)entry, + rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); @@ -1451,8 +1438,7 @@ static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw) } for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { - ret = _rtl_pci_init_tx_ring(hw, i, - rtlpci->txringcount[i]); + ret = _rtl_pci_init_tx_ring(hw, i, rtlpci->txringcount[i]); if (ret) goto err_free_rings; } @@ -1500,7 +1486,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) /* force the rx_ring[RX_MPDU_QUEUE/ * RX_CMD_QUEUE].idx to the first one *new trx flow, do nothing - */ + */ if (!rtlpriv->use_new_trx_flow && rtlpci->rx_ring[rxring_idx].desc) { struct rtl_rx_desc *entry = NULL; @@ -1510,8 +1496,8 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) entry = &rtlpci->rx_ring[rxring_idx].desc[i]; bufferaddress = rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, - false , HW_DESC_RXBUFF_ADDR); - memset((u8 *)entry , 0 , + false, HW_DESC_RXBUFF_ADDR); + memset((u8 *)entry, 0, sizeof(*rtlpci->rx_ring [rxring_idx].desc));/*clear one entry*/ if (rtlpriv->use_new_trx_flow) { @@ -1540,8 +1526,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) rtlpci->rx_ring[rxring_idx].idx = 0; } - /* - *after reset, release previous pending packet, + /*after reset, release previous pending packet, *and force the tx idx to the first one */ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); @@ -1642,7 +1627,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if (rtlpriv->psc.sw_ps_enabled) { if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && - !ieee80211_has_pm(fc)) + !ieee80211_has_pm(fc)) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); } @@ -1674,7 +1659,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN); - if ((own == 1) && (hw_queue != BEACON_QUEUE)) { + if (own == 1 && hw_queue != BEACON_QUEUE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", hw_queue, ring->idx, idx, @@ -1688,11 +1673,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if (rtlpriv->cfg->ops->get_available_desc && rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "get_available_desc fail\n"); - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, - flags); - return skb->len; + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail\n"); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return skb->len; } if (ieee80211_is_data(fc)) @@ -1751,7 +1735,7 @@ static void rtl_pci_flush(struct ieee80211_hw *hw, u32 queues, bool drop) ring = &pcipriv->dev.tx_ring[queue_id]; queue_len = skb_queue_len(&ring->queue); if (queue_len == 0 || queue_id == BEACON_QUEUE || - queue_id == TXCMD_QUEUE) { + queue_id == TXCMD_QUEUE) { queue_id--; continue; } else { @@ -1761,7 +1745,7 @@ static void rtl_pci_flush(struct ieee80211_hw *hw, u32 queues, bool drop) /* we just wait 1s for all queues */ if (rtlpriv->psc.rfpwr_state == ERFOFF || - is_hal_stop(rtlhal) || i >= 200) + is_hal_stop(rtlhal) || i >= 200) return; } } @@ -1779,7 +1763,6 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) flush_workqueue(rtlpriv->works.rtl_wq); destroy_workqueue(rtlpriv->works.rtl_wq); - } static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) @@ -1837,7 +1820,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "rtl_pci_start OK\n"); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); return 0; } @@ -1848,13 +1831,12 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); unsigned long flags; - u8 RFInProgressTimeOut = 0; + u8 rf_timeout = 0; if (rtlpriv->cfg->ops->get_btc_status()) rtlpriv->btcoexist.btc_ops->btc_halt_notify(); - /* - *should be before disable interrupt&adapter + /*should be before disable interrupt&adapter *and will do it immediately. */ set_hal_stop(rtlhal); @@ -1866,12 +1848,12 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); while (ppsc->rfchange_inprogress) { spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); - if (RFInProgressTimeOut > 100) { + if (rf_timeout > 100) { spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); break; } mdelay(1); - RFInProgressTimeOut++; + rf_timeout++; spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); } ppsc->rfchange_inprogress = true; @@ -1891,7 +1873,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) } static bool _rtl_pci_find_adapter(struct pci_dev *pdev, - struct ieee80211_hw *hw) + struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); @@ -1946,13 +1928,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; - } } else if (deviceid == RTL_PCI_8723AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8723AE PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid); + "8723AE PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || @@ -1972,21 +1953,26 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Find adapter, Hardware type is 8188EE\n"); } else if (deviceid == RTL_PCI_8723BE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; - RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD, - "Find adapter, Hardware type is 8723BE\n"); + rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8723BE\n"); } else if (deviceid == RTL_PCI_8192EE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; - RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD, - "Find adapter, Hardware type is 8192EE\n"); + rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8192EE\n"); } else if (deviceid == RTL_PCI_8821AE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; - RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD, - "Find adapter, Hardware type is 8821AE\n"); + rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8821AE\n"); } else if (deviceid == RTL_PCI_8812AE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; - RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD, - "Find adapter, Hardware type is 8812AE\n"); + rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8812AE\n"); + } else if (deviceid == RTL_PCI_8822BE_DID) { + rtlhal->hw_type = HARDWARE_TYPE_RTL8822BE; + rtlhal->bandset = BAND_ON_BOTH; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8822BE\n"); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Err: Unknown device - vid/did=%x/%x\n", @@ -2014,11 +2000,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } } - /* 92ee use new trx flow */ - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) + switch (rtlhal->hw_type) { + case HARDWARE_TYPE_RTL8192EE: + case HARDWARE_TYPE_RTL8822BE: + /* use new trx flow */ rtlpriv->use_new_trx_flow = true; - else + break; + + default: rtlpriv->use_new_trx_flow = false; + break; + } /*find bus info */ pcipriv->ndis_adapter.busnumber = pdev->bus->number; @@ -2109,7 +2101,7 @@ static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) rtlpci->using_msi = true; - RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, "MSI Interrupt Mode!\n"); return 0; } @@ -2127,7 +2119,7 @@ static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) return ret; rtlpci->using_msi = false; - RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, "Pin-based Interrupt Mode!\n"); return 0; } @@ -2164,7 +2156,7 @@ static void platform_enable_dma64(struct pci_dev *pdev, bool dma64) } int rtl_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) + const struct pci_device_id *id) { struct ieee80211_hw *hw = NULL; @@ -2343,7 +2335,6 @@ int rtl_pci_probe(struct pci_dev *pdev, pci_disable_device(pdev); return err; - } EXPORT_SYMBOL(rtl_pci_probe); @@ -2402,20 +2393,20 @@ EXPORT_SYMBOL(rtl_pci_disconnect); #ifdef CONFIG_PM_SLEEP /*************************************** -kernel pci power state define: -PCI_D0 ((pci_power_t __force) 0) -PCI_D1 ((pci_power_t __force) 1) -PCI_D2 ((pci_power_t __force) 2) -PCI_D3hot ((pci_power_t __force) 3) -PCI_D3cold ((pci_power_t __force) 4) -PCI_UNKNOWN ((pci_power_t __force) 5) + * kernel pci power state define: + * PCI_D0 ((pci_power_t __force) 0) + * PCI_D1 ((pci_power_t __force) 1) + * PCI_D2 ((pci_power_t __force) 2) + * PCI_D3hot ((pci_power_t __force) 3) + * PCI_D3cold ((pci_power_t __force) 4) + * PCI_UNKNOWN ((pci_power_t __force) 5) -This function is called when system -goes into suspend state mac80211 will -call rtl_mac_stop() from the mac80211 -suspend function first, So there is -no need to call hw_disable here. -****************************************/ + * This function is called when system + * goes into suspend state mac80211 will + * call rtl_mac_stop() from the mac80211 + * suspend function first, So there is + * no need to call hw_disable here. + ****************************************/ int rtl_pci_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h index 1af92b34979d..e7d070e8da2d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.h +++ b/drivers/net/wireless/realtek/rtlwifi/pci.h @@ -27,10 +27,9 @@ #define __RTL_PCI_H__ #include -/* -1: MSDU packet queue, -2: Rx Command Queue -*/ +/* 1: MSDU packet queue, + * 2: Rx Command Queue + */ #define RTL_PCI_RX_MPDU_QUEUE 0 #define RTL_PCI_RX_CMD_QUEUE 1 #define RTL_PCI_MAX_RX_QUEUE 2 @@ -40,6 +39,7 @@ #define RT_TXDESC_NUM 128 #define TX_DESC_NUM_92E 512 +#define TX_DESC_NUM_8822B 512 #define RT_TXDESC_NUM_BE_QUEUE 256 #define BK_QUEUE 0 @@ -51,6 +51,7 @@ #define MGNT_QUEUE 6 #define HIGH_QUEUE 7 #define HCCA_QUEUE 8 +#define H2C_QUEUE TXCMD_QUEUE /* In 8822B */ #define RTL_PCI_DEVICE(vend, dev, cfg) \ .vendor = (vend), \ @@ -108,6 +109,7 @@ #define RTL_PCI_8192EE_DID 0x818B /*8192ee*/ #define RTL_PCI_8821AE_DID 0x8821 /*8821ae*/ #define RTL_PCI_8812AE_DID 0x8812 /*8812ae*/ +#define RTL_PCI_8822BE_DID 0xB822 /*8822be*/ /*8192 support 16 pages of IO registers*/ #define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 @@ -209,7 +211,7 @@ struct rtl_pci { /*irq */ u8 irq_alloc; - u32 irq_mask[2]; + u32 irq_mask[4]; /* 0-1: normal, 2: unused, 3: h2c */ u32 sys_irq_mask; /*Bcn control register setting */ @@ -223,8 +225,9 @@ struct rtl_pci { u8 const_hostpci_aspm_setting; /*pci-e device */ u8 const_devicepci_aspm_setting; - /*If it supports ASPM, Offset[560h] = 0x40, - otherwise Offset[560h] = 0x00. */ + /* If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + */ bool support_aspm; bool support_backdoor; @@ -279,7 +282,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw); extern const struct rtl_intf_ops rtl_pci_ops; int rtl_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); + const struct pci_device_id *id); void rtl_pci_disconnect(struct pci_dev *pdev); #ifdef CONFIG_PM_SLEEP int rtl_pci_suspend(struct device *dev); @@ -287,34 +290,34 @@ int rtl_pci_resume(struct device *dev); #endif /* CONFIG_PM_SLEEP */ static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return readb((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return readw((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return readl((u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) { - writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writeb(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline void pci_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) { - writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writew(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline void pci_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) { - writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writel(val, (u8 __iomem *)rtlpriv->io.pci_mem_start + addr); } static inline u16 calc_fifo_space(u16 rp, u16 wp) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index 2c671364c521..e30a18e64ff5 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -1472,7 +1472,8 @@ void rtl88ee_card_disable(struct ieee80211_hw *hw) } void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h index ab8488da9409..cdf49de1e6ed 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h @@ -29,7 +29,8 @@ void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw); void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl88ee_hw_init(struct ieee80211_hw *hw); void rtl88ee_card_disable(struct ieee80211_hw *hw); void rtl88ee_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c index 9310fad69cd9..0f4c86a28716 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c @@ -1375,7 +1375,8 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw) } void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h index 7683c5dfe851..b5c8e2fc1ba2 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.h @@ -42,7 +42,8 @@ static inline u8 rtl92c_get_chnl_group(u8 chnl) void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl92ce_hw_init(struct ieee80211_hw *hw); void rtl92ce_card_disable(struct ieee80211_hw *hw); void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c index 5a67f85fa165..0da6c0136857 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -1356,7 +1356,8 @@ void rtl92de_card_disable(struct ieee80211_hw *hw) } void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h index 85c565b86ae3..9236aa91273d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.h @@ -29,7 +29,8 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92de_read_eeprom_info(struct ieee80211_hw *hw); void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl92de_hw_init(struct ieee80211_hw *hw); void rtl92de_card_disable(struct ieee80211_hw *hw); void rtl92de_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c index 6fc3090c4b72..fe5da637e77a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c @@ -1694,7 +1694,8 @@ void rtl92ee_card_disable(struct ieee80211_hw *hw) } void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h index cd6aeb44b996..cd6d3322f033 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.h @@ -29,7 +29,8 @@ void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw); void rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl92ee_hw_init(struct ieee80211_hw *hw); void rtl92ee_card_disable(struct ieee80211_hw *hw); void rtl92ee_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c index 66be79ca4247..76bf089cced4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -1559,7 +1559,7 @@ void rtl92se_card_disable(struct ieee80211_hw *hw) } void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, - u32 *p_intb) + u32 *p_intb, u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h index 3c93d30fcae7..607056010974 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.h @@ -42,7 +42,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92se_read_eeprom_info(struct ieee80211_hw *hw); void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, - u32 *inta, u32 *intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl92se_hw_init(struct ieee80211_hw *hw); void rtl92se_card_disable(struct ieee80211_hw *hw); void rtl92se_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c index 8cfd4993c90a..c3f98d58124c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c @@ -1340,7 +1340,8 @@ void rtl8723e_card_disable(struct ieee80211_hw *hw) } void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h index 1e7063105c96..19e467a37c72 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.h @@ -34,7 +34,8 @@ void rtl8723e_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8723e_read_eeprom_info(struct ieee80211_hw *hw); void rtl8723e_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl8723e_hw_init(struct ieee80211_hw *hw); void rtl8723e_card_disable(struct ieee80211_hw *hw); void rtl8723e_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index 239518bd31f1..7cd1ffa7d4a7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -1682,7 +1682,8 @@ void rtl8723be_card_disable(struct ieee80211_hw *hw) } void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h index 54d7afa7297e..2215a792f6bf 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.h @@ -30,7 +30,8 @@ void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw); void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl8723be_hw_init(struct ieee80211_hw *hw); void rtl8723be_card_disable(struct ieee80211_hw *hw); void rtl8723be_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 60c82a5b51cd..43e18c4c1e68 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -1364,7 +1364,6 @@ static void _rtl8821ae_get_wakeup_reason(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); u8 fw_reason = 0; - struct timeval ts; fw_reason = rtl_read_byte(rtlpriv, REG_MCUTST_WOWLAN); @@ -1373,20 +1372,16 @@ static void _rtl8821ae_get_wakeup_reason(struct ieee80211_hw *hw) ppsc->wakeup_reason = 0; - rtlhal->last_suspend_sec = ts.tv_sec; + rtlhal->last_suspend_sec = ktime_get_real_seconds(); switch (fw_reason) { case FW_WOW_V2_PTK_UPDATE_EVENT: ppsc->wakeup_reason = WOL_REASON_PTK_UPDATE; - do_gettimeofday(&ts); - ppsc->last_wakeup_time = ts.tv_sec*1000 + ts.tv_usec/1000; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "It's a WOL PTK Key update event!\n"); break; case FW_WOW_V2_GTK_UPDATE_EVENT: ppsc->wakeup_reason = WOL_REASON_GTK_UPDATE; - do_gettimeofday(&ts); - ppsc->last_wakeup_time = ts.tv_sec*1000 + ts.tv_usec/1000; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "It's a WOL GTK Key update event!\n"); break; @@ -2488,7 +2483,8 @@ void rtl8821ae_card_disable(struct ieee80211_hw *hw) } void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h index 50fa9c718189..284d259fe557 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.h @@ -30,7 +30,8 @@ void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw); void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int rtl8821ae_hw_init(struct ieee80211_hw *hw); void rtl8821ae_card_disable(struct ieee80211_hw *hw); void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 22afc14c3da6..92d4859ec906 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -709,6 +709,7 @@ enum rtl_var_map { RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ RTL_IMR_RDU, /*Receive Descriptor Unavailable */ RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ + RTL_IMR_H2CDOK, /*H2C Queue DMA OK Interrupt */ RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ @@ -1599,7 +1600,7 @@ struct rtl_hal { bool enter_pnp_sleep; bool wake_from_pnp_sleep; bool wow_enabled; - __kernel_time_t last_suspend_sec; + time64_t last_suspend_sec; u32 wowlan_fwsize; u8 *wowlan_firmware; @@ -1953,8 +1954,6 @@ struct rtl_ps_ctl { u8 gtk_offload_enable; /* Used for WOL, indicates the reason for waking event.*/ u32 wakeup_reason; - /* Record the last waking time for comparison with setting key. */ - u64 last_wakeup_time; }; struct rtl_stats { @@ -2100,7 +2099,8 @@ struct rtl_hal_ops { void (*read_chip_version)(struct ieee80211_hw *hw); void (*read_eeprom_info) (struct ieee80211_hw *hw); void (*interrupt_recognized) (struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); int (*hw_init) (struct ieee80211_hw *hw); void (*hw_disable) (struct ieee80211_hw *hw); void (*hw_suspend) (struct ieee80211_hw *hw); @@ -2144,6 +2144,9 @@ struct rtl_hal_ops { void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, bool firstseg, bool lastseg, struct sk_buff *skb); + void (*fill_tx_special_desc)(struct ieee80211_hw *hw, + u8 *pdesc, u8 *pbd_desc, + struct sk_buff *skb, u8 hw_queue); bool (*query_rx_desc) (struct ieee80211_hw *hw, struct rtl_stats *stats, struct ieee80211_rx_status *rx_status, diff --git a/drivers/net/wireless/rsi/rsi_91x_ps.c b/drivers/net/wireless/rsi/rsi_91x_ps.c index 523f5329d2b7..01472fac8b9a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_ps.c +++ b/drivers/net/wireless/rsi/rsi_91x_ps.c @@ -36,7 +36,6 @@ char *str_psstate(enum ps_state state) default: return "INVALID_STATE"; } - return "INVALID_STATE"; } static inline void rsi_modify_ps_state(struct rsi_hw *adapter, diff --git a/drivers/net/wireless/zydas/zd1201.c b/drivers/net/wireless/zydas/zd1201.c index 581e8577a221..253403899fe9 100644 --- a/drivers/net/wireless/zydas/zd1201.c +++ b/drivers/net/wireless/zydas/zd1201.c @@ -230,8 +230,7 @@ static void zd1201_usbrx(struct urb *urb) /* Info frame */ if (type == ZD1201_PACKET_INQUIRE) { int i = 0; - unsigned short infotype, framelen, copylen; - framelen = le16_to_cpu(*(__le16*)&data[4]); + unsigned short infotype, copylen; infotype = le16_to_cpu(*(__le16*)&data[6]); if (infotype == ZD1201_INF_LINKSTATUS) {