idualwifi7260: Merge new changes from FreeBSD.
These seem to greatly improve driver stability.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,8 @@ enum iwm_device_family {
|
||||
IWM_DEVICE_FAMILY_8000,
|
||||
};
|
||||
|
||||
#define IWM_DEFAULT_MAX_TX_POWER 22
|
||||
|
||||
/* Antenna presence definitions */
|
||||
#define IWM_ANT_NONE 0x0
|
||||
#define IWM_ANT_A (1 << 0)
|
||||
|
||||
@@ -44,6 +44,7 @@ enum {
|
||||
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
||||
IWM_DEBUG_FW = 0x00200000, /* Firmware management */
|
||||
IWM_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */
|
||||
IWM_DEBUG_TE = 0x00800000, /* Time Event handling */
|
||||
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||
|
||||
@@ -141,7 +141,7 @@ iwm_free_fw_paging(struct iwm_softc *sc)
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_img *image)
|
||||
{
|
||||
int sec_idx, idx;
|
||||
uint32_t offset = 0;
|
||||
@@ -158,7 +158,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
* CPU2 paging image (including instruction and data)
|
||||
*/
|
||||
for (sec_idx = 0; sec_idx < IWM_UCODE_SECTION_MAX; sec_idx++) {
|
||||
if (image->fw_sect[sec_idx].offset == IWM_PAGING_SEPARATOR_SECTION) {
|
||||
if (image->sec[sec_idx].offset == IWM_PAGING_SEPARATOR_SECTION) {
|
||||
sec_idx++;
|
||||
break;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
* If paging is enabled there should be at least 2 more sections left
|
||||
* (one for CSS and one for Paging data)
|
||||
*/
|
||||
if (sec_idx >= nitems(image->fw_sect) - 1) {
|
||||
if (sec_idx >= nitems(image->sec) - 1) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Paging: Missing CSS and/or paging sections\n");
|
||||
iwm_free_fw_paging(sc);
|
||||
@@ -181,7 +181,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
sec_idx);
|
||||
|
||||
memcpy(sc->fw_paging_db[0].fw_paging_block.vaddr,
|
||||
image->fw_sect[sec_idx].data,
|
||||
image->sec[sec_idx].data,
|
||||
sc->fw_paging_db[0].fw_paging_size);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
@@ -198,7 +198,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
*/
|
||||
for (idx = 1; idx < sc->num_of_paging_blk; idx++) {
|
||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
||||
(const char *)image->fw_sect[sec_idx].data + offset,
|
||||
(const char *)image->sec[sec_idx].data + offset,
|
||||
sc->fw_paging_db[idx].fw_paging_size);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
@@ -212,7 +212,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
/* copy the last paging block */
|
||||
if (sc->num_of_pages_in_last_blk > 0) {
|
||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
||||
(const char *)image->fw_sect[sec_idx].data + offset,
|
||||
(const char *)image->sec[sec_idx].data + offset,
|
||||
IWM_FW_PAGING_SIZE * sc->num_of_pages_in_last_blk);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
@@ -224,7 +224,7 @@ iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_alloc_fw_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
iwm_alloc_fw_paging_mem(struct iwm_softc *sc, const struct iwm_fw_img *image)
|
||||
{
|
||||
int blk_idx = 0;
|
||||
int error, num_of_pages;
|
||||
@@ -298,7 +298,7 @@ iwm_alloc_fw_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *image)
|
||||
}
|
||||
|
||||
int
|
||||
iwm_save_fw_paging(struct iwm_softc *sc, const struct iwm_fw_sects *fw)
|
||||
iwm_save_fw_paging(struct iwm_softc *sc, const struct iwm_fw_img *fw)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -311,7 +311,7 @@ iwm_save_fw_paging(struct iwm_softc *sc, const struct iwm_fw_sects *fw)
|
||||
|
||||
/* send paging cmd to FW in case CPU2 has paging image */
|
||||
int
|
||||
iwm_send_paging_cmd(struct iwm_softc *sc, const struct iwm_fw_sects *fw)
|
||||
iwm_send_paging_cmd(struct iwm_softc *sc, const struct iwm_fw_img *fw)
|
||||
{
|
||||
int blk_idx;
|
||||
uint32_t dev_phy_addr;
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
#define IWM_PAGING_TLV_SECURE_MASK 1
|
||||
|
||||
extern void iwm_free_fw_paging(struct iwm_softc *);
|
||||
extern int iwm_save_fw_paging(struct iwm_softc *, const struct iwm_fw_sects *);
|
||||
extern int iwm_send_paging_cmd(struct iwm_softc *, const struct iwm_fw_sects *);
|
||||
extern int iwm_save_fw_paging(struct iwm_softc *, const struct iwm_fw_img *);
|
||||
extern int iwm_send_paging_cmd(struct iwm_softc *, const struct iwm_fw_img *);
|
||||
|
||||
#endif /* __IF_IWM_FW_H__ */
|
||||
|
||||
@@ -162,6 +162,9 @@ iwm_led_blink_timeout(void *arg)
|
||||
{
|
||||
struct iwm_softc *sc = arg;
|
||||
|
||||
if (sc->sc_attached == 0)
|
||||
return;
|
||||
|
||||
if (iwm_mvm_led_is_enabled(sc))
|
||||
iwm_mvm_led_disable(sc);
|
||||
else
|
||||
|
||||
@@ -309,7 +309,12 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
|
||||
* iwm_mvm_mac_ctxt_changed() when already authenticating or
|
||||
* associating, ni->ni_bssid should always make sense here.
|
||||
*/
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
|
||||
if (ivp->iv_auth) {
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
|
||||
} else {
|
||||
/* XXX Or maybe all zeroes address? */
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ieee80211broadcastaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -406,18 +406,39 @@ iwm_prepare_card_hw(struct iwm_softc *sc)
|
||||
void
|
||||
iwm_apm_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint16_t reg;
|
||||
uint16_t lctl, cap;
|
||||
int pcie_ptr;
|
||||
|
||||
reg = pci_read_config(sc->sc_dev, PCIER_LINK_CTL, sizeof(reg));
|
||||
if (reg & PCIEM_LINK_CTL_ASPMC_L1) {
|
||||
/* Um the Linux driver prints "Disabling L0S for this one ... */
|
||||
/*
|
||||
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
|
||||
* Check if BIOS (or OS) enabled L1-ASPM on this device.
|
||||
* If so (likely), disable L0S, so device moves directly L0->L1;
|
||||
* costs negligible amount of power savings.
|
||||
* If not (unlikely), enable L0S, so there is at least some
|
||||
* power savings, even without L1.
|
||||
*/
|
||||
int error;
|
||||
|
||||
error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr);
|
||||
if (error != 0)
|
||||
return;
|
||||
lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL,
|
||||
sizeof(lctl));
|
||||
if (lctl & PCIEM_LINK_CTL_ASPMC_L1) {
|
||||
IWM_SETBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
} else {
|
||||
/* ... and "Enabling" here */
|
||||
IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
}
|
||||
|
||||
cap = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_DEVICE_CTL2,
|
||||
sizeof(cap));
|
||||
sc->sc_ltr_enabled = (cap & PCIEM_CTL2_LTR_ENABLE) ? 1 : 0;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_PWRSAVE,
|
||||
"L1 %sabled - LTR %sabled\n",
|
||||
(lctl & PCIEM_LINK_CTL_ASPMC_L1) ? "En" : "Dis",
|
||||
sc->sc_ltr_enabled ? "En" : "Dis");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -390,7 +390,7 @@ static uint8_t
|
||||
ch_id_to_ch_index(uint16_t ch_id)
|
||||
{
|
||||
if (!is_valid_channel(ch_id))
|
||||
return 0xff;
|
||||
return 0xff;
|
||||
|
||||
if (ch_id <= 14)
|
||||
return ch_id - 1;
|
||||
@@ -509,7 +509,7 @@ iwm_phy_db_send_all_channel_groups(struct iwm_phy_db *phy_db,
|
||||
int err;
|
||||
struct iwm_phy_db_entry *entry;
|
||||
|
||||
/* Send all the channel specific groups to operational fw */
|
||||
/* Send all the channel specific groups to operational fw */
|
||||
for (i = 0; i < max_ch_groups; i++) {
|
||||
entry = iwm_phy_db_get_section(phy_db,
|
||||
type,
|
||||
|
||||
@@ -215,7 +215,7 @@ static inline boolean_t
|
||||
iwm_mvm_rrm_scan_needed(struct iwm_softc *sc)
|
||||
{
|
||||
/* require rrm scan whenever the fw supports it */
|
||||
return fw_has_capa(&sc->ucode_capa,
|
||||
return fw_has_capa(&sc->sc_fw.ucode_capa,
|
||||
IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
|
||||
/* If this happens, the firmware has mistakenly sent an LMAC
|
||||
* notification during UMAC scans -- warn and ignore it.
|
||||
*/
|
||||
if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Mistakenly got LMAC notification during UMAC scan\n",
|
||||
__func__);
|
||||
@@ -307,7 +307,8 @@ iwm_mvm_lmac_scan_fill_channels(struct iwm_softc *sc,
|
||||
int j;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ss->ss_last && nchan < sc->ucode_capa.n_scan_channels; j++) {
|
||||
j < ss->ss_last && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = ss->ss_chans[j];
|
||||
/*
|
||||
* Catch other channels, in case we have 900MHz channels or
|
||||
@@ -350,7 +351,8 @@ iwm_mvm_umac_scan_fill_channels(struct iwm_softc *sc,
|
||||
int j;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ss->ss_last && nchan < sc->ucode_capa.n_scan_channels; j++) {
|
||||
j < ss->ss_last && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = ss->ss_chans[j];
|
||||
/*
|
||||
* Catch other channels, in case we have 900MHz channels or
|
||||
@@ -495,7 +497,7 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
||||
IWM_SCAN_CONFIG_RATE_36M | IWM_SCAN_CONFIG_RATE_48M |
|
||||
IWM_SCAN_CONFIG_RATE_54M);
|
||||
|
||||
cmd_size = sizeof(*scan_config) + sc->ucode_capa.n_scan_channels;
|
||||
cmd_size = sizeof(*scan_config) + sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
|
||||
scan_config = malloc(cmd_size, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (scan_config == NULL)
|
||||
@@ -523,7 +525,8 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
||||
IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ic->ic_nchans && nchan < sc->ucode_capa.n_scan_channels; j++) {
|
||||
j < ic->ic_nchans && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = &ic->ic_channels[j];
|
||||
/* For 2GHz, only populate 11b channels */
|
||||
/* For 5GHz, only populate 11a channels */
|
||||
@@ -566,7 +569,7 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
||||
static boolean_t
|
||||
iwm_mvm_scan_use_ebs(struct iwm_softc *sc)
|
||||
{
|
||||
const struct iwm_ucode_capabilities *capa = &sc->ucode_capa;
|
||||
const struct iwm_ucode_capabilities *capa = &sc->sc_fw.ucode_capa;
|
||||
|
||||
/* We can only use EBS if:
|
||||
* 1. the feature is supported;
|
||||
@@ -596,7 +599,7 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
|
||||
|
||||
req_len = sizeof(struct iwm_scan_req_umac) +
|
||||
(sizeof(struct iwm_scan_channel_cfg_umac) *
|
||||
sc->ucode_capa.n_scan_channels) +
|
||||
sc->sc_fw.ucode_capa.n_scan_channels) +
|
||||
sizeof(struct iwm_scan_req_umac_tail);
|
||||
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||
return ENOMEM;
|
||||
@@ -630,7 +633,7 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
|
||||
|
||||
tail = (void *)((char *)&req->data +
|
||||
sizeof(struct iwm_scan_channel_cfg_umac) *
|
||||
sc->ucode_capa.n_scan_channels);
|
||||
sc->sc_fw.ucode_capa.n_scan_channels);
|
||||
|
||||
/* Check if we're doing an active directed scan. */
|
||||
for (i = 0; i < nssid; i++) {
|
||||
@@ -694,7 +697,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
|
||||
|
||||
req_len = sizeof(struct iwm_scan_req_lmac) +
|
||||
(sizeof(struct iwm_scan_channel_cfg_lmac) *
|
||||
sc->ucode_capa.n_scan_channels) + sizeof(struct iwm_scan_probe_req);
|
||||
sc->sc_fw.ucode_capa.n_scan_channels) + sizeof(struct iwm_scan_probe_req);
|
||||
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||
return ENOMEM;
|
||||
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
@@ -764,7 +767,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
|
||||
ret = iwm_mvm_fill_probe_req(sc,
|
||||
(struct iwm_scan_probe_req *)(req->data +
|
||||
(sizeof(struct iwm_scan_channel_cfg_lmac) *
|
||||
sc->ucode_capa.n_scan_channels)));
|
||||
sc->sc_fw.ucode_capa.n_scan_channels)));
|
||||
if (ret) {
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
@@ -863,7 +866,7 @@ iwm_mvm_scan_stop_wait(struct iwm_softc *sc)
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Preparing to stop scan\n");
|
||||
|
||||
if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
ret = iwm_mvm_umac_scan_abort(sc);
|
||||
else
|
||||
ret = iwm_mvm_lmac_scan_abort(sc);
|
||||
|
||||
@@ -286,7 +286,7 @@ iwm_mvm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
|
||||
for (ac = 0; ac < WME_NUM_AC; ac++) {
|
||||
tfd_queue_msk |= htole32(1 << iwm_mvm_ac_to_tx_fifo[ac]);
|
||||
}
|
||||
ret = iwm_mvm_flush_tx_path(sc, tfd_queue_msk, 0);
|
||||
ret = iwm_mvm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC);
|
||||
if (ret)
|
||||
return ret;
|
||||
#ifdef notyet /* function not yet implemented */
|
||||
|
||||
+226
-10
@@ -155,31 +155,188 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.c 318212 2017-05-1
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_notif_wait.h>
|
||||
#include <dev/iwm/if_iwm_pcie_trans.h>
|
||||
#include <dev/iwm/if_iwm_time_event.h>
|
||||
|
||||
#define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000)
|
||||
|
||||
static void
|
||||
iwm_mvm_te_clear_data(struct iwm_softc *sc)
|
||||
{
|
||||
sc->sc_time_event_uid = 0;
|
||||
sc->sc_time_event_duration = 0;
|
||||
sc->sc_time_event_end_ticks = 0;
|
||||
sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the high priority TE use a time event type that has similar priority to
|
||||
* the FW's action scan priority.
|
||||
* Handles a FW notification for an event that is known to the driver.
|
||||
*
|
||||
* @mvm: the mvm component
|
||||
* @te_data: the time event data
|
||||
* @notif: the notification data corresponding the time event data.
|
||||
*/
|
||||
#define IWM_MVM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE
|
||||
#define IWM_MVM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
|
||||
static void
|
||||
iwm_mvm_te_handle_notif(struct iwm_softc *sc,
|
||||
struct iwm_time_event_notif *notif)
|
||||
{
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Handle time event notif - UID = 0x%x action %d\n",
|
||||
le32toh(notif->unique_id),
|
||||
le32toh(notif->action));
|
||||
|
||||
if (!le32toh(notif->status)) {
|
||||
const char *msg;
|
||||
|
||||
if (notif->action & htole32(IWM_TE_V2_NOTIF_HOST_EVENT_START))
|
||||
msg = "Time Event start notification failure";
|
||||
else
|
||||
msg = "Time Event end notification failure";
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE, "%s\n", msg);
|
||||
}
|
||||
|
||||
if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_END) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TE ended - current time %d, estimated end %d\n",
|
||||
ticks, sc->sc_time_event_end_ticks);
|
||||
|
||||
iwm_mvm_te_clear_data(sc);
|
||||
} else if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_START) {
|
||||
sc->sc_time_event_end_ticks =
|
||||
ticks + TU_TO_HZ(sc->sc_time_event_duration);
|
||||
} else {
|
||||
device_printf(sc->sc_dev, "Got TE with unknown action\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The Rx handler for time event notifications
|
||||
*/
|
||||
void
|
||||
iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_time_event_notif *notif = (void *)pkt->data;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Time event notification - UID = 0x%x action %d\n",
|
||||
le32toh(notif->unique_id),
|
||||
le32toh(notif->action));
|
||||
|
||||
iwm_mvm_te_handle_notif(sc, notif);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
struct iwm_time_event_notif *resp;
|
||||
int resp_len = iwm_rx_packet_payload_len(pkt);
|
||||
|
||||
if (pkt->hdr.code != IWM_TIME_EVENT_NOTIFICATION ||
|
||||
resp_len != sizeof(*resp)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Invalid TIME_EVENT_NOTIFICATION response\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
/* te_data->uid is already set in the TIME_EVENT_CMD response */
|
||||
if (le32toh(resp->unique_id) != sc->sc_time_event_uid)
|
||||
return false;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_NOTIFICATION response - UID = 0x%x\n",
|
||||
sc->sc_time_event_uid);
|
||||
if (!resp->status) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_NOTIFICATION received but not executed\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_time_event_response(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
struct iwm_time_event_resp *resp;
|
||||
int resp_len = iwm_rx_packet_payload_len(pkt);
|
||||
|
||||
if (pkt->hdr.code != IWM_TIME_EVENT_CMD ||
|
||||
resp_len != sizeof(*resp)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Invalid TIME_EVENT_CMD response\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
/* we should never get a response to another TIME_EVENT_CMD here */
|
||||
if (le32toh(resp->id) != IWM_TE_BSS_STA_AGGRESSIVE_ASSOC) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Got TIME_EVENT_CMD response with wrong id: %d\n",
|
||||
le32toh(resp->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc->sc_time_event_uid = le32toh(resp->unique_id);
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_CMD response - UID = 0x%x\n", sc->sc_time_event_uid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* XXX Use the te_data function argument properly, like in iwlwifi's code. */
|
||||
|
||||
static int
|
||||
iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
void *te_data, struct iwm_time_event_cmd *te_cmd)
|
||||
{
|
||||
static const uint16_t time_event_response[] = { IWM_TIME_EVENT_CMD };
|
||||
struct iwm_notification_wait wait_time_event;
|
||||
int ret;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD | IWM_DEBUG_RESET,
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Add new TE, duration %d TU\n", le32toh(te_cmd->duration));
|
||||
|
||||
ret = iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, IWM_CMD_SYNC,
|
||||
sizeof(*te_cmd), te_cmd);
|
||||
sc->sc_time_event_duration = le32toh(te_cmd->duration);
|
||||
|
||||
/*
|
||||
* Use a notification wait, which really just processes the
|
||||
* command response and doesn't wait for anything, in order
|
||||
* to be able to process the response and get the UID inside
|
||||
* the RX path. Using CMD_WANT_SKB doesn't work because it
|
||||
* stores the buffer and then wakes up this thread, by which
|
||||
* time another notification (that the time event started)
|
||||
* might already be processed unsuccessfully.
|
||||
*/
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_time_event,
|
||||
time_event_response,
|
||||
nitems(time_event_response),
|
||||
iwm_mvm_time_event_response, /*te_data*/NULL);
|
||||
|
||||
ret = iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*te_cmd),
|
||||
te_cmd);
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD | IWM_DEBUG_RESET,
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Couldn't send IWM_TIME_EVENT_CMD: %d\n",
|
||||
__func__, ret);
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_time_event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* No need to wait for anything, so just pass 1 (0 isn't valid) */
|
||||
IWM_UNLOCK(sc);
|
||||
ret = iwm_wait_notification(sc->sc_notif_wait, &wait_time_event, 1);
|
||||
IWM_LOCK(sc);
|
||||
/* should never fail */
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to get response for IWM_TIME_EVENT_CMD: %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -187,10 +344,16 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
|
||||
void
|
||||
iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
uint32_t duration, uint32_t max_delay)
|
||||
uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif)
|
||||
{
|
||||
const uint16_t te_notif_response[] = { IWM_TIME_EVENT_NOTIFICATION };
|
||||
struct iwm_notification_wait wait_te_notif;
|
||||
struct iwm_time_event_cmd time_cmd = {};
|
||||
|
||||
/* Do nothing if a time event is already scheduled. */
|
||||
if (sc->sc_flags & IWM_FLAG_TE_ACTIVE)
|
||||
return;
|
||||
|
||||
time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
|
||||
time_cmd.id_and_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color));
|
||||
@@ -209,5 +372,58 @@ iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
IWM_TE_V2_NOTIF_HOST_EVENT_END |
|
||||
IWM_T2_V2_START_IMMEDIATELY);
|
||||
|
||||
iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd);
|
||||
if (!wait_for_notif) {
|
||||
iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd);
|
||||
DELAY(100);
|
||||
sc->sc_flags |= IWM_FLAG_TE_ACTIVE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create notification_wait for the TIME_EVENT_NOTIFICATION to use
|
||||
* right after we send the time event
|
||||
*/
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_te_notif,
|
||||
te_notif_response, nitems(te_notif_response),
|
||||
iwm_mvm_te_notif, /*te_data*/NULL);
|
||||
|
||||
/* If TE was sent OK - wait for the notification that started */
|
||||
if (iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to add TE to protect session\n", __func__);
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_te_notif);
|
||||
} else {
|
||||
sc->sc_flags |= IWM_FLAG_TE_ACTIVE;
|
||||
IWM_UNLOCK(sc);
|
||||
if (iwm_wait_notification(sc->sc_notif_wait, &wait_te_notif,
|
||||
TU_TO_HZ(max_delay))) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to protect session until TE\n",
|
||||
__func__);
|
||||
}
|
||||
IWM_LOCK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iwm_mvm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
struct iwm_time_event_cmd time_cmd = {};
|
||||
|
||||
/* Do nothing if the time event has already ended. */
|
||||
if ((sc->sc_flags & IWM_FLAG_TE_ACTIVE) == 0)
|
||||
return;
|
||||
|
||||
time_cmd.id = htole32(sc->sc_time_event_uid);
|
||||
time_cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
|
||||
time_cmd.id_and_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color));
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Removing TE 0x%x\n", __func__, le32toh(time_cmd.id));
|
||||
if (iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(time_cmd),
|
||||
&time_cmd) == 0)
|
||||
iwm_mvm_te_clear_data(sc);
|
||||
|
||||
DELAY(100);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,11 @@
|
||||
#ifndef __IF_IWM_TIME_EVENT_H__
|
||||
#define __IF_IWM_TIME_EVENT_H__
|
||||
|
||||
extern void iwm_mvm_rx_time_event_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt);
|
||||
extern void iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
uint32_t duration, uint32_t max_delay);
|
||||
uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif);
|
||||
extern void iwm_mvm_stop_session_protection(struct iwm_softc *sc,
|
||||
struct iwm_vap *ivp);
|
||||
|
||||
#endif /* __IF_IWM_TIME_EVENT_H__ */
|
||||
|
||||
@@ -702,8 +702,9 @@ enum iwm_ucode_tlv_api {
|
||||
* @IWM_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG: support getting more shared
|
||||
* memory addresses from the firmware.
|
||||
* @IWM_UCODE_TLV_CAPA_LQM_SUPPORT: supports Link Quality Measurement
|
||||
* @IWM_UCODE_TLV_CAPA_LMAC_UPLOAD: supports upload mode in lmac (1=supported,
|
||||
* 0=no support)
|
||||
* @IWM_UCODE_TLV_CAPA_TX_POWER_ACK: reduced TX power API has larger
|
||||
* command size (command version 4) that supports toggling ACK TX
|
||||
* power reduction.
|
||||
*
|
||||
* @IWM_NUM_UCODE_TLV_CAPA: number of bits used
|
||||
*/
|
||||
@@ -744,9 +745,9 @@ enum iwm_ucode_tlv_capa {
|
||||
IWM_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT = 75,
|
||||
IWM_UCODE_TLV_CAPA_CTDP_SUPPORT = 76,
|
||||
IWM_UCODE_TLV_CAPA_USNIFFER_UNIFIED = 77,
|
||||
IWM_UCODE_TLV_CAPA_LMAC_UPLOAD = 79,
|
||||
IWM_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG = 80,
|
||||
IWM_UCODE_TLV_CAPA_LQM_SUPPORT = 81,
|
||||
IWM_UCODE_TLV_CAPA_TX_POWER_ACK = 84,
|
||||
|
||||
IWM_NUM_UCODE_TLV_CAPA = 128
|
||||
};
|
||||
@@ -1790,15 +1791,11 @@ enum {
|
||||
/* Power - legacy power table command */
|
||||
IWM_POWER_TABLE_CMD = 0x77,
|
||||
IWM_PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
|
||||
IWM_LTR_CONFIG = 0xee,
|
||||
|
||||
/* Thermal Throttling*/
|
||||
IWM_REPLY_THERMAL_MNG_BACKOFF = 0x7e,
|
||||
|
||||
/* Scanning */
|
||||
IWM_SCAN_ABORT_CMD = 0x81,
|
||||
IWM_SCAN_START_NOTIFICATION = 0x82,
|
||||
IWM_SCAN_RESULTS_NOTIFICATION = 0x83,
|
||||
|
||||
/* NVM */
|
||||
IWM_NVM_ACCESS_CMD = 0x88,
|
||||
|
||||
@@ -1869,8 +1866,6 @@ enum {
|
||||
IWM_NET_DETECT_PROFILES_CMD = 0x57,
|
||||
IWM_NET_DETECT_HOTSPOTS_CMD = 0x58,
|
||||
IWM_NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
|
||||
|
||||
IWM_REPLY_MAX = 0xff,
|
||||
};
|
||||
|
||||
enum iwm_phy_ops_subcmd_ids {
|
||||
@@ -1921,6 +1916,51 @@ struct iwm_reduce_tx_power_cmd {
|
||||
uint16_t pwr_restriction;
|
||||
} __packed; /* IWM_TX_REDUCED_POWER_API_S_VER_1 */
|
||||
|
||||
enum iwm_dev_tx_power_cmd_mode {
|
||||
IWM_TX_POWER_MODE_SET_MAC = 0,
|
||||
IWM_TX_POWER_MODE_SET_DEVICE = 1,
|
||||
IWM_TX_POWER_MODE_SET_CHAINS = 2,
|
||||
IWM_TX_POWER_MODE_SET_ACK = 3,
|
||||
}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_4 */;
|
||||
|
||||
#define IWM_NUM_CHAIN_LIMITS 2
|
||||
#define IWM_NUM_SUB_BANDS 5
|
||||
|
||||
/**
|
||||
* struct iwm_dev_tx_power_cmd - TX power reduction command
|
||||
* @set_mode: see &enum iwl_dev_tx_power_cmd_mode
|
||||
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
|
||||
* @pwr_restriction: TX power restriction in 1/8 dBms.
|
||||
* @dev_24: device TX power restriction in 1/8 dBms
|
||||
* @dev_52_low: device TX power restriction upper band - low
|
||||
* @dev_52_high: device TX power restriction upper band - high
|
||||
* @per_chain_restriction: per chain restrictions
|
||||
*/
|
||||
struct iwm_dev_tx_power_cmd_v3 {
|
||||
uint32_t set_mode;
|
||||
uint32_t mac_context_id;
|
||||
uint16_t pwr_restriction;
|
||||
uint16_t dev_24;
|
||||
uint16_t dev_52_low;
|
||||
uint16_t dev_52_high;
|
||||
uint16_t per_chain_restriction[IWM_NUM_CHAIN_LIMITS][IWM_NUM_SUB_BANDS];
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_3 */
|
||||
|
||||
#define IWM_DEV_MAX_TX_POWER 0x7FFF
|
||||
|
||||
/**
|
||||
* struct iwm_dev_tx_power_cmd - TX power reduction command
|
||||
* @v3: version 3 of the command, embedded here for easier software handling
|
||||
* @enable_ack_reduction: enable or disable close range ack TX power
|
||||
* reduction.
|
||||
*/
|
||||
struct iwm_dev_tx_power_cmd {
|
||||
/* v4 is just an extension of v3 - keep this here */
|
||||
struct iwm_dev_tx_power_cmd_v3 v3;
|
||||
uint8_t enable_ack_reduction;
|
||||
uint8_t reserved[3];
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_4 */
|
||||
|
||||
/*
|
||||
* Calibration control struct.
|
||||
* Sent as part of the phy configuration command.
|
||||
@@ -2102,41 +2142,13 @@ enum {
|
||||
|
||||
#define IWM_ALIVE_FLG_RFKILL (1 << 0)
|
||||
|
||||
struct iwm_mvm_alive_resp_ver1 {
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint8_t ucode_minor;
|
||||
uint8_t ucode_major;
|
||||
uint16_t id;
|
||||
uint8_t api_minor;
|
||||
uint8_t api_major;
|
||||
struct iwm_lmac_alive {
|
||||
uint32_t ucode_major;
|
||||
uint32_t ucode_minor;
|
||||
uint8_t ver_subtype;
|
||||
uint8_t ver_type;
|
||||
uint8_t mac;
|
||||
uint8_t opt;
|
||||
uint16_t reserved2;
|
||||
uint32_t timestamp;
|
||||
uint32_t error_event_table_ptr; /* SRAM address for error log */
|
||||
uint32_t log_event_table_ptr; /* SRAM address for event log */
|
||||
uint32_t cpu_register_ptr;
|
||||
uint32_t dbgm_config_ptr;
|
||||
uint32_t alive_counter_ptr;
|
||||
uint32_t scd_base_ptr; /* SRAM address for SCD */
|
||||
} __packed; /* IWM_ALIVE_RES_API_S_VER_1 */
|
||||
|
||||
struct iwm_mvm_alive_resp_ver2 {
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint8_t ucode_minor;
|
||||
uint8_t ucode_major;
|
||||
uint16_t id;
|
||||
uint8_t api_minor;
|
||||
uint8_t api_major;
|
||||
uint8_t ver_subtype;
|
||||
uint8_t ver_type;
|
||||
uint8_t mac;
|
||||
uint8_t opt;
|
||||
uint16_t reserved2;
|
||||
uint32_t timestamp;
|
||||
uint32_t error_event_table_ptr; /* SRAM address for error log */
|
||||
uint32_t log_event_table_ptr; /* SRAM address for LMAC event log */
|
||||
@@ -2146,36 +2158,28 @@ struct iwm_mvm_alive_resp_ver2 {
|
||||
uint32_t scd_base_ptr; /* SRAM address for SCD */
|
||||
uint32_t st_fwrd_addr; /* pointer to Store and forward */
|
||||
uint32_t st_fwrd_size;
|
||||
uint8_t umac_minor; /* UMAC version: minor */
|
||||
uint8_t umac_major; /* UMAC version: major */
|
||||
uint16_t umac_id; /* UMAC version: id */
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */
|
||||
|
||||
struct iwm_umac_alive {
|
||||
uint32_t umac_major; /* UMAC version: major */
|
||||
uint32_t umac_minor; /* UMAC version: minor */
|
||||
uint32_t error_info_addr; /* SRAM address for UMAC error log */
|
||||
uint32_t dbg_print_buff_addr;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_2 */
|
||||
} __packed; /* UMAC_ALIVE_DATA_API_S_VER_2 */
|
||||
|
||||
struct iwm_mvm_alive_resp_v3 {
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
struct iwm_lmac_alive lmac_data;
|
||||
struct iwm_umac_alive umac_data;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_3 */
|
||||
|
||||
struct iwm_mvm_alive_resp {
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint32_t ucode_minor;
|
||||
uint32_t ucode_major;
|
||||
uint8_t ver_subtype;
|
||||
uint8_t ver_type;
|
||||
uint8_t mac;
|
||||
uint8_t opt;
|
||||
uint32_t timestamp;
|
||||
uint32_t error_event_table_ptr; /* SRAM address for error log */
|
||||
uint32_t log_event_table_ptr; /* SRAM address for LMAC event log */
|
||||
uint32_t cpu_register_ptr;
|
||||
uint32_t dbgm_config_ptr;
|
||||
uint32_t alive_counter_ptr;
|
||||
uint32_t scd_base_ptr; /* SRAM address for SCD */
|
||||
uint32_t st_fwrd_addr; /* pointer to Store and forward */
|
||||
uint32_t st_fwrd_size;
|
||||
uint32_t umac_minor; /* UMAC version: minor */
|
||||
uint32_t umac_major; /* UMAC version: major */
|
||||
uint32_t error_info_addr; /* SRAM address for UMAC error log */
|
||||
uint32_t dbg_print_buff_addr;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_3 */
|
||||
struct iwm_lmac_alive lmac_data[2];
|
||||
struct iwm_umac_alive umac_data;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_4 */
|
||||
|
||||
/* Error response/notification */
|
||||
enum {
|
||||
@@ -3527,6 +3531,57 @@ struct iwm_nonqos_seq_query_cmd {
|
||||
|
||||
/* Power Management Commands, Responses, Notifications */
|
||||
|
||||
/**
|
||||
* enum iwm_ltr_config_flags - masks for LTR config command flags
|
||||
* @IWM_LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
|
||||
* @IWM_LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
|
||||
* memory access
|
||||
* @IWM_LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
|
||||
* reg change
|
||||
* @IWM_LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
|
||||
* D0 to D3
|
||||
* @IWM_LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
|
||||
* @IWM_LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
|
||||
* @IWM_LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
|
||||
*/
|
||||
enum iwm_ltr_config_flags {
|
||||
IWM_LTR_CFG_FLAG_FEATURE_ENABLE = (1 << 0),
|
||||
IWM_LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = (1 << 1),
|
||||
IWM_LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = (1 << 2),
|
||||
IWM_LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = (1 << 3),
|
||||
IWM_LTR_CFG_FLAG_SW_SET_SHORT = (1 << 4),
|
||||
IWM_LTR_CFG_FLAG_SW_SET_LONG = (1 << 5),
|
||||
IWM_LTR_CFG_FLAG_DENIE_C10_ON_PD = (1 << 6),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_ltr_config_cmd_v1 - configures the LTR
|
||||
* @flags: See %enum iwm_ltr_config_flags
|
||||
*/
|
||||
struct iwm_ltr_config_cmd_v1 {
|
||||
uint32_t flags;
|
||||
uint32_t static_long;
|
||||
uint32_t static_short;
|
||||
} __packed; /* LTR_CAPABLE_API_S_VER_1 */
|
||||
|
||||
#define IWM_LTR_VALID_STATES_NUM 4
|
||||
|
||||
/**
|
||||
* struct iwm_ltr_config_cmd - configures the LTR
|
||||
* @flags: See %enum iwm_ltr_config_flags
|
||||
* @static_long:
|
||||
* @static_short:
|
||||
* @ltr_cfg_values:
|
||||
* @ltr_short_idle_timeout:
|
||||
*/
|
||||
struct iwm_ltr_config_cmd {
|
||||
uint32_t flags;
|
||||
uint32_t static_long;
|
||||
uint32_t static_short;
|
||||
uint32_t ltr_cfg_values[IWM_LTR_VALID_STATES_NUM];
|
||||
uint32_t ltr_short_idle_timeout;
|
||||
} __packed; /* LTR_CAPABLE_API_S_VER_2 */
|
||||
|
||||
/* Radio LP RX Energy Threshold measured in dBm */
|
||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD 75
|
||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD_MAX 94
|
||||
@@ -4228,29 +4283,6 @@ enum iwm_tx_pm_timeouts {
|
||||
#define IWM_TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
|
||||
#define IWM_TX_CMD_SEC_KEY128 0x08
|
||||
|
||||
/* TODO: how does these values are OK with only 16 bit variable??? */
|
||||
/*
|
||||
* TX command next frame info
|
||||
*
|
||||
* bits 0:2 - security control (IWM_TX_CMD_SEC_*)
|
||||
* bit 3 - immediate ACK required
|
||||
* bit 4 - rate is taken from STA table
|
||||
* bit 5 - frame belongs to BA stream
|
||||
* bit 6 - immediate BA response expected
|
||||
* bit 7 - unused
|
||||
* bits 8:15 - Station ID
|
||||
* bits 16:31 - rate
|
||||
*/
|
||||
#define IWM_TX_CMD_NEXT_FRAME_ACK_MSK (0x8)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_STA_RATE_MSK (0x10)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_BA_MSK (0x20)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_IMM_BA_RSP_MSK (0x40)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_FLAGS_MSK (0xf8)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_STA_ID_MSK (0xff00)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_STA_ID_POS (8)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_RATE_MSK (0xffff0000)
|
||||
#define IWM_TX_CMD_NEXT_FRAME_RATE_POS (16)
|
||||
|
||||
/*
|
||||
* TX command Frame life time in us - to be written in pm_frame_timeout
|
||||
*/
|
||||
@@ -4288,7 +4320,7 @@ enum iwm_tx_pm_timeouts {
|
||||
* @initial_rate_index: index into the rate table for initial TX attempt.
|
||||
* Applied if IWM_TX_CMD_FLG_STA_RATE_MSK is set, normally 0 for data frames.
|
||||
* @key: security key
|
||||
* @next_frame_flags: IWM_TX_CMD_SEC_* and IWM_TX_CMD_NEXT_FRAME_*
|
||||
* @reserved3: reserved
|
||||
* @life_time: frame life time (usecs??)
|
||||
* @dram_lsb_ptr: Physical address of scratch area in the command (try_cnt +
|
||||
* btkill_cnd + reserved), first 32 bits. "0" disables usage.
|
||||
@@ -4952,50 +4984,14 @@ struct iwm_periodic_scan_complete {
|
||||
uint32_t reserved;
|
||||
} __packed;
|
||||
|
||||
/* How many statistics are gathered for each channel */
|
||||
#define IWM_SCAN_RESULTS_STATISTICS 1
|
||||
|
||||
/**
|
||||
* enum iwm_scan_complete_status - status codes for scan complete notifications
|
||||
* @IWM_SCAN_COMP_STATUS_OK: scan completed successfully
|
||||
* @IWM_SCAN_COMP_STATUS_ABORT: scan was aborted by user
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_SLEEP: sending null sleep packet failed
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT: timeout before channel is ready
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_PROBE: sending probe request failed
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_WAKEUP: sending null wakeup packet failed
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_ANTENNAS: invalid antennas chosen at scan command
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_INTERNAL: internal error caused scan abort
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax
|
||||
* @IWM_SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful
|
||||
* (not an error!)
|
||||
* @IWM_SCAN_COMP_STATUS_ITERATION_END: indicates end of one repeatition the driver
|
||||
* asked for
|
||||
* @IWM_SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events
|
||||
*/
|
||||
enum iwm_scan_complete_status {
|
||||
IWM_SCAN_COMP_STATUS_OK = 0x1,
|
||||
IWM_SCAN_COMP_STATUS_ABORT = 0x2,
|
||||
IWM_SCAN_COMP_STATUS_ERR_SLEEP = 0x3,
|
||||
IWM_SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT = 0x4,
|
||||
IWM_SCAN_COMP_STATUS_ERR_PROBE = 0x5,
|
||||
IWM_SCAN_COMP_STATUS_ERR_WAKEUP = 0x6,
|
||||
IWM_SCAN_COMP_STATUS_ERR_ANTENNAS = 0x7,
|
||||
IWM_SCAN_COMP_STATUS_ERR_INTERNAL = 0x8,
|
||||
IWM_SCAN_COMP_STATUS_ERR_COEX = 0x9,
|
||||
IWM_SCAN_COMP_STATUS_P2P_ACTION_OK = 0xA,
|
||||
IWM_SCAN_COMP_STATUS_ITERATION_END = 0x0B,
|
||||
IWM_SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_scan_results_notif - scan results for one channel
|
||||
* ( IWM_SCAN_RESULTS_NOTIFICATION = 0x83 )
|
||||
* struct iwm_scan_results_notif - scan results for one channel -
|
||||
* SCAN_RESULT_NTF_API_S_VER_3
|
||||
* @channel: which channel the results are from
|
||||
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
|
||||
* @probe_status: IWM_SCAN_PROBE_STATUS_*, indicates success of probe request
|
||||
* @num_probe_not_sent: # of request that weren't sent due to not enough time
|
||||
* @duration: duration spent in channel, in usecs
|
||||
* @statistics: statistics gathered for this channel
|
||||
*/
|
||||
struct iwm_scan_results_notif {
|
||||
uint8_t channel;
|
||||
@@ -5003,8 +4999,7 @@ struct iwm_scan_results_notif {
|
||||
uint8_t probe_status;
|
||||
uint8_t num_probe_not_sent;
|
||||
uint32_t duration;
|
||||
uint32_t statistics[IWM_SCAN_RESULTS_STATISTICS];
|
||||
} __packed; /* IWM_SCAN_RESULT_NTF_API_S_VER_2 */
|
||||
} __packed;
|
||||
|
||||
enum iwm_scan_framework_client {
|
||||
IWM_SCAN_CLIENT_SCHED_SCAN = (1 << 0),
|
||||
|
||||
@@ -139,15 +139,6 @@ struct iwm_tx_radiotap_header {
|
||||
|
||||
#define IWM_UCODE_SECTION_MAX 16
|
||||
|
||||
/*
|
||||
* fw_status is used to determine if we've already parsed the firmware file
|
||||
*
|
||||
* In addition to the following, status < 0 ==> -error
|
||||
*/
|
||||
#define IWM_FW_STATUS_NONE 0
|
||||
#define IWM_FW_STATUS_INPROGRESS 1
|
||||
#define IWM_FW_STATUS_DONE 2
|
||||
|
||||
/**
|
||||
* enum iwm_ucode_type
|
||||
*
|
||||
@@ -195,16 +186,20 @@ struct iwm_fw_desc {
|
||||
uint32_t offset; /* offset in the device */
|
||||
};
|
||||
|
||||
struct iwm_fw_img {
|
||||
struct iwm_fw_desc sec[IWM_UCODE_SECTION_MAX];
|
||||
int fw_count;
|
||||
int is_dual_cpus;
|
||||
uint32_t paging_mem_size;
|
||||
};
|
||||
|
||||
struct iwm_fw_info {
|
||||
const struct firmware *fw_fp;
|
||||
int fw_status;
|
||||
|
||||
struct iwm_fw_sects {
|
||||
struct iwm_fw_desc fw_sect[IWM_UCODE_SECTION_MAX];
|
||||
int fw_count;
|
||||
int is_dual_cpus;
|
||||
uint32_t paging_mem_size;
|
||||
} fw_sects[IWM_UCODE_TYPE_MAX];
|
||||
/* ucode images */
|
||||
struct iwm_fw_img img[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
struct iwm_ucode_capabilities ucode_capa;
|
||||
|
||||
uint32_t phy_config;
|
||||
uint8_t valid_tx_ant;
|
||||
@@ -370,6 +365,7 @@ struct iwm_bf_data {
|
||||
struct iwm_vap {
|
||||
struct ieee80211vap iv_vap;
|
||||
int is_uploaded;
|
||||
int iv_auth;
|
||||
|
||||
int (*iv_newstate)(struct ieee80211vap *,
|
||||
enum ieee80211_state, int);
|
||||
@@ -404,8 +400,6 @@ struct iwm_node {
|
||||
int in_assoc;
|
||||
|
||||
struct iwm_lq_cmd in_lq;
|
||||
|
||||
uint8_t in_ridx[IEEE80211_RATE_MAXSIZE];
|
||||
};
|
||||
#define IWM_NODE(_ni) ((struct iwm_node *)(_ni))
|
||||
|
||||
@@ -440,6 +434,7 @@ struct iwm_softc {
|
||||
#define IWM_FLAG_BUSY (1 << 4)
|
||||
#define IWM_FLAG_SCANNING (1 << 5)
|
||||
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
||||
#define IWM_FLAG_TE_ACTIVE (1 << 7)
|
||||
|
||||
struct intr_config_hook sc_preinit_hook;
|
||||
struct callout sc_watchdog_to;
|
||||
@@ -482,7 +477,6 @@ struct iwm_softc {
|
||||
int ucode_loaded;
|
||||
char sc_fwver[32];
|
||||
|
||||
struct iwm_ucode_capabilities ucode_capa;
|
||||
char sc_fw_mcc[3];
|
||||
|
||||
int sc_intmask;
|
||||
@@ -544,7 +538,7 @@ struct iwm_softc {
|
||||
int cmd_hold_nic_awake;
|
||||
|
||||
/* Firmware status */
|
||||
uint32_t error_event_table;
|
||||
uint32_t error_event_table[2];
|
||||
uint32_t log_event_table;
|
||||
uint32_t umac_error_event_table;
|
||||
int support_umac_log;
|
||||
@@ -565,6 +559,20 @@ struct iwm_softc {
|
||||
/* Indicate if device power save is allowed */
|
||||
boolean_t sc_ps_disabled;
|
||||
|
||||
int sc_ltr_enabled;
|
||||
|
||||
/* Track firmware state for STA association. */
|
||||
int sc_firmware_state;
|
||||
|
||||
/* Unique ID (assigned by the firmware) of the current Time Event. */
|
||||
uint32_t sc_time_event_uid;
|
||||
|
||||
/* Duration of the Time Event in TU. */
|
||||
uint32_t sc_time_event_duration;
|
||||
|
||||
/* Expected end of the Time Event in HZ ticks. */
|
||||
int sc_time_event_end_ticks;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
uint32_t sc_intr_status_1;
|
||||
uint32_t sc_intr_status_2;
|
||||
|
||||
Reference in New Issue
Block a user