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,
|
IWM_DEVICE_FAMILY_8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IWM_DEFAULT_MAX_TX_POWER 22
|
||||||
|
|
||||||
/* Antenna presence definitions */
|
/* Antenna presence definitions */
|
||||||
#define IWM_ANT_NONE 0x0
|
#define IWM_ANT_NONE 0x0
|
||||||
#define IWM_ANT_A (1 << 0)
|
#define IWM_ANT_A (1 << 0)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ enum {
|
|||||||
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
||||||
IWM_DEBUG_FW = 0x00200000, /* Firmware management */
|
IWM_DEBUG_FW = 0x00200000, /* Firmware management */
|
||||||
IWM_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */
|
IWM_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */
|
||||||
|
IWM_DEBUG_TE = 0x00800000, /* Time Event handling */
|
||||||
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||||
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||||
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ iwm_free_fw_paging(struct iwm_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
int sec_idx, idx;
|
||||||
uint32_t offset = 0;
|
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)
|
* CPU2 paging image (including instruction and data)
|
||||||
*/
|
*/
|
||||||
for (sec_idx = 0; sec_idx < IWM_UCODE_SECTION_MAX; sec_idx++) {
|
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++;
|
sec_idx++;
|
||||||
break;
|
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
|
* If paging is enabled there should be at least 2 more sections left
|
||||||
* (one for CSS and one for Paging data)
|
* (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,
|
device_printf(sc->sc_dev,
|
||||||
"Paging: Missing CSS and/or paging sections\n");
|
"Paging: Missing CSS and/or paging sections\n");
|
||||||
iwm_free_fw_paging(sc);
|
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);
|
sec_idx);
|
||||||
|
|
||||||
memcpy(sc->fw_paging_db[0].fw_paging_block.vaddr,
|
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);
|
sc->fw_paging_db[0].fw_paging_size);
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
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++) {
|
for (idx = 1; idx < sc->num_of_paging_blk; idx++) {
|
||||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
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);
|
sc->fw_paging_db[idx].fw_paging_size);
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
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 */
|
/* copy the last paging block */
|
||||||
if (sc->num_of_pages_in_last_blk > 0) {
|
if (sc->num_of_pages_in_last_blk > 0) {
|
||||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
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_FW_PAGING_SIZE * sc->num_of_pages_in_last_blk);
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
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
|
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 blk_idx = 0;
|
||||||
int error, num_of_pages;
|
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
|
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;
|
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 */
|
/* send paging cmd to FW in case CPU2 has paging image */
|
||||||
int
|
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;
|
int blk_idx;
|
||||||
uint32_t dev_phy_addr;
|
uint32_t dev_phy_addr;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
#define IWM_PAGING_TLV_SECURE_MASK 1
|
#define IWM_PAGING_TLV_SECURE_MASK 1
|
||||||
|
|
||||||
extern void iwm_free_fw_paging(struct iwm_softc *);
|
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_save_fw_paging(struct iwm_softc *, const struct iwm_fw_img *);
|
||||||
extern int iwm_send_paging_cmd(struct iwm_softc *, const struct iwm_fw_sects *);
|
extern int iwm_send_paging_cmd(struct iwm_softc *, const struct iwm_fw_img *);
|
||||||
|
|
||||||
#endif /* __IF_IWM_FW_H__ */
|
#endif /* __IF_IWM_FW_H__ */
|
||||||
|
|||||||
@@ -162,6 +162,9 @@ iwm_led_blink_timeout(void *arg)
|
|||||||
{
|
{
|
||||||
struct iwm_softc *sc = arg;
|
struct iwm_softc *sc = arg;
|
||||||
|
|
||||||
|
if (sc->sc_attached == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (iwm_mvm_led_is_enabled(sc))
|
if (iwm_mvm_led_is_enabled(sc))
|
||||||
iwm_mvm_led_disable(sc);
|
iwm_mvm_led_disable(sc);
|
||||||
else
|
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
|
* iwm_mvm_mac_ctxt_changed() when already authenticating or
|
||||||
* associating, ni->ni_bssid should always make sense here.
|
* 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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -406,18 +406,39 @@ iwm_prepare_card_hw(struct iwm_softc *sc)
|
|||||||
void
|
void
|
||||||
iwm_apm_config(struct iwm_softc *sc)
|
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) {
|
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
|
||||||
/* Um the Linux driver prints "Disabling L0S for this one ... */
|
* 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_SETBITS(sc, IWM_CSR_GIO_REG,
|
||||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
/* ... and "Enabling" here */
|
|
||||||
IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
|
IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
|
||||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
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)
|
ch_id_to_ch_index(uint16_t ch_id)
|
||||||
{
|
{
|
||||||
if (!is_valid_channel(ch_id))
|
if (!is_valid_channel(ch_id))
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
||||||
if (ch_id <= 14)
|
if (ch_id <= 14)
|
||||||
return ch_id - 1;
|
return ch_id - 1;
|
||||||
@@ -509,7 +509,7 @@ iwm_phy_db_send_all_channel_groups(struct iwm_phy_db *phy_db,
|
|||||||
int err;
|
int err;
|
||||||
struct iwm_phy_db_entry *entry;
|
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++) {
|
for (i = 0; i < max_ch_groups; i++) {
|
||||||
entry = iwm_phy_db_get_section(phy_db,
|
entry = iwm_phy_db_get_section(phy_db,
|
||||||
type,
|
type,
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ static inline boolean_t
|
|||||||
iwm_mvm_rrm_scan_needed(struct iwm_softc *sc)
|
iwm_mvm_rrm_scan_needed(struct iwm_softc *sc)
|
||||||
{
|
{
|
||||||
/* require rrm scan whenever the fw supports it */
|
/* 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);
|
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
|
/* If this happens, the firmware has mistakenly sent an LMAC
|
||||||
* notification during UMAC scans -- warn and ignore it.
|
* 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,
|
device_printf(sc->sc_dev,
|
||||||
"%s: Mistakenly got LMAC notification during UMAC scan\n",
|
"%s: Mistakenly got LMAC notification during UMAC scan\n",
|
||||||
__func__);
|
__func__);
|
||||||
@@ -307,7 +307,8 @@ iwm_mvm_lmac_scan_fill_channels(struct iwm_softc *sc,
|
|||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (nchan = j = 0;
|
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];
|
c = ss->ss_chans[j];
|
||||||
/*
|
/*
|
||||||
* Catch other channels, in case we have 900MHz channels or
|
* 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;
|
int j;
|
||||||
|
|
||||||
for (nchan = j = 0;
|
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];
|
c = ss->ss_chans[j];
|
||||||
/*
|
/*
|
||||||
* Catch other channels, in case we have 900MHz channels or
|
* 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_36M | IWM_SCAN_CONFIG_RATE_48M |
|
||||||
IWM_SCAN_CONFIG_RATE_54M);
|
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);
|
scan_config = malloc(cmd_size, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||||
if (scan_config == NULL)
|
if (scan_config == NULL)
|
||||||
@@ -523,7 +525,8 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
|||||||
IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
|
IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
|
||||||
|
|
||||||
for (nchan = j = 0;
|
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];
|
c = &ic->ic_channels[j];
|
||||||
/* For 2GHz, only populate 11b channels */
|
/* For 2GHz, only populate 11b channels */
|
||||||
/* For 5GHz, only populate 11a channels */
|
/* For 5GHz, only populate 11a channels */
|
||||||
@@ -566,7 +569,7 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
|||||||
static boolean_t
|
static boolean_t
|
||||||
iwm_mvm_scan_use_ebs(struct iwm_softc *sc)
|
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:
|
/* We can only use EBS if:
|
||||||
* 1. the feature is supported;
|
* 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) +
|
req_len = sizeof(struct iwm_scan_req_umac) +
|
||||||
(sizeof(struct iwm_scan_channel_cfg_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);
|
sizeof(struct iwm_scan_req_umac_tail);
|
||||||
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
@@ -630,7 +633,7 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
|
|||||||
|
|
||||||
tail = (void *)((char *)&req->data +
|
tail = (void *)((char *)&req->data +
|
||||||
sizeof(struct iwm_scan_channel_cfg_umac) *
|
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. */
|
/* Check if we're doing an active directed scan. */
|
||||||
for (i = 0; i < nssid; i++) {
|
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) +
|
req_len = sizeof(struct iwm_scan_req_lmac) +
|
||||||
(sizeof(struct iwm_scan_channel_cfg_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)
|
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
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,
|
ret = iwm_mvm_fill_probe_req(sc,
|
||||||
(struct iwm_scan_probe_req *)(req->data +
|
(struct iwm_scan_probe_req *)(req->data +
|
||||||
(sizeof(struct iwm_scan_channel_cfg_lmac) *
|
(sizeof(struct iwm_scan_channel_cfg_lmac) *
|
||||||
sc->ucode_capa.n_scan_channels)));
|
sc->sc_fw.ucode_capa.n_scan_channels)));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free(req, M_DEVBUF);
|
free(req, M_DEVBUF);
|
||||||
return ret;
|
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");
|
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);
|
ret = iwm_mvm_umac_scan_abort(sc);
|
||||||
else
|
else
|
||||||
ret = iwm_mvm_lmac_scan_abort(sc);
|
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++) {
|
for (ac = 0; ac < WME_NUM_AC; ac++) {
|
||||||
tfd_queue_msk |= htole32(1 << iwm_mvm_ac_to_tx_fifo[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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
#ifdef notyet /* function not yet implemented */
|
#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_iwmvar.h>
|
||||||
#include <dev/iwm/if_iwm_debug.h>
|
#include <dev/iwm/if_iwm_debug.h>
|
||||||
#include <dev/iwm/if_iwm_util.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_pcie_trans.h>
|
||||||
#include <dev/iwm/if_iwm_time_event.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
|
* Handles a FW notification for an event that is known to the driver.
|
||||||
* the FW's action scan priority.
|
*
|
||||||
|
* @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
|
static void
|
||||||
#define IWM_MVM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
|
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
|
static int
|
||||||
iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||||
void *te_data, struct iwm_time_event_cmd *te_cmd)
|
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;
|
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));
|
"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,
|
sc->sc_time_event_duration = le32toh(te_cmd->duration);
|
||||||
sizeof(*te_cmd), te_cmd);
|
|
||||||
|
/*
|
||||||
|
* 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) {
|
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",
|
"%s: Couldn't send IWM_TIME_EVENT_CMD: %d\n",
|
||||||
__func__, ret);
|
__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;
|
return ret;
|
||||||
@@ -187,10 +344,16 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
|||||||
|
|
||||||
void
|
void
|
||||||
iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
|
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 = {};
|
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.action = htole32(IWM_FW_CTXT_ACTION_ADD);
|
||||||
time_cmd.id_and_color =
|
time_cmd.id_and_color =
|
||||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->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_TE_V2_NOTIF_HOST_EVENT_END |
|
||||||
IWM_T2_V2_START_IMMEDIATELY);
|
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__
|
#ifndef __IF_IWM_TIME_EVENT_H__
|
||||||
#define __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,
|
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__ */
|
#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
|
* @IWM_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG: support getting more shared
|
||||||
* memory addresses from the firmware.
|
* memory addresses from the firmware.
|
||||||
* @IWM_UCODE_TLV_CAPA_LQM_SUPPORT: supports Link Quality Measurement
|
* @IWM_UCODE_TLV_CAPA_LQM_SUPPORT: supports Link Quality Measurement
|
||||||
* @IWM_UCODE_TLV_CAPA_LMAC_UPLOAD: supports upload mode in lmac (1=supported,
|
* @IWM_UCODE_TLV_CAPA_TX_POWER_ACK: reduced TX power API has larger
|
||||||
* 0=no support)
|
* command size (command version 4) that supports toggling ACK TX
|
||||||
|
* power reduction.
|
||||||
*
|
*
|
||||||
* @IWM_NUM_UCODE_TLV_CAPA: number of bits used
|
* @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_TEMP_THS_REPORT_SUPPORT = 75,
|
||||||
IWM_UCODE_TLV_CAPA_CTDP_SUPPORT = 76,
|
IWM_UCODE_TLV_CAPA_CTDP_SUPPORT = 76,
|
||||||
IWM_UCODE_TLV_CAPA_USNIFFER_UNIFIED = 77,
|
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_EXTEND_SHARED_MEM_CFG = 80,
|
||||||
IWM_UCODE_TLV_CAPA_LQM_SUPPORT = 81,
|
IWM_UCODE_TLV_CAPA_LQM_SUPPORT = 81,
|
||||||
|
IWM_UCODE_TLV_CAPA_TX_POWER_ACK = 84,
|
||||||
|
|
||||||
IWM_NUM_UCODE_TLV_CAPA = 128
|
IWM_NUM_UCODE_TLV_CAPA = 128
|
||||||
};
|
};
|
||||||
@@ -1790,15 +1791,11 @@ enum {
|
|||||||
/* Power - legacy power table command */
|
/* Power - legacy power table command */
|
||||||
IWM_POWER_TABLE_CMD = 0x77,
|
IWM_POWER_TABLE_CMD = 0x77,
|
||||||
IWM_PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
|
IWM_PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
|
||||||
|
IWM_LTR_CONFIG = 0xee,
|
||||||
|
|
||||||
/* Thermal Throttling*/
|
/* Thermal Throttling*/
|
||||||
IWM_REPLY_THERMAL_MNG_BACKOFF = 0x7e,
|
IWM_REPLY_THERMAL_MNG_BACKOFF = 0x7e,
|
||||||
|
|
||||||
/* Scanning */
|
|
||||||
IWM_SCAN_ABORT_CMD = 0x81,
|
|
||||||
IWM_SCAN_START_NOTIFICATION = 0x82,
|
|
||||||
IWM_SCAN_RESULTS_NOTIFICATION = 0x83,
|
|
||||||
|
|
||||||
/* NVM */
|
/* NVM */
|
||||||
IWM_NVM_ACCESS_CMD = 0x88,
|
IWM_NVM_ACCESS_CMD = 0x88,
|
||||||
|
|
||||||
@@ -1869,8 +1866,6 @@ enum {
|
|||||||
IWM_NET_DETECT_PROFILES_CMD = 0x57,
|
IWM_NET_DETECT_PROFILES_CMD = 0x57,
|
||||||
IWM_NET_DETECT_HOTSPOTS_CMD = 0x58,
|
IWM_NET_DETECT_HOTSPOTS_CMD = 0x58,
|
||||||
IWM_NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
|
IWM_NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
|
||||||
|
|
||||||
IWM_REPLY_MAX = 0xff,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum iwm_phy_ops_subcmd_ids {
|
enum iwm_phy_ops_subcmd_ids {
|
||||||
@@ -1921,6 +1916,51 @@ struct iwm_reduce_tx_power_cmd {
|
|||||||
uint16_t pwr_restriction;
|
uint16_t pwr_restriction;
|
||||||
} __packed; /* IWM_TX_REDUCED_POWER_API_S_VER_1 */
|
} __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.
|
* Calibration control struct.
|
||||||
* Sent as part of the phy configuration command.
|
* Sent as part of the phy configuration command.
|
||||||
@@ -2102,41 +2142,13 @@ enum {
|
|||||||
|
|
||||||
#define IWM_ALIVE_FLG_RFKILL (1 << 0)
|
#define IWM_ALIVE_FLG_RFKILL (1 << 0)
|
||||||
|
|
||||||
struct iwm_mvm_alive_resp_ver1 {
|
struct iwm_lmac_alive {
|
||||||
uint16_t status;
|
uint32_t ucode_major;
|
||||||
uint16_t flags;
|
uint32_t ucode_minor;
|
||||||
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_subtype;
|
||||||
uint8_t ver_type;
|
uint8_t ver_type;
|
||||||
uint8_t mac;
|
uint8_t mac;
|
||||||
uint8_t opt;
|
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 timestamp;
|
||||||
uint32_t error_event_table_ptr; /* SRAM address for error log */
|
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 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 scd_base_ptr; /* SRAM address for SCD */
|
||||||
uint32_t st_fwrd_addr; /* pointer to Store and forward */
|
uint32_t st_fwrd_addr; /* pointer to Store and forward */
|
||||||
uint32_t st_fwrd_size;
|
uint32_t st_fwrd_size;
|
||||||
uint8_t umac_minor; /* UMAC version: minor */
|
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */
|
||||||
uint8_t umac_major; /* UMAC version: major */
|
|
||||||
uint16_t umac_id; /* UMAC version: id */
|
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 error_info_addr; /* SRAM address for UMAC error log */
|
||||||
uint32_t dbg_print_buff_addr;
|
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 {
|
struct iwm_mvm_alive_resp {
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint32_t ucode_minor;
|
struct iwm_lmac_alive lmac_data[2];
|
||||||
uint32_t ucode_major;
|
struct iwm_umac_alive umac_data;
|
||||||
uint8_t ver_subtype;
|
} __packed; /* ALIVE_RES_API_S_VER_4 */
|
||||||
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 */
|
|
||||||
|
|
||||||
/* Error response/notification */
|
/* Error response/notification */
|
||||||
enum {
|
enum {
|
||||||
@@ -3527,6 +3531,57 @@ struct iwm_nonqos_seq_query_cmd {
|
|||||||
|
|
||||||
/* Power Management Commands, Responses, Notifications */
|
/* 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 */
|
/* Radio LP RX Energy Threshold measured in dBm */
|
||||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD 75
|
#define IWM_POWER_LPRX_RSSI_THRESHOLD 75
|
||||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD_MAX 94
|
#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_WEP_KEY_IDX_MSK 0xc0
|
||||||
#define IWM_TX_CMD_SEC_KEY128 0x08
|
#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
|
* 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.
|
* @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.
|
* Applied if IWM_TX_CMD_FLG_STA_RATE_MSK is set, normally 0 for data frames.
|
||||||
* @key: security key
|
* @key: security key
|
||||||
* @next_frame_flags: IWM_TX_CMD_SEC_* and IWM_TX_CMD_NEXT_FRAME_*
|
* @reserved3: reserved
|
||||||
* @life_time: frame life time (usecs??)
|
* @life_time: frame life time (usecs??)
|
||||||
* @dram_lsb_ptr: Physical address of scratch area in the command (try_cnt +
|
* @dram_lsb_ptr: Physical address of scratch area in the command (try_cnt +
|
||||||
* btkill_cnd + reserved), first 32 bits. "0" disables usage.
|
* btkill_cnd + reserved), first 32 bits. "0" disables usage.
|
||||||
@@ -4952,50 +4984,14 @@ struct iwm_periodic_scan_complete {
|
|||||||
uint32_t reserved;
|
uint32_t reserved;
|
||||||
} __packed;
|
} __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
|
* struct iwm_scan_results_notif - scan results for one channel -
|
||||||
* @IWM_SCAN_COMP_STATUS_OK: scan completed successfully
|
* SCAN_RESULT_NTF_API_S_VER_3
|
||||||
* @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 )
|
|
||||||
* @channel: which channel the results are from
|
* @channel: which channel the results are from
|
||||||
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
|
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
|
||||||
* @probe_status: IWM_SCAN_PROBE_STATUS_*, indicates success of probe request
|
* @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
|
* @num_probe_not_sent: # of request that weren't sent due to not enough time
|
||||||
* @duration: duration spent in channel, in usecs
|
* @duration: duration spent in channel, in usecs
|
||||||
* @statistics: statistics gathered for this channel
|
|
||||||
*/
|
*/
|
||||||
struct iwm_scan_results_notif {
|
struct iwm_scan_results_notif {
|
||||||
uint8_t channel;
|
uint8_t channel;
|
||||||
@@ -5003,8 +4999,7 @@ struct iwm_scan_results_notif {
|
|||||||
uint8_t probe_status;
|
uint8_t probe_status;
|
||||||
uint8_t num_probe_not_sent;
|
uint8_t num_probe_not_sent;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
uint32_t statistics[IWM_SCAN_RESULTS_STATISTICS];
|
} __packed;
|
||||||
} __packed; /* IWM_SCAN_RESULT_NTF_API_S_VER_2 */
|
|
||||||
|
|
||||||
enum iwm_scan_framework_client {
|
enum iwm_scan_framework_client {
|
||||||
IWM_SCAN_CLIENT_SCHED_SCAN = (1 << 0),
|
IWM_SCAN_CLIENT_SCHED_SCAN = (1 << 0),
|
||||||
|
|||||||
@@ -139,15 +139,6 @@ struct iwm_tx_radiotap_header {
|
|||||||
|
|
||||||
#define IWM_UCODE_SECTION_MAX 16
|
#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
|
* enum iwm_ucode_type
|
||||||
*
|
*
|
||||||
@@ -195,16 +186,20 @@ struct iwm_fw_desc {
|
|||||||
uint32_t offset; /* offset in the device */
|
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 {
|
struct iwm_fw_info {
|
||||||
const struct firmware *fw_fp;
|
const struct firmware *fw_fp;
|
||||||
int fw_status;
|
|
||||||
|
|
||||||
struct iwm_fw_sects {
|
/* ucode images */
|
||||||
struct iwm_fw_desc fw_sect[IWM_UCODE_SECTION_MAX];
|
struct iwm_fw_img img[IWM_UCODE_TYPE_MAX];
|
||||||
int fw_count;
|
|
||||||
int is_dual_cpus;
|
struct iwm_ucode_capabilities ucode_capa;
|
||||||
uint32_t paging_mem_size;
|
|
||||||
} fw_sects[IWM_UCODE_TYPE_MAX];
|
|
||||||
|
|
||||||
uint32_t phy_config;
|
uint32_t phy_config;
|
||||||
uint8_t valid_tx_ant;
|
uint8_t valid_tx_ant;
|
||||||
@@ -370,6 +365,7 @@ struct iwm_bf_data {
|
|||||||
struct iwm_vap {
|
struct iwm_vap {
|
||||||
struct ieee80211vap iv_vap;
|
struct ieee80211vap iv_vap;
|
||||||
int is_uploaded;
|
int is_uploaded;
|
||||||
|
int iv_auth;
|
||||||
|
|
||||||
int (*iv_newstate)(struct ieee80211vap *,
|
int (*iv_newstate)(struct ieee80211vap *,
|
||||||
enum ieee80211_state, int);
|
enum ieee80211_state, int);
|
||||||
@@ -404,8 +400,6 @@ struct iwm_node {
|
|||||||
int in_assoc;
|
int in_assoc;
|
||||||
|
|
||||||
struct iwm_lq_cmd in_lq;
|
struct iwm_lq_cmd in_lq;
|
||||||
|
|
||||||
uint8_t in_ridx[IEEE80211_RATE_MAXSIZE];
|
|
||||||
};
|
};
|
||||||
#define IWM_NODE(_ni) ((struct iwm_node *)(_ni))
|
#define IWM_NODE(_ni) ((struct iwm_node *)(_ni))
|
||||||
|
|
||||||
@@ -440,6 +434,7 @@ struct iwm_softc {
|
|||||||
#define IWM_FLAG_BUSY (1 << 4)
|
#define IWM_FLAG_BUSY (1 << 4)
|
||||||
#define IWM_FLAG_SCANNING (1 << 5)
|
#define IWM_FLAG_SCANNING (1 << 5)
|
||||||
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
||||||
|
#define IWM_FLAG_TE_ACTIVE (1 << 7)
|
||||||
|
|
||||||
struct intr_config_hook sc_preinit_hook;
|
struct intr_config_hook sc_preinit_hook;
|
||||||
struct callout sc_watchdog_to;
|
struct callout sc_watchdog_to;
|
||||||
@@ -482,7 +477,6 @@ struct iwm_softc {
|
|||||||
int ucode_loaded;
|
int ucode_loaded;
|
||||||
char sc_fwver[32];
|
char sc_fwver[32];
|
||||||
|
|
||||||
struct iwm_ucode_capabilities ucode_capa;
|
|
||||||
char sc_fw_mcc[3];
|
char sc_fw_mcc[3];
|
||||||
|
|
||||||
int sc_intmask;
|
int sc_intmask;
|
||||||
@@ -544,7 +538,7 @@ struct iwm_softc {
|
|||||||
int cmd_hold_nic_awake;
|
int cmd_hold_nic_awake;
|
||||||
|
|
||||||
/* Firmware status */
|
/* Firmware status */
|
||||||
uint32_t error_event_table;
|
uint32_t error_event_table[2];
|
||||||
uint32_t log_event_table;
|
uint32_t log_event_table;
|
||||||
uint32_t umac_error_event_table;
|
uint32_t umac_error_event_table;
|
||||||
int support_umac_log;
|
int support_umac_log;
|
||||||
@@ -565,6 +559,20 @@ struct iwm_softc {
|
|||||||
/* Indicate if device power save is allowed */
|
/* Indicate if device power save is allowed */
|
||||||
boolean_t sc_ps_disabled;
|
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__
|
#ifdef __HAIKU__
|
||||||
uint32_t sc_intr_status_1;
|
uint32_t sc_intr_status_1;
|
||||||
uint32_t sc_intr_status_2;
|
uint32_t sc_intr_status_2;
|
||||||
|
|||||||
Reference in New Issue
Block a user