You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'iwlwifi-next-for-kalle-2015-03-01' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
* add triggers for firmware dump collection * remove support for -9.ucode * new statitics API * rate control improvements
This commit is contained in:
@@ -1549,7 +1549,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
||||
table.blink1, table.blink2, table.ilink1,
|
||||
table.ilink2, table.bcon_time, table.gp1,
|
||||
table.gp2, table.gp3, table.ucode_ver,
|
||||
table.hw_ver, table.brd_ver);
|
||||
table.hw_ver, 0, table.brd_ver);
|
||||
IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
|
||||
desc_lookup(table.error_id));
|
||||
IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
#define IWL3160_UCODE_API_OK 10
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MIN 9
|
||||
#define IWL3160_UCODE_API_MIN 9
|
||||
#define IWL7260_UCODE_API_MIN 10
|
||||
#define IWL3160_UCODE_API_MIN 10
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL7260_NVM_VERSION 0x0a1d
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
#define IWL8000_UCODE_API_OK 10
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MIN 9
|
||||
#define IWL8000_UCODE_API_MIN 10
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
|
||||
@@ -431,11 +431,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
|
||||
TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
|
||||
u32 data1, u32 data2, u32 line, u32 blink1,
|
||||
u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
|
||||
u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
|
||||
u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver,
|
||||
u32 brd_ver),
|
||||
TP_ARGS(dev, desc, tsf_low, data1, data2, line,
|
||||
blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
|
||||
gp3, ucode_ver, hw_ver, brd_ver),
|
||||
gp3, major, minor, hw_ver, brd_ver),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u32, desc)
|
||||
@@ -451,7 +451,8 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
|
||||
__field(u32, gp1)
|
||||
__field(u32, gp2)
|
||||
__field(u32, gp3)
|
||||
__field(u32, ucode_ver)
|
||||
__field(u32, major)
|
||||
__field(u32, minor)
|
||||
__field(u32, hw_ver)
|
||||
__field(u32, brd_ver)
|
||||
),
|
||||
@@ -470,21 +471,22 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
|
||||
__entry->gp1 = gp1;
|
||||
__entry->gp2 = gp2;
|
||||
__entry->gp3 = gp3;
|
||||
__entry->ucode_ver = ucode_ver;
|
||||
__entry->major = major;
|
||||
__entry->minor = minor;
|
||||
__entry->hw_ver = hw_ver;
|
||||
__entry->brd_ver = brd_ver;
|
||||
),
|
||||
TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
|
||||
"blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
|
||||
"bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
|
||||
"hw 0x%08X brd 0x%08X",
|
||||
"bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X "
|
||||
"minor 0x%08X hw 0x%08X brd 0x%08X",
|
||||
__get_str(dev), __entry->desc, __entry->tsf_low,
|
||||
__entry->data1,
|
||||
__entry->data2, __entry->line, __entry->blink1,
|
||||
__entry->blink2, __entry->ilink1, __entry->ilink2,
|
||||
__entry->bcon_time, __entry->gp1, __entry->gp2,
|
||||
__entry->gp3, __entry->ucode_ver, __entry->hw_ver,
|
||||
__entry->brd_ver)
|
||||
__entry->gp3, __entry->major, __entry->minor,
|
||||
__entry->hw_ver, __entry->brd_ver)
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_ucode_event,
|
||||
|
||||
@@ -175,6 +175,8 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
|
||||
kfree(drv->fw.dbg_dest_tlv);
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
|
||||
kfree(drv->fw.dbg_conf_tlv[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
|
||||
kfree(drv->fw.dbg_trigger_tlv[i]);
|
||||
|
||||
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
|
||||
iwl_free_fw_img(drv, drv->fw.img + i);
|
||||
@@ -293,8 +295,10 @@ struct iwl_firmware_pieces {
|
||||
|
||||
/* FW debug data parsed for driver usage */
|
||||
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_MAX];
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -842,6 +846,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
capa->n_scan_channels =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_VERSION: {
|
||||
__le32 *ptr = (void *)tlv_data;
|
||||
u32 major, minor;
|
||||
u8 local_comp;
|
||||
|
||||
if (tlv_len != sizeof(u32) * 3)
|
||||
goto invalid_tlv_len;
|
||||
|
||||
major = le32_to_cpup(ptr++);
|
||||
minor = le32_to_cpup(ptr++);
|
||||
local_comp = le32_to_cpup(ptr);
|
||||
|
||||
snprintf(drv->fw.fw_version,
|
||||
sizeof(drv->fw.fw_version), "%u.%u.%u",
|
||||
major, minor, local_comp);
|
||||
break;
|
||||
}
|
||||
case IWL_UCODE_TLV_FW_DBG_DEST: {
|
||||
struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
|
||||
|
||||
@@ -897,6 +918,31 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
|
||||
break;
|
||||
}
|
||||
case IWL_UCODE_TLV_FW_DBG_TRIGGER: {
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger =
|
||||
(void *)tlv_data;
|
||||
u32 trigger_id = le32_to_cpu(trigger->id);
|
||||
|
||||
if (trigger_id >= ARRAY_SIZE(drv->fw.dbg_trigger_tlv)) {
|
||||
IWL_ERR(drv,
|
||||
"Skip unknown trigger: %u\n",
|
||||
trigger->id);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pieces->dbg_trigger_tlv[trigger_id]) {
|
||||
IWL_ERR(drv,
|
||||
"Ignore duplicate dbg trigger %u\n",
|
||||
trigger->id);
|
||||
break;
|
||||
}
|
||||
|
||||
IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id);
|
||||
|
||||
pieces->dbg_trigger_tlv[trigger_id] = trigger;
|
||||
pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len;
|
||||
break;
|
||||
}
|
||||
case IWL_UCODE_TLV_SEC_RT_USNIFFER:
|
||||
usniffer_images = true;
|
||||
iwl_store_ucode_sec(pieces, tlv_data,
|
||||
@@ -1107,7 +1153,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
if (err)
|
||||
goto try_again;
|
||||
|
||||
api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
|
||||
if (drv->fw.ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)
|
||||
api_ver = drv->fw.ucode_ver;
|
||||
else
|
||||
api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
|
||||
|
||||
/*
|
||||
* api_ver should match the api version forming part of the
|
||||
@@ -1178,6 +1227,19 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
|
||||
if (pieces->dbg_trigger_tlv[i]) {
|
||||
drv->fw.dbg_trigger_tlv_len[i] =
|
||||
pieces->dbg_trigger_tlv_len[i];
|
||||
drv->fw.dbg_trigger_tlv[i] =
|
||||
kmemdup(pieces->dbg_trigger_tlv[i],
|
||||
drv->fw.dbg_trigger_tlv_len[i],
|
||||
GFP_KERNEL);
|
||||
if (!drv->fw.dbg_trigger_tlv[i])
|
||||
goto out_free_fw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we can no longer fail, copy information */
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
* sections like this in a single file.
|
||||
* @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
|
||||
* @IWL_FW_ERROR_DUMP_MEM: chunk of memory
|
||||
* @IWL_FW_ERROR_DUMP_ERROR_INFO: description of what triggered this dump.
|
||||
* Structured as &struct iwl_fw_error_dump_trigger_desc.
|
||||
*/
|
||||
enum iwl_fw_error_dump_type {
|
||||
/* 0 is deprecated */
|
||||
@@ -94,6 +96,7 @@ enum iwl_fw_error_dump_type {
|
||||
IWL_FW_ERROR_DUMP_TXF = 7,
|
||||
IWL_FW_ERROR_DUMP_FH_REGS = 8,
|
||||
IWL_FW_ERROR_DUMP_MEM = 9,
|
||||
IWL_FW_ERROR_DUMP_ERROR_INFO = 10,
|
||||
|
||||
IWL_FW_ERROR_DUMP_MAX,
|
||||
};
|
||||
@@ -230,4 +233,47 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
|
||||
return (void *)(data->data + le32_to_cpu(data->len));
|
||||
}
|
||||
|
||||
/**
|
||||
* enum iwl_fw_dbg_trigger - triggers available
|
||||
*
|
||||
* @FW_DBG_TRIGGER_USER: trigger log collection by user
|
||||
* This should not be defined as a trigger to the driver, but a value the
|
||||
* driver should set to indicate that the trigger was initiated by the
|
||||
* user.
|
||||
* @FW_DBG_TRIGGER_FW_ASSERT: trigger log collection when the firmware asserts
|
||||
* @FW_DBG_TRIGGER_MISSED_BEACONS: trigger log collection when beacons are
|
||||
* missed.
|
||||
* @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch.
|
||||
* @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a
|
||||
* command response or a notification.
|
||||
* @FW_DB_TRIGGER_RESERVED: reserved
|
||||
* @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold.
|
||||
* @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon
|
||||
* goes below a threshold.
|
||||
*/
|
||||
enum iwl_fw_dbg_trigger {
|
||||
FW_DBG_TRIGGER_INVALID = 0,
|
||||
FW_DBG_TRIGGER_USER,
|
||||
FW_DBG_TRIGGER_FW_ASSERT,
|
||||
FW_DBG_TRIGGER_MISSED_BEACONS,
|
||||
FW_DBG_TRIGGER_CHANNEL_SWITCH,
|
||||
FW_DBG_TRIGGER_FW_NOTIF,
|
||||
FW_DB_TRIGGER_RESERVED,
|
||||
FW_DBG_TRIGGER_STATS,
|
||||
FW_DBG_TRIGGER_RSSI,
|
||||
|
||||
/* must be last */
|
||||
FW_DBG_TRIGGER_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_trigger_desc - describes the trigger condition
|
||||
* @type: %enum iwl_fw_dbg_trigger
|
||||
* @data: raw data about what happened
|
||||
*/
|
||||
struct iwl_fw_error_dump_trigger_desc {
|
||||
__le32 type;
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
#endif /* __fw_error_dump_h__ */
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#define __iwl_fw_file_h__
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
/* v1/v2 uCode file layout */
|
||||
struct iwl_ucode_header {
|
||||
@@ -133,8 +134,10 @@ enum iwl_ucode_tlv_type {
|
||||
IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
|
||||
IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
|
||||
IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
|
||||
IWL_UCODE_TLV_FW_VERSION = 36,
|
||||
IWL_UCODE_TLV_FW_DBG_DEST = 38,
|
||||
IWL_UCODE_TLV_FW_DBG_CONF = 39,
|
||||
IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
@@ -156,7 +159,8 @@ struct iwl_tlv_ucode_header {
|
||||
__le32 zero;
|
||||
__le32 magic;
|
||||
u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
|
||||
__le32 ver; /* major/minor/API/serial */
|
||||
/* major/minor/API/serial or major in new format */
|
||||
__le32 ver;
|
||||
__le32 build;
|
||||
__le64 ignore;
|
||||
/*
|
||||
@@ -237,7 +241,6 @@ enum iwl_ucode_tlv_flag {
|
||||
* enum iwl_ucode_tlv_api - ucode api
|
||||
* @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
|
||||
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
|
||||
* @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
|
||||
* @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
|
||||
* @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
|
||||
* longer than the passive one, which is essential for fragmented scan.
|
||||
@@ -250,11 +253,12 @@ enum iwl_ucode_tlv_flag {
|
||||
* @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too.
|
||||
* @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
|
||||
* @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
|
||||
* @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10
|
||||
* @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
|
||||
*/
|
||||
enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
|
||||
IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
|
||||
IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
|
||||
IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
|
||||
IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
|
||||
IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
|
||||
@@ -263,6 +267,8 @@ enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16),
|
||||
IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17),
|
||||
IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18),
|
||||
IWL_UCODE_TLV_API_STATS_V10 = BIT(19),
|
||||
IWL_UCODE_TLV_API_NEW_VERSION = BIT(20),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -284,6 +290,8 @@ enum iwl_ucode_tlv_api {
|
||||
* which also implies support for the scheduler configuration command
|
||||
* @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
|
||||
* @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
|
||||
* @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics
|
||||
* @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running
|
||||
*/
|
||||
enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
|
||||
@@ -298,6 +306,8 @@ enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
|
||||
IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
|
||||
IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
|
||||
IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22),
|
||||
IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28),
|
||||
};
|
||||
|
||||
/* The default calibrate table size if not specified by firmware file */
|
||||
@@ -450,44 +460,129 @@ struct iwl_fw_dbg_conf_hcmd {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger - a TLV that describes a debug configuration
|
||||
* enum iwl_fw_dbg_trigger_mode - triggers functionalities
|
||||
*
|
||||
* @enabled: is this trigger enabled
|
||||
* @reserved:
|
||||
* @len: length, in bytes, of the %trigger field
|
||||
* @trigger: pointer to a trigger struct
|
||||
* @IWL_FW_DBG_TRIGGER_START: when trigger occurs re-conf the dbg mechanism
|
||||
* @IWL_FW_DBG_TRIGGER_STOP: when trigger occurs pull the dbg data
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger {
|
||||
u8 enabled;
|
||||
u8 reserved;
|
||||
u8 len;
|
||||
u8 trigger[0];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum iwl_fw_dbg_conf - configurations available
|
||||
*
|
||||
* @FW_DBG_CUSTOM: take this configuration from alive
|
||||
* Note that the trigger is NO-OP for this configuration
|
||||
*/
|
||||
enum iwl_fw_dbg_conf {
|
||||
FW_DBG_CUSTOM = 0,
|
||||
|
||||
/* must be last */
|
||||
FW_DBG_MAX,
|
||||
FW_DBG_INVALID = 0xff,
|
||||
enum iwl_fw_dbg_trigger_mode {
|
||||
IWL_FW_DBG_TRIGGER_START = BIT(0),
|
||||
IWL_FW_DBG_TRIGGER_STOP = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration
|
||||
*
|
||||
* @id: %enum iwl_fw_dbg_conf
|
||||
* enum iwl_fw_dbg_trigger_vif_type - define the VIF type for a trigger
|
||||
* @IWL_FW_DBG_CONF_VIF_ANY: any vif type
|
||||
* @IWL_FW_DBG_CONF_VIF_IBSS: IBSS mode
|
||||
* @IWL_FW_DBG_CONF_VIF_STATION: BSS mode
|
||||
* @IWL_FW_DBG_CONF_VIF_AP: AP mode
|
||||
* @IWL_FW_DBG_CONF_VIF_P2P_CLIENT: P2P Client mode
|
||||
* @IWL_FW_DBG_CONF_VIF_P2P_GO: P2P GO mode
|
||||
* @IWL_FW_DBG_CONF_VIF_P2P_DEVICE: P2P device
|
||||
*/
|
||||
enum iwl_fw_dbg_trigger_vif_type {
|
||||
IWL_FW_DBG_CONF_VIF_ANY = NL80211_IFTYPE_UNSPECIFIED,
|
||||
IWL_FW_DBG_CONF_VIF_IBSS = NL80211_IFTYPE_ADHOC,
|
||||
IWL_FW_DBG_CONF_VIF_STATION = NL80211_IFTYPE_STATION,
|
||||
IWL_FW_DBG_CONF_VIF_AP = NL80211_IFTYPE_AP,
|
||||
IWL_FW_DBG_CONF_VIF_P2P_CLIENT = NL80211_IFTYPE_P2P_CLIENT,
|
||||
IWL_FW_DBG_CONF_VIF_P2P_GO = NL80211_IFTYPE_P2P_GO,
|
||||
IWL_FW_DBG_CONF_VIF_P2P_DEVICE = NL80211_IFTYPE_P2P_DEVICE,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_tlv - a TLV that describes the trigger
|
||||
* @id: %enum iwl_fw_dbg_trigger
|
||||
* @vif_type: %enum iwl_fw_dbg_trigger_vif_type
|
||||
* @stop_conf_ids: bitmap of configurations this trigger relates to.
|
||||
* if the mode is %IWL_FW_DBG_TRIGGER_STOP, then if the bit corresponding
|
||||
* to the currently running configuration is set, the data should be
|
||||
* collected.
|
||||
* @stop_delay: how many milliseconds to wait before collecting the data
|
||||
* after the STOP trigger fires.
|
||||
* @mode: %enum iwl_fw_dbg_trigger_mode - can be stop / start of both
|
||||
* @start_conf_id: if mode is %IWL_FW_DBG_TRIGGER_START, this defines what
|
||||
* configuration should be applied when the triggers kicks in.
|
||||
* @occurrences: number of occurrences. 0 means the trigger will never fire.
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_tlv {
|
||||
__le32 id;
|
||||
__le32 vif_type;
|
||||
__le32 stop_conf_ids;
|
||||
__le32 stop_delay;
|
||||
u8 mode;
|
||||
u8 start_conf_id;
|
||||
__le16 occurrences;
|
||||
__le32 reserved[2];
|
||||
|
||||
u8 data[0];
|
||||
} __packed;
|
||||
|
||||
#define FW_DBG_START_FROM_ALIVE 0
|
||||
#define FW_DBG_CONF_MAX 32
|
||||
#define FW_DBG_INVALID 0xff
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_missed_bcon - configures trigger for missed beacons
|
||||
* @stop_consec_missed_bcon: stop recording if threshold is crossed.
|
||||
* @stop_consec_missed_bcon_since_rx: stop recording if threshold is crossed.
|
||||
* @start_consec_missed_bcon: start recording if threshold is crossed.
|
||||
* @start_consec_missed_bcon_since_rx: start recording if threshold is crossed.
|
||||
* @reserved1: reserved
|
||||
* @reserved2: reserved
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_missed_bcon {
|
||||
__le32 stop_consec_missed_bcon;
|
||||
__le32 stop_consec_missed_bcon_since_rx;
|
||||
__le32 reserved2[2];
|
||||
__le32 start_consec_missed_bcon;
|
||||
__le32 start_consec_missed_bcon_since_rx;
|
||||
__le32 reserved1[2];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_cmd - configures trigger for messages from FW.
|
||||
* cmds: the list of commands to trigger the collection on
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_cmd {
|
||||
struct cmd {
|
||||
u8 cmd_id;
|
||||
u8 group_id;
|
||||
} __packed cmds[16];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* iwl_fw_dbg_trigger_stats - configures trigger for statistics
|
||||
* @stop_offset: the offset of the value to be monitored
|
||||
* @stop_threshold: the threshold above which to collect
|
||||
* @start_offset: the offset of the value to be monitored
|
||||
* @start_threshold: the threshold above which to start recording
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_stats {
|
||||
__le32 stop_offset;
|
||||
__le32 stop_threshold;
|
||||
__le32 start_offset;
|
||||
__le32 start_threshold;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_low_rssi - trigger for low beacon RSSI
|
||||
* @rssi: RSSI value to trigger at
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_low_rssi {
|
||||
__le32 rssi;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
|
||||
* @id: conf id
|
||||
* @usniffer: should the uSniffer image be used
|
||||
* @num_of_hcmds: how many HCMDs to send are present here
|
||||
* @hcmd: a variable length host command to be sent to apply the configuration.
|
||||
* If there is more than one HCMD to send, they will appear one after the
|
||||
* other and be sent in the order that they appear in.
|
||||
* This parses IWL_UCODE_TLV_FW_DBG_CONF
|
||||
* This parses IWL_UCODE_TLV_FW_DBG_CONF. The user can add up-to
|
||||
* %FW_DBG_CONF_MAX configuration per run.
|
||||
*/
|
||||
struct iwl_fw_dbg_conf_tlv {
|
||||
u8 id;
|
||||
@@ -495,8 +590,6 @@ struct iwl_fw_dbg_conf_tlv {
|
||||
u8 reserved;
|
||||
u8 num_of_hcmds;
|
||||
struct iwl_fw_dbg_conf_hcmd hcmd;
|
||||
|
||||
/* struct iwl_fw_dbg_trigger sits after all variable length hcmds */
|
||||
} __packed;
|
||||
|
||||
#endif /* __iwl_fw_file_h__ */
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "iwl-fw-file.h"
|
||||
#include "iwl-fw-error-dump.h"
|
||||
|
||||
/**
|
||||
* enum iwl_ucode_type
|
||||
@@ -157,6 +158,8 @@ struct iwl_fw_cscheme_list {
|
||||
* @dbg_dest_tlv: points to the destination TLV for debug
|
||||
* @dbg_conf_tlv: array of pointers to configuration TLVs for debug
|
||||
* @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
|
||||
* @dbg_trigger_tlv: array of pointers to triggers TLVs
|
||||
* @dbg_trigger_tlv_len: lengths of the @dbg_trigger_tlv entries
|
||||
* @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
|
||||
*/
|
||||
struct iwl_fw {
|
||||
@@ -186,9 +189,10 @@ struct iwl_fw {
|
||||
u32 sdio_adma_addr;
|
||||
|
||||
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_MAX];
|
||||
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
u8 dbg_dest_reg_num;
|
||||
};
|
||||
|
||||
@@ -206,37 +210,6 @@ static inline const char *get_fw_dbg_mode_string(int mode)
|
||||
}
|
||||
}
|
||||
|
||||
static inline const struct iwl_fw_dbg_trigger *
|
||||
iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id)
|
||||
{
|
||||
const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
|
||||
u8 *ptr;
|
||||
int i;
|
||||
|
||||
if (!conf_tlv)
|
||||
return NULL;
|
||||
|
||||
ptr = (void *)&conf_tlv->hcmd;
|
||||
for (i = 0; i < conf_tlv->num_of_hcmds; i++) {
|
||||
ptr += sizeof(conf_tlv->hcmd);
|
||||
ptr += le16_to_cpu(conf_tlv->hcmd.len);
|
||||
}
|
||||
|
||||
return (const struct iwl_fw_dbg_trigger *)ptr;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
|
||||
{
|
||||
const struct iwl_fw_dbg_trigger *trigger =
|
||||
iwl_fw_dbg_conf_get_trigger(fw, id);
|
||||
|
||||
if (!trigger)
|
||||
return false;
|
||||
|
||||
return trigger->enabled;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
|
||||
{
|
||||
@@ -248,4 +221,18 @@ iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
|
||||
return conf_tlv->usniffer;
|
||||
}
|
||||
|
||||
#define iwl_fw_dbg_trigger_enabled(fw, id) ({ \
|
||||
void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)]; \
|
||||
unlikely(__dbg_trigger); \
|
||||
})
|
||||
|
||||
static inline struct iwl_fw_dbg_trigger_tlv*
|
||||
iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, u8 id)
|
||||
{
|
||||
if (WARN_ON(id >= ARRAY_SIZE(fw->dbg_trigger_tlv)))
|
||||
return NULL;
|
||||
|
||||
return fw->dbg_trigger_tlv[id];
|
||||
}
|
||||
|
||||
#endif /* __iwl_fw_h__ */
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
#include "iwl-trans.h"
|
||||
|
||||
#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
|
||||
#define IWL_NUM_PAPD_CH_GROUPS 7
|
||||
#define IWL_NUM_PAPD_CH_GROUPS 9
|
||||
#define IWL_NUM_TXP_CH_GROUPS 9
|
||||
|
||||
struct iwl_phy_db_entry {
|
||||
|
||||
@@ -370,7 +370,6 @@ enum secure_load_status_reg {
|
||||
#define MON_BUFF_CYCLE_CNT (0xa03c48)
|
||||
|
||||
#define DBGC_IN_SAMPLE (0xa03c00)
|
||||
#define DBGC_OUT_CTRL (0xa03c0c)
|
||||
|
||||
/* FW chicken bits */
|
||||
#define LMPM_CHICK 0xA01FF8
|
||||
|
||||
@@ -595,6 +595,7 @@ enum iwl_d0i3_mode {
|
||||
* @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
|
||||
* @dbg_dest_tlv: points to the destination TLV for debug
|
||||
* @dbg_conf_tlv: array of pointers to configuration TLVs for debug
|
||||
* @dbg_trigger_tlv: array of pointers to triggers TLVs for debug
|
||||
* @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
|
||||
*/
|
||||
struct iwl_trans {
|
||||
@@ -628,7 +629,8 @@ struct iwl_trans {
|
||||
u64 dflt_pwr_limit;
|
||||
|
||||
const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
|
||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
||||
u8 dbg_dest_reg_num;
|
||||
|
||||
enum iwl_d0i3_mode d0i3_mode;
|
||||
|
||||
@@ -611,7 +611,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
||||
bt_cmd->enabled_modules |=
|
||||
cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
|
||||
|
||||
if (IWL_MVM_BT_COEX_CORUNNING)
|
||||
if (iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
|
||||
|
||||
if (IWL_MVM_BT_COEX_MPLUT) {
|
||||
@@ -1234,7 +1234,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
|
||||
if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
|
||||
return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd);
|
||||
|
||||
if (!IWL_MVM_BT_COEX_CORUNNING)
|
||||
if (!iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
return 0;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -619,7 +619,7 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
|
||||
if (IWL_MVM_BT_COEX_SYNC2SCO)
|
||||
bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
|
||||
|
||||
if (IWL_MVM_BT_COEX_CORUNNING) {
|
||||
if (iwl_mvm_bt_is_plcr_supported(mvm)) {
|
||||
bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
|
||||
BT_VALID_CORUN_LUT_40);
|
||||
bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
|
||||
@@ -1167,16 +1167,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
|
||||
return lut_type != BT_COEX_LOOSE_LUT;
|
||||
}
|
||||
|
||||
bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant)
|
||||
{
|
||||
u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
|
||||
return ag < BT_HIGH_TRAFFIC;
|
||||
}
|
||||
|
||||
bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm)
|
||||
{
|
||||
u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
|
||||
return ag == BT_OFF;
|
||||
return ag < BT_HIGH_TRAFFIC;
|
||||
}
|
||||
|
||||
bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
|
||||
@@ -1213,7 +1207,7 @@ int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
|
||||
.dataflags = { IWL_HCMD_DFL_NOCOPY, },
|
||||
};
|
||||
|
||||
if (!IWL_MVM_BT_COEX_CORUNNING)
|
||||
if (!iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
return 0;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@@ -1876,25 +1876,28 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
|
||||
if (mvm->net_detect) {
|
||||
iwl_mvm_query_netdetect_reasons(mvm, vif);
|
||||
/* has unlocked the mutex, so skip that */
|
||||
goto out;
|
||||
} else {
|
||||
keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
if (keep)
|
||||
mvm->keep_vif = vif;
|
||||
/* has unlocked the mutex, so skip that */
|
||||
goto out_iterate;
|
||||
#endif
|
||||
}
|
||||
/* has unlocked the mutex, so skip that */
|
||||
goto out;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
out:
|
||||
out_iterate:
|
||||
if (!test)
|
||||
ieee80211_iterate_active_interfaces_rtnl(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
|
||||
|
||||
out:
|
||||
/* return 1 to reconfigure the device */
|
||||
set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
|
||||
|
||||
@@ -545,6 +545,57 @@ static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
|
||||
return ret ? count : -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm *mvm = mvmvif->mvm;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
||||
u16 value;
|
||||
int ret;
|
||||
|
||||
ret = kstrtou16(buf, 0, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
rcu_read_lock();
|
||||
|
||||
chanctx_conf = rcu_dereference(vif->chanctx_conf);
|
||||
/* make sure the channel context is assigned */
|
||||
if (!chanctx_conf) {
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&mvm->mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
phy_ctxt = &mvm->phy_ctxts[*(u16 *)chanctx_conf->drv_priv];
|
||||
rcu_read_unlock();
|
||||
|
||||
mvm->dbgfs_rx_phyinfo = value;
|
||||
|
||||
ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chanctx_conf->min_def,
|
||||
chanctx_conf->rx_chains_static,
|
||||
chanctx_conf->rx_chains_dynamic);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_vif *vif = file->private_data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
char buf[8];
|
||||
|
||||
snprintf(buf, sizeof(buf), "0x%04x\n", mvmvif->mvm->dbgfs_rx_phyinfo);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
|
||||
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
|
||||
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
|
||||
@@ -560,6 +611,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10);
|
||||
|
||||
void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
@@ -595,6 +647,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir,
|
||||
S_IRUSR | S_IWUSR);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
|
||||
mvmvif == mvm->bf_allowed_vif)
|
||||
|
||||
@@ -942,7 +942,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
enum iwl_fw_dbg_conf conf;
|
||||
int conf;
|
||||
char buf[8];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
int pos = 0;
|
||||
@@ -966,7 +966,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (WARN_ON(conf_id >= FW_DBG_MAX))
|
||||
if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
@@ -985,7 +985,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_mvm_fw_dbg_collect(mvm);
|
||||
iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, 0);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#define MAC_INDEX_AUX 4
|
||||
#define MAC_INDEX_MIN_DRIVER 0
|
||||
#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
|
||||
#define NUM_MAC_INDEX (MAC_INDEX_AUX + 1)
|
||||
|
||||
enum iwl_ac {
|
||||
AC_BK,
|
||||
|
||||
@@ -70,54 +70,9 @@
|
||||
|
||||
/* Scan Commands, Responses, Notifications */
|
||||
|
||||
/* Masks for iwl_scan_channel.type flags */
|
||||
#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
|
||||
#define SCAN_CHANNEL_NARROW_BAND BIT(22)
|
||||
|
||||
/* Max number of IEs for direct SSID scans in a command */
|
||||
#define PROBE_OPTION_MAX 20
|
||||
|
||||
/**
|
||||
* struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
|
||||
* @channel: band is selected by iwl_scan_cmd "flags" field
|
||||
* @tx_gain: gain for analog radio
|
||||
* @dsp_atten: gain for DSP
|
||||
* @active_dwell: dwell time for active scan in TU, typically 5-50
|
||||
* @passive_dwell: dwell time for passive scan in TU, typically 20-500
|
||||
* @type: type is broken down to these bits:
|
||||
* bit 0: 0 = passive, 1 = active
|
||||
* bits 1-20: SSID direct bit map. If any of these bits is set then
|
||||
* the corresponding SSID IE is transmitted in probe request
|
||||
* (bit i adds IE in position i to the probe request)
|
||||
* bit 22: channel width, 0 = regular, 1 = TGj narrow channel
|
||||
*
|
||||
* @iteration_count:
|
||||
* @iteration_interval:
|
||||
* This struct is used once for each channel in the scan list.
|
||||
* Each channel can independently select:
|
||||
* 1) SSID for directed active scans
|
||||
* 2) Txpower setting (for rate specified within Tx command)
|
||||
* 3) How long to stay on-channel (behavior may be modified by quiet_time,
|
||||
* quiet_plcp_th, good_CRC_th)
|
||||
*
|
||||
* To avoid uCode errors, make sure the following are true (see comments
|
||||
* under struct iwl_scan_cmd about max_out_time and quiet_time):
|
||||
* 1) If using passive_dwell (i.e. passive_dwell != 0):
|
||||
* active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
|
||||
* 2) quiet_time <= active_dwell
|
||||
* 3) If restricting off-channel time (i.e. max_out_time !=0):
|
||||
* passive_dwell < max_out_time
|
||||
* active_dwell < max_out_time
|
||||
*/
|
||||
struct iwl_scan_channel {
|
||||
__le32 type;
|
||||
__le16 channel;
|
||||
__le16 iteration_count;
|
||||
__le32 iteration_interval;
|
||||
__le16 active_dwell;
|
||||
__le16 passive_dwell;
|
||||
} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_ssid_ie - directed scan network information element
|
||||
*
|
||||
@@ -132,152 +87,6 @@ struct iwl_ssid_ie {
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* iwl_scan_flags - masks for scan command flags
|
||||
*@SCAN_FLAGS_PERIODIC_SCAN:
|
||||
*@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
|
||||
*@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
|
||||
*@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
|
||||
*@SCAN_FLAGS_FRAGMENTED_SCAN:
|
||||
*@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active
|
||||
* in the past hour, even if they are marked as passive.
|
||||
*/
|
||||
enum iwl_scan_flags {
|
||||
SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
|
||||
SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
|
||||
SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
|
||||
SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
|
||||
SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
|
||||
SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_scan_type - Scan types for scan command
|
||||
* @SCAN_TYPE_FORCED:
|
||||
* @SCAN_TYPE_BACKGROUND:
|
||||
* @SCAN_TYPE_OS:
|
||||
* @SCAN_TYPE_ROAMING:
|
||||
* @SCAN_TYPE_ACTION:
|
||||
* @SCAN_TYPE_DISCOVERY:
|
||||
* @SCAN_TYPE_DISCOVERY_FORCED:
|
||||
*/
|
||||
enum iwl_scan_type {
|
||||
SCAN_TYPE_FORCED = 0,
|
||||
SCAN_TYPE_BACKGROUND = 1,
|
||||
SCAN_TYPE_OS = 2,
|
||||
SCAN_TYPE_ROAMING = 3,
|
||||
SCAN_TYPE_ACTION = 4,
|
||||
SCAN_TYPE_DISCOVERY = 5,
|
||||
SCAN_TYPE_DISCOVERY_FORCED = 6,
|
||||
}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_cmd - scan request command
|
||||
* ( SCAN_REQUEST_CMD = 0x80 )
|
||||
* @len: command length in bytes
|
||||
* @scan_flags: scan flags from SCAN_FLAGS_*
|
||||
* @channel_count: num of channels in channel list
|
||||
* (1 - ucode_capa.n_scan_channels)
|
||||
* @quiet_time: in msecs, dwell this time for active scan on quiet channels
|
||||
* @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
|
||||
* this number of packets were received (typically 1)
|
||||
* @passive2active: is auto switching from passive to active during scan allowed
|
||||
* @rxchain_sel_flags: RXON_RX_CHAIN_*
|
||||
* @max_out_time: in TUs, max out of serving channel time
|
||||
* @suspend_time: how long to pause scan when returning to service channel:
|
||||
* bits 0-19: beacon interal in TUs (suspend before executing)
|
||||
* bits 20-23: reserved
|
||||
* bits 24-31: number of beacons (suspend between channels)
|
||||
* @rxon_flags: RXON_FLG_*
|
||||
* @filter_flags: RXON_FILTER_*
|
||||
* @tx_cmd: for active scans (zero for passive), w/o payload,
|
||||
* no RS so specify TX rate
|
||||
* @direct_scan: direct scan SSIDs
|
||||
* @type: one of SCAN_TYPE_*
|
||||
* @repeats: how many time to repeat the scan
|
||||
*/
|
||||
struct iwl_scan_cmd {
|
||||
__le16 len;
|
||||
u8 scan_flags;
|
||||
u8 channel_count;
|
||||
__le16 quiet_time;
|
||||
__le16 quiet_plcp_th;
|
||||
__le16 passive2active;
|
||||
__le16 rxchain_sel_flags;
|
||||
__le32 max_out_time;
|
||||
__le32 suspend_time;
|
||||
/* RX_ON_FLAGS_API_S_VER_1 */
|
||||
__le32 rxon_flags;
|
||||
__le32 filter_flags;
|
||||
struct iwl_tx_cmd tx_cmd;
|
||||
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
|
||||
__le32 type;
|
||||
__le32 repeats;
|
||||
|
||||
/*
|
||||
* Probe request frame, followed by channel list.
|
||||
*
|
||||
* Size of probe request frame is specified by byte count in tx_cmd.
|
||||
* Channel list follows immediately after probe request frame.
|
||||
* Number of channels in list is specified by channel_count.
|
||||
* Each channel in list is of type:
|
||||
*
|
||||
* struct iwl_scan_channel channels[0];
|
||||
*
|
||||
* NOTE: Only one band of channels can be scanned per pass. You
|
||||
* must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
|
||||
* for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
|
||||
* before requesting another scan.
|
||||
*/
|
||||
u8 data[0];
|
||||
} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
|
||||
|
||||
/* Response to scan request contains only status with one of these values */
|
||||
#define SCAN_RESPONSE_OK 0x1
|
||||
#define SCAN_RESPONSE_ERROR 0x2
|
||||
|
||||
/*
|
||||
* SCAN_ABORT_CMD = 0x81
|
||||
* When scan abort is requested, the command has no fields except the common
|
||||
* header. The response contains only a status with one of these values.
|
||||
*/
|
||||
#define SCAN_ABORT_POSSIBLE 0x1
|
||||
#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
|
||||
|
||||
/* TODO: complete documentation */
|
||||
#define SCAN_OWNER_STATUS 0x1
|
||||
#define MEASURE_OWNER_STATUS 0x2
|
||||
|
||||
/**
|
||||
* struct iwl_scan_start_notif - notifies start of scan in the device
|
||||
* ( SCAN_START_NOTIFICATION = 0x82 )
|
||||
* @tsf_low: TSF timer (lower half) in usecs
|
||||
* @tsf_high: TSF timer (higher half) in usecs
|
||||
* @beacon_timer: structured as follows:
|
||||
* bits 0:19 - beacon interval in usecs
|
||||
* bits 20:23 - reserved (0)
|
||||
* bits 24:31 - number of beacons
|
||||
* @channel: which channel is scanned
|
||||
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
|
||||
* @status: one of *_OWNER_STATUS
|
||||
*/
|
||||
struct iwl_scan_start_notif {
|
||||
__le32 tsf_low;
|
||||
__le32 tsf_high;
|
||||
__le32 beacon_timer;
|
||||
u8 channel;
|
||||
u8 band;
|
||||
u8 reserved[2];
|
||||
__le32 status;
|
||||
} __packed; /* SCAN_START_NTF_API_S_VER_1 */
|
||||
|
||||
/* scan results probe_status first bit indicates success */
|
||||
#define SCAN_PROBE_STATUS_OK 0
|
||||
#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
|
||||
/* error statuses combined with TX_FAILED */
|
||||
#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
|
||||
#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
|
||||
|
||||
/* How many statistics are gathered for each channel */
|
||||
#define SCAN_RESULTS_STATISTICS 1
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
|
||||
#ifndef __fw_api_stats_h__
|
||||
#define __fw_api_stats_h__
|
||||
#include "fw-api-mac.h"
|
||||
|
||||
struct mvm_statistics_dbg {
|
||||
__le32 burst_check;
|
||||
@@ -218,7 +219,7 @@ struct mvm_statistics_bt_activity {
|
||||
__le32 lo_priority_rx_denied_cnt;
|
||||
} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
|
||||
|
||||
struct mvm_statistics_general {
|
||||
struct mvm_statistics_general_v5 {
|
||||
__le32 radio_temperature;
|
||||
__le32 radio_voltage;
|
||||
struct mvm_statistics_dbg dbg;
|
||||
@@ -244,6 +245,39 @@ struct mvm_statistics_general {
|
||||
struct mvm_statistics_bt_activity bt_activity;
|
||||
} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
|
||||
|
||||
struct mvm_statistics_general_v8 {
|
||||
__le32 radio_temperature;
|
||||
__le32 radio_voltage;
|
||||
struct mvm_statistics_dbg dbg;
|
||||
__le32 sleep_time;
|
||||
__le32 slots_out;
|
||||
__le32 slots_idle;
|
||||
__le32 ttl_timestamp;
|
||||
struct mvm_statistics_div slow_div;
|
||||
__le32 rx_enable_counter;
|
||||
/*
|
||||
* num_of_sos_states:
|
||||
* count the number of times we have to re-tune
|
||||
* in order to get out of bad PHY status
|
||||
*/
|
||||
__le32 num_of_sos_states;
|
||||
__le32 beacon_filtered;
|
||||
__le32 missed_beacons;
|
||||
__s8 beacon_filter_average_energy;
|
||||
__s8 beacon_filter_reason;
|
||||
__s8 beacon_filter_current_energy;
|
||||
__s8 beacon_filter_reserved;
|
||||
__le32 beacon_filter_delta_time;
|
||||
struct mvm_statistics_bt_activity bt_activity;
|
||||
__le64 rx_time;
|
||||
__le64 on_time_rf;
|
||||
__le64 on_time_scan;
|
||||
__le64 tx_time;
|
||||
__le32 beacon_counter[NUM_MAC_INDEX];
|
||||
u8 beacon_average_energy[NUM_MAC_INDEX];
|
||||
u8 reserved[4 - (NUM_MAC_INDEX % 4)];
|
||||
} __packed; /* STATISTICS_GENERAL_API_S_VER_8 */
|
||||
|
||||
struct mvm_statistics_rx {
|
||||
struct mvm_statistics_rx_phy ofdm;
|
||||
struct mvm_statistics_rx_phy cck;
|
||||
@@ -256,22 +290,28 @@ struct mvm_statistics_rx {
|
||||
*
|
||||
* By default, uCode issues this notification after receiving a beacon
|
||||
* while associated. To disable this behavior, set DISABLE_NOTIF flag in the
|
||||
* REPLY_STATISTICS_CMD 0x9c, above.
|
||||
*
|
||||
* Statistics counters continue to increment beacon after beacon, but are
|
||||
* cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
|
||||
* 0x9c with CLEAR_STATS bit set (see above).
|
||||
*
|
||||
* uCode also issues this notification during scans. uCode clears statistics
|
||||
* appropriately so that each notification contains statistics for only the
|
||||
* one channel that has just been scanned.
|
||||
* STATISTICS_CMD (0x9c), below.
|
||||
*/
|
||||
|
||||
struct iwl_notif_statistics {
|
||||
struct iwl_notif_statistics_v8 {
|
||||
__le32 flag;
|
||||
struct mvm_statistics_rx rx;
|
||||
struct mvm_statistics_tx tx;
|
||||
struct mvm_statistics_general general;
|
||||
struct mvm_statistics_general_v5 general;
|
||||
} __packed; /* STATISTICS_NTFY_API_S_VER_8 */
|
||||
|
||||
struct iwl_notif_statistics_v10 {
|
||||
__le32 flag;
|
||||
struct mvm_statistics_rx rx;
|
||||
struct mvm_statistics_tx tx;
|
||||
struct mvm_statistics_general_v8 general;
|
||||
} __packed; /* STATISTICS_NTFY_API_S_VER_10 */
|
||||
|
||||
#define IWL_STATISTICS_FLG_CLEAR 0x1
|
||||
#define IWL_STATISTICS_FLG_DISABLE_NOTIF 0x2
|
||||
|
||||
struct iwl_statistics_cmd {
|
||||
__le32 flags;
|
||||
} __packed; /* STATISTICS_CMD_API_S_VER_1 */
|
||||
|
||||
#endif /* __fw_api_stats_h__ */
|
||||
|
||||
@@ -192,6 +192,7 @@ enum {
|
||||
BEACON_NOTIFICATION = 0x90,
|
||||
BEACON_TEMPLATE_CMD = 0x91,
|
||||
TX_ANT_CONFIGURATION_CMD = 0x98,
|
||||
STATISTICS_CMD = 0x9c,
|
||||
STATISTICS_NOTIFICATION = 0x9d,
|
||||
EOSP_NOTIFICATION = 0x9e,
|
||||
REDUCE_TX_POWER_CMD = 0x9f,
|
||||
@@ -431,7 +432,7 @@ enum {
|
||||
|
||||
#define IWL_ALIVE_FLG_RFKILL BIT(0)
|
||||
|
||||
struct mvm_alive_resp {
|
||||
struct mvm_alive_resp_ver1 {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
u8 ucode_minor;
|
||||
@@ -482,6 +483,30 @@ struct mvm_alive_resp_ver2 {
|
||||
__le32 dbg_print_buff_addr;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_2 */
|
||||
|
||||
struct mvm_alive_resp {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
__le32 ucode_minor;
|
||||
__le32 ucode_major;
|
||||
u8 ver_subtype;
|
||||
u8 ver_type;
|
||||
u8 mac;
|
||||
u8 opt;
|
||||
__le32 timestamp;
|
||||
__le32 error_event_table_ptr; /* SRAM address for error log */
|
||||
__le32 log_event_table_ptr; /* SRAM address for LMAC event log */
|
||||
__le32 cpu_register_ptr;
|
||||
__le32 dbgm_config_ptr;
|
||||
__le32 alive_counter_ptr;
|
||||
__le32 scd_base_ptr; /* SRAM address for SCD */
|
||||
__le32 st_fwrd_addr; /* pointer to Store and forward */
|
||||
__le32 st_fwrd_size;
|
||||
__le32 umac_minor; /* UMAC version: minor */
|
||||
__le32 umac_major; /* UMAC version: major */
|
||||
__le32 error_info_addr; /* SRAM address for UMAC error log */
|
||||
__le32 dbg_print_buff_addr;
|
||||
} __packed; /* ALIVE_RES_API_S_VER_3 */
|
||||
|
||||
/* Error response/notification */
|
||||
enum {
|
||||
FW_ERR_UNKNOWN_CMD = 0x0,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user