mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-15 16:26:43 +07:00
wireless-drivers-next patches for 4.18
Hopefully the last pull request to 4.18 before the merge window. Nothing major here, we have smaller new features and of course a lots of fixes. Major changes: ath10k * add memory dump support for QCA9888 and QCA99X0 * add support to configure channel dwell time * support new DFS host confirmation feature in the firmware ath * update various regulatory mappings wcn36xx * various fixes to improve reliability * add Factory Test Mode support brmfmac * add debugfs file for reading firmware capabilities mwifiex * support sysfs initiated device coredump -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJbD/3rAAoJEG4XJFUm622b1ZwH/1xe1IqcwJXzfoDsYPlXVnSh TiLExjKkD0ty5M0//844FxpxE1sSYJKOJ11uz/COzyG2qi4+5lgpUdjnDoINuKfH ycqrXGssW7ogPWkVvnxKtlEYvkHNRYLQtxvd26umT77C69jVJLD0x9uihhh2En/C EKs+OK1Pp0SRvTfB4AblWzoAnpEe1wHJFFh4i3F5H0lMGxLQz/YjFl5aeAjjR406 0vSKLGy2wKIydp8Pe4cAqBEeUWDJurn8ufkk7bmAET5zaXTH1qgZzLH3OWtx/ksz mcPQq9/ctv35G2917t3Sn69SIUCDGfYkP5DiZV+ti0Hz2gIV0zOg7mGYCU8uHaU= =11X5 -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2018-05-31' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers-next patches for 4.18 Hopefully the last pull request to 4.18 before the merge window. Nothing major here, we have smaller new features and of course a lots of fixes. Major changes: ath10k * add memory dump support for QCA9888 and QCA99X0 * add support to configure channel dwell time * support new DFS host confirmation feature in the firmware ath * update various regulatory mappings wcn36xx * various fixes to improve reliability * add Factory Test Mode support brmfmac * add debugfs file for reading firmware capabilities mwifiex * support sysfs initiated device coredump ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
f624434a0e
@ -180,14 +180,11 @@ static void ath10k_ahb_clock_disable(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
|
||||
|
||||
if (!IS_ERR_OR_NULL(ar_ahb->cmd_clk))
|
||||
clk_disable_unprepare(ar_ahb->cmd_clk);
|
||||
clk_disable_unprepare(ar_ahb->cmd_clk);
|
||||
|
||||
if (!IS_ERR_OR_NULL(ar_ahb->ref_clk))
|
||||
clk_disable_unprepare(ar_ahb->ref_clk);
|
||||
clk_disable_unprepare(ar_ahb->ref_clk);
|
||||
|
||||
if (!IS_ERR_OR_NULL(ar_ahb->rtc_clk))
|
||||
clk_disable_unprepare(ar_ahb->rtc_clk);
|
||||
clk_disable_unprepare(ar_ahb->rtc_clk);
|
||||
}
|
||||
|
||||
static int ath10k_ahb_rst_ctrl_init(struct ath10k *ar)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define WO(_f) ((_f##_OFFSET) >> 2)
|
||||
|
||||
#define ATH10K_SCAN_ID 0
|
||||
#define ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* msec */
|
||||
#define WMI_READY_TIMEOUT (5 * HZ)
|
||||
#define ATH10K_FLUSH_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
@ -175,6 +176,7 @@ struct ath10k_wmi {
|
||||
struct completion service_ready;
|
||||
struct completion unified_ready;
|
||||
struct completion barrier;
|
||||
struct completion radar_confirm;
|
||||
wait_queue_head_t tx_credits_wq;
|
||||
DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
|
||||
struct wmi_cmd_map *cmd;
|
||||
@ -377,6 +379,21 @@ struct ath10k_dfs_stats {
|
||||
u32 radar_detected;
|
||||
};
|
||||
|
||||
enum ath10k_radar_confirmation_state {
|
||||
ATH10K_RADAR_CONFIRMATION_IDLE = 0,
|
||||
ATH10K_RADAR_CONFIRMATION_INPROGRESS,
|
||||
ATH10K_RADAR_CONFIRMATION_STOPPED,
|
||||
};
|
||||
|
||||
struct ath10k_radar_found_info {
|
||||
u32 pri_min;
|
||||
u32 pri_max;
|
||||
u32 width_min;
|
||||
u32 width_max;
|
||||
u32 sidx_min;
|
||||
u32 sidx_max;
|
||||
};
|
||||
|
||||
#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */
|
||||
|
||||
struct ath10k_peer {
|
||||
@ -1109,6 +1126,11 @@ struct ath10k {
|
||||
|
||||
u32 sta_tid_stats_mask;
|
||||
|
||||
/* protected by data_lock */
|
||||
enum ath10k_radar_confirmation_state radar_conf_state;
|
||||
struct ath10k_radar_found_info last_radar_info;
|
||||
struct work_struct radar_confirmation_work;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
|
@ -701,6 +701,89 @@ static const struct ath10k_mem_region qca988x_hw20_mem_regions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_region qca99x0_hw20_mem_regions[] = {
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_DRAM,
|
||||
.start = 0x400000,
|
||||
.len = 0x60000,
|
||||
.name = "DRAM",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_REG,
|
||||
.start = 0x98000,
|
||||
.len = 0x50000,
|
||||
.name = "IRAM",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOSRAM,
|
||||
.start = 0xC0000,
|
||||
.len = 0x40000,
|
||||
.name = "SRAM",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOREG,
|
||||
.start = 0x30000,
|
||||
.len = 0x7000,
|
||||
.name = "APB REG 1",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOREG,
|
||||
.start = 0x3f000,
|
||||
.len = 0x3000,
|
||||
.name = "APB REG 2",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOREG,
|
||||
.start = 0x43000,
|
||||
.len = 0x3000,
|
||||
.name = "WIFI REG",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOREG,
|
||||
.start = 0x4A000,
|
||||
.len = 0x5000,
|
||||
.name = "CE REG",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IOREG,
|
||||
.start = 0x80000,
|
||||
.len = 0x6000,
|
||||
.name = "SOC REG",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_region qca9984_hw10_mem_regions[] = {
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_DRAM,
|
||||
@ -848,6 +931,21 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
.size = ARRAY_SIZE(qca9984_hw10_mem_regions),
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw_id = QCA9888_HW_2_0_DEV_VERSION,
|
||||
.region_table = {
|
||||
.regions = qca9984_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca9984_hw10_mem_regions),
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw_id = QCA99X0_HW_2_0_DEV_VERSION,
|
||||
.region_table = {
|
||||
.regions = qca99x0_hw20_mem_regions,
|
||||
.size = ARRAY_SIZE(qca99x0_hw20_mem_regions),
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
|
||||
|
@ -987,13 +987,13 @@ static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
int res;
|
||||
char buf[64];
|
||||
char buf[64] = {0};
|
||||
unsigned int amsdu, ampdu;
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
res = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
res = sscanf(buf, "%u %u", &amsdu, &du);
|
||||
|
||||
@ -1043,14 +1043,14 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file,
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
int ret;
|
||||
char buf[96];
|
||||
char buf[96] = {0};
|
||||
unsigned int log_level;
|
||||
u64 mask;
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%llx %u", &mask, &log_level);
|
||||
|
||||
@ -1519,7 +1519,13 @@ static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
"********************************\n");
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
"No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3\n");
|
||||
"No. Preamble Rate_code ");
|
||||
|
||||
for (i = 0; i < WMI_TPC_TX_N_CHAIN; i++)
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
"tpc_value%d ", i);
|
||||
|
||||
*len += scnprintf(buf + *len, buf_len - *len, "\n");
|
||||
|
||||
for (i = 0; i < tpc_stats->rate_max; i++) {
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
|
@ -254,12 +254,12 @@ static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
|
||||
struct ath10k *ar = arsta->arvif->ar;
|
||||
u32 tid, buf_size;
|
||||
int ret;
|
||||
char buf[64];
|
||||
char buf[64] = {0};
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u", &tid, &buf_size);
|
||||
if (ret != 2)
|
||||
@ -305,12 +305,12 @@ static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
|
||||
struct ath10k *ar = arsta->arvif->ar;
|
||||
u32 tid, status;
|
||||
int ret;
|
||||
char buf[64];
|
||||
char buf[64] = {0};
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u", &tid, &status);
|
||||
if (ret != 2)
|
||||
@ -355,12 +355,12 @@ static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
|
||||
struct ath10k *ar = arsta->arvif->ar;
|
||||
u32 tid, initiator, reason;
|
||||
int ret;
|
||||
char buf[64];
|
||||
char buf[64] = {0};
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
|
||||
if (ret != 3)
|
||||
|
@ -85,11 +85,11 @@ enum qca9377_chip_id_rev {
|
||||
QCA9377_HW_1_1_CHIP_ID_REV = 0x1,
|
||||
};
|
||||
|
||||
#define QCA6174_HW_2_1_FW_DIR "ath10k/QCA6174/hw2.1"
|
||||
#define QCA6174_HW_2_1_FW_DIR ATH10K_FW_DIR "/QCA6174/hw2.1"
|
||||
#define QCA6174_HW_2_1_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA6174_HW_2_1_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
#define QCA6174_HW_3_0_FW_DIR "ath10k/QCA6174/hw3.0"
|
||||
#define QCA6174_HW_3_0_FW_DIR ATH10K_FW_DIR "/QCA6174/hw3.0"
|
||||
#define QCA6174_HW_3_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA6174_HW_3_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
|
@ -3217,6 +3217,15 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
|
||||
ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
|
||||
}
|
||||
|
||||
static void ath10k_stop_radar_confirmation(struct ath10k *ar)
|
||||
{
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_STOPPED;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
cancel_work_sync(&ar->radar_confirmation_work);
|
||||
}
|
||||
|
||||
/***************/
|
||||
/* TX handlers */
|
||||
/***************/
|
||||
@ -4290,7 +4299,7 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
|
||||
|
||||
while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
|
||||
ret = ath10k_mac_tx_push_txq(hw, f_txq);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
if (ret != -ENOENT)
|
||||
@ -4333,6 +4342,7 @@ void ath10k_halt(struct ath10k *ar)
|
||||
|
||||
ath10k_scan_finish(ar);
|
||||
ath10k_peer_cleanup_all(ar);
|
||||
ath10k_stop_radar_confirmation(ar);
|
||||
ath10k_core_stop(ar);
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
@ -4758,6 +4768,8 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
||||
ath10k_spectral_start(ar);
|
||||
ath10k_thermal_set_throttling(ar);
|
||||
|
||||
ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return 0;
|
||||
|
||||
@ -5675,6 +5687,7 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
|
||||
struct wmi_start_scan_arg arg;
|
||||
int ret = 0;
|
||||
int i;
|
||||
u32 scan_timeout;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@ -5736,6 +5749,22 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
|
||||
arg.channels[i] = req->channels[i]->center_freq;
|
||||
}
|
||||
|
||||
/* if duration is set, default dwell times will be overwritten */
|
||||
if (req->duration) {
|
||||
arg.dwell_time_active = req->duration;
|
||||
arg.dwell_time_passive = req->duration;
|
||||
arg.burst_duration_ms = req->duration;
|
||||
|
||||
scan_timeout = min_t(u32, arg.max_rest_time *
|
||||
(arg.n_channels - 1) + (req->duration +
|
||||
ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
|
||||
arg.n_channels, arg.max_scan_time + 200);
|
||||
|
||||
} else {
|
||||
/* Add a 200ms margin to account for event/command processing */
|
||||
scan_timeout = arg.max_scan_time + 200;
|
||||
}
|
||||
|
||||
ret = ath10k_start_scan(ar, &arg);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
|
||||
@ -5744,10 +5773,8 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
/* Add a 200ms margin to account for event/command processing */
|
||||
ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
|
||||
msecs_to_jiffies(arg.max_scan_time +
|
||||
200));
|
||||
msecs_to_jiffies(scan_timeout));
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
@ -8364,6 +8391,8 @@ int ath10k_mac_register(struct ath10k *ar)
|
||||
}
|
||||
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
|
||||
/*
|
||||
* on LL hardware queues are managed entirely by the FW
|
||||
|
@ -18,39 +18,41 @@
|
||||
#ifndef _RX_DESC_H_
|
||||
#define _RX_DESC_H_
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
||||
enum rx_attention_flags {
|
||||
RX_ATTENTION_FLAGS_FIRST_MPDU = 1 << 0,
|
||||
RX_ATTENTION_FLAGS_LAST_MPDU = 1 << 1,
|
||||
RX_ATTENTION_FLAGS_MCAST_BCAST = 1 << 2,
|
||||
RX_ATTENTION_FLAGS_PEER_IDX_INVALID = 1 << 3,
|
||||
RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT = 1 << 4,
|
||||
RX_ATTENTION_FLAGS_POWER_MGMT = 1 << 5,
|
||||
RX_ATTENTION_FLAGS_NON_QOS = 1 << 6,
|
||||
RX_ATTENTION_FLAGS_NULL_DATA = 1 << 7,
|
||||
RX_ATTENTION_FLAGS_MGMT_TYPE = 1 << 8,
|
||||
RX_ATTENTION_FLAGS_CTRL_TYPE = 1 << 9,
|
||||
RX_ATTENTION_FLAGS_MORE_DATA = 1 << 10,
|
||||
RX_ATTENTION_FLAGS_EOSP = 1 << 11,
|
||||
RX_ATTENTION_FLAGS_U_APSD_TRIGGER = 1 << 12,
|
||||
RX_ATTENTION_FLAGS_FRAGMENT = 1 << 13,
|
||||
RX_ATTENTION_FLAGS_ORDER = 1 << 14,
|
||||
RX_ATTENTION_FLAGS_CLASSIFICATION = 1 << 15,
|
||||
RX_ATTENTION_FLAGS_OVERFLOW_ERR = 1 << 16,
|
||||
RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = 1 << 17,
|
||||
RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = 1 << 18,
|
||||
RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL = 1 << 19,
|
||||
RX_ATTENTION_FLAGS_SA_IDX_INVALID = 1 << 20,
|
||||
RX_ATTENTION_FLAGS_DA_IDX_INVALID = 1 << 21,
|
||||
RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT = 1 << 22,
|
||||
RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT = 1 << 23,
|
||||
RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED = 1 << 24,
|
||||
RX_ATTENTION_FLAGS_DIRECTED = 1 << 25,
|
||||
RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = 1 << 26,
|
||||
RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = 1 << 27,
|
||||
RX_ATTENTION_FLAGS_TKIP_MIC_ERR = 1 << 28,
|
||||
RX_ATTENTION_FLAGS_DECRYPT_ERR = 1 << 29,
|
||||
RX_ATTENTION_FLAGS_FCS_ERR = 1 << 30,
|
||||
RX_ATTENTION_FLAGS_MSDU_DONE = 1 << 31,
|
||||
RX_ATTENTION_FLAGS_FIRST_MPDU = BIT(0),
|
||||
RX_ATTENTION_FLAGS_LAST_MPDU = BIT(1),
|
||||
RX_ATTENTION_FLAGS_MCAST_BCAST = BIT(2),
|
||||
RX_ATTENTION_FLAGS_PEER_IDX_INVALID = BIT(3),
|
||||
RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT = BIT(4),
|
||||
RX_ATTENTION_FLAGS_POWER_MGMT = BIT(5),
|
||||
RX_ATTENTION_FLAGS_NON_QOS = BIT(6),
|
||||
RX_ATTENTION_FLAGS_NULL_DATA = BIT(7),
|
||||
RX_ATTENTION_FLAGS_MGMT_TYPE = BIT(8),
|
||||
RX_ATTENTION_FLAGS_CTRL_TYPE = BIT(9),
|
||||
RX_ATTENTION_FLAGS_MORE_DATA = BIT(10),
|
||||
RX_ATTENTION_FLAGS_EOSP = BIT(11),
|
||||
RX_ATTENTION_FLAGS_U_APSD_TRIGGER = BIT(12),
|
||||
RX_ATTENTION_FLAGS_FRAGMENT = BIT(13),
|
||||
RX_ATTENTION_FLAGS_ORDER = BIT(14),
|
||||
RX_ATTENTION_FLAGS_CLASSIFICATION = BIT(15),
|
||||
RX_ATTENTION_FLAGS_OVERFLOW_ERR = BIT(16),
|
||||
RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = BIT(17),
|
||||
RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = BIT(18),
|
||||
RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL = BIT(19),
|
||||
RX_ATTENTION_FLAGS_SA_IDX_INVALID = BIT(20),
|
||||
RX_ATTENTION_FLAGS_DA_IDX_INVALID = BIT(21),
|
||||
RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT = BIT(22),
|
||||
RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT = BIT(23),
|
||||
RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED = BIT(24),
|
||||
RX_ATTENTION_FLAGS_DIRECTED = BIT(25),
|
||||
RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = BIT(26),
|
||||
RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = BIT(27),
|
||||
RX_ATTENTION_FLAGS_TKIP_MIC_ERR = BIT(28),
|
||||
RX_ATTENTION_FLAGS_DECRYPT_ERR = BIT(29),
|
||||
RX_ATTENTION_FLAGS_FCS_ERR = BIT(30),
|
||||
RX_ATTENTION_FLAGS_MSDU_DONE = BIT(31),
|
||||
};
|
||||
|
||||
struct rx_attention {
|
||||
@ -254,15 +256,15 @@ enum htt_rx_mpdu_encrypt_type {
|
||||
#define RX_MPDU_START_INFO0_SEQ_NUM_LSB 16
|
||||
#define RX_MPDU_START_INFO0_ENCRYPT_TYPE_MASK 0xf0000000
|
||||
#define RX_MPDU_START_INFO0_ENCRYPT_TYPE_LSB 28
|
||||
#define RX_MPDU_START_INFO0_FROM_DS (1 << 11)
|
||||
#define RX_MPDU_START_INFO0_TO_DS (1 << 12)
|
||||
#define RX_MPDU_START_INFO0_ENCRYPTED (1 << 13)
|
||||
#define RX_MPDU_START_INFO0_RETRY (1 << 14)
|
||||
#define RX_MPDU_START_INFO0_TXBF_H_INFO (1 << 15)
|
||||
#define RX_MPDU_START_INFO0_FROM_DS BIT(11)
|
||||
#define RX_MPDU_START_INFO0_TO_DS BIT(12)
|
||||
#define RX_MPDU_START_INFO0_ENCRYPTED BIT(13)
|
||||
#define RX_MPDU_START_INFO0_RETRY BIT(14)
|
||||
#define RX_MPDU_START_INFO0_TXBF_H_INFO BIT(15)
|
||||
|
||||
#define RX_MPDU_START_INFO1_TID_MASK 0xf0000000
|
||||
#define RX_MPDU_START_INFO1_TID_LSB 28
|
||||
#define RX_MPDU_START_INFO1_DIRECTED (1 << 16)
|
||||
#define RX_MPDU_START_INFO1_DIRECTED BIT(16)
|
||||
|
||||
struct rx_mpdu_start {
|
||||
__le32 info0;
|
||||
@ -357,13 +359,13 @@ struct rx_mpdu_start {
|
||||
#define RX_MPDU_END_INFO0_RESERVED_0_LSB 0
|
||||
#define RX_MPDU_END_INFO0_POST_DELIM_CNT_MASK 0x0fff0000
|
||||
#define RX_MPDU_END_INFO0_POST_DELIM_CNT_LSB 16
|
||||
#define RX_MPDU_END_INFO0_OVERFLOW_ERR (1 << 13)
|
||||
#define RX_MPDU_END_INFO0_LAST_MPDU (1 << 14)
|
||||
#define RX_MPDU_END_INFO0_POST_DELIM_ERR (1 << 15)
|
||||
#define RX_MPDU_END_INFO0_MPDU_LENGTH_ERR (1 << 28)
|
||||
#define RX_MPDU_END_INFO0_TKIP_MIC_ERR (1 << 29)
|
||||
#define RX_MPDU_END_INFO0_DECRYPT_ERR (1 << 30)
|
||||
#define RX_MPDU_END_INFO0_FCS_ERR (1 << 31)
|
||||
#define RX_MPDU_END_INFO0_OVERFLOW_ERR BIT(13)
|
||||
#define RX_MPDU_END_INFO0_LAST_MPDU BIT(14)
|
||||
#define RX_MPDU_END_INFO0_POST_DELIM_ERR BIT(15)
|
||||
#define RX_MPDU_END_INFO0_MPDU_LENGTH_ERR BIT(28)
|
||||
#define RX_MPDU_END_INFO0_TKIP_MIC_ERR BIT(29)
|
||||
#define RX_MPDU_END_INFO0_DECRYPT_ERR BIT(30)
|
||||
#define RX_MPDU_END_INFO0_FCS_ERR BIT(31)
|
||||
|
||||
struct rx_mpdu_end {
|
||||
__le32 info0;
|
||||
@ -422,12 +424,12 @@ struct rx_mpdu_end {
|
||||
#define RX_MSDU_START_INFO1_DECAP_FORMAT_LSB 8
|
||||
#define RX_MSDU_START_INFO1_SA_IDX_MASK 0x07ff0000
|
||||
#define RX_MSDU_START_INFO1_SA_IDX_LSB 16
|
||||
#define RX_MSDU_START_INFO1_IPV4_PROTO (1 << 10)
|
||||
#define RX_MSDU_START_INFO1_IPV6_PROTO (1 << 11)
|
||||
#define RX_MSDU_START_INFO1_TCP_PROTO (1 << 12)
|
||||
#define RX_MSDU_START_INFO1_UDP_PROTO (1 << 13)
|
||||
#define RX_MSDU_START_INFO1_IP_FRAG (1 << 14)
|
||||
#define RX_MSDU_START_INFO1_TCP_ONLY_ACK (1 << 15)
|
||||
#define RX_MSDU_START_INFO1_IPV4_PROTO BIT(10)
|
||||
#define RX_MSDU_START_INFO1_IPV6_PROTO BIT(11)
|
||||
#define RX_MSDU_START_INFO1_TCP_PROTO BIT(12)
|
||||
#define RX_MSDU_START_INFO1_UDP_PROTO BIT(13)
|
||||
#define RX_MSDU_START_INFO1_IP_FRAG BIT(14)
|
||||
#define RX_MSDU_START_INFO1_TCP_ONLY_ACK BIT(15)
|
||||
|
||||
#define RX_MSDU_START_INFO2_DA_IDX_MASK 0x000007ff
|
||||
#define RX_MSDU_START_INFO2_DA_IDX_LSB 0
|
||||
@ -568,10 +570,10 @@ struct rx_msdu_start {
|
||||
|
||||
#define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_MASK 0x00003fff
|
||||
#define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_LSB 0
|
||||
#define RX_MSDU_END_INFO0_FIRST_MSDU (1 << 14)
|
||||
#define RX_MSDU_END_INFO0_LAST_MSDU (1 << 15)
|
||||
#define RX_MSDU_END_INFO0_PRE_DELIM_ERR (1 << 30)
|
||||
#define RX_MSDU_END_INFO0_RESERVED_3B (1 << 31)
|
||||
#define RX_MSDU_END_INFO0_FIRST_MSDU BIT(14)
|
||||
#define RX_MSDU_END_INFO0_LAST_MSDU BIT(15)
|
||||
#define RX_MSDU_END_INFO0_PRE_DELIM_ERR BIT(30)
|
||||
#define RX_MSDU_END_INFO0_RESERVED_3B BIT(31)
|
||||
|
||||
struct rx_msdu_end_common {
|
||||
__le16 ip_hdr_cksum;
|
||||
@ -691,7 +693,7 @@ struct rx_msdu_end {
|
||||
#define HTT_RX_PPDU_START_PREAMBLE_VHT 0x0C
|
||||
#define HTT_RX_PPDU_START_PREAMBLE_VHT_WITH_TXBF 0x0D
|
||||
|
||||
#define RX_PPDU_START_INFO0_IS_GREENFIELD (1 << 0)
|
||||
#define RX_PPDU_START_INFO0_IS_GREENFIELD BIT(0)
|
||||
|
||||
#define RX_PPDU_START_INFO1_L_SIG_RATE_MASK 0x0000000f
|
||||
#define RX_PPDU_START_INFO1_L_SIG_RATE_LSB 0
|
||||
@ -701,15 +703,15 @@ struct rx_msdu_end {
|
||||
#define RX_PPDU_START_INFO1_L_SIG_TAIL_LSB 18
|
||||
#define RX_PPDU_START_INFO1_PREAMBLE_TYPE_MASK 0xff000000
|
||||
#define RX_PPDU_START_INFO1_PREAMBLE_TYPE_LSB 24
|
||||
#define RX_PPDU_START_INFO1_L_SIG_RATE_SELECT (1 << 4)
|
||||
#define RX_PPDU_START_INFO1_L_SIG_PARITY (1 << 17)
|
||||
#define RX_PPDU_START_INFO1_L_SIG_RATE_SELECT BIT(4)
|
||||
#define RX_PPDU_START_INFO1_L_SIG_PARITY BIT(17)
|
||||
|
||||
#define RX_PPDU_START_INFO2_HT_SIG_VHT_SIG_A_1_MASK 0x00ffffff
|
||||
#define RX_PPDU_START_INFO2_HT_SIG_VHT_SIG_A_1_LSB 0
|
||||
|
||||
#define RX_PPDU_START_INFO3_HT_SIG_VHT_SIG_A_2_MASK 0x00ffffff
|
||||
#define RX_PPDU_START_INFO3_HT_SIG_VHT_SIG_A_2_LSB 0
|
||||
#define RX_PPDU_START_INFO3_TXBF_H_INFO (1 << 24)
|
||||
#define RX_PPDU_START_INFO3_TXBF_H_INFO BIT(24)
|
||||
|
||||
#define RX_PPDU_START_INFO4_VHT_SIG_B_MASK 0x1fffffff
|
||||
#define RX_PPDU_START_INFO4_VHT_SIG_B_LSB 0
|
||||
@ -898,14 +900,14 @@ struct rx_ppdu_start {
|
||||
* Reserved: HW should fill with 0, FW should ignore.
|
||||
*/
|
||||
|
||||
#define RX_PPDU_END_FLAGS_PHY_ERR (1 << 0)
|
||||
#define RX_PPDU_END_FLAGS_RX_LOCATION (1 << 1)
|
||||
#define RX_PPDU_END_FLAGS_TXBF_H_INFO (1 << 2)
|
||||
#define RX_PPDU_END_FLAGS_PHY_ERR BIT(0)
|
||||
#define RX_PPDU_END_FLAGS_RX_LOCATION BIT(1)
|
||||
#define RX_PPDU_END_FLAGS_TXBF_H_INFO BIT(2)
|
||||
|
||||
#define RX_PPDU_END_INFO0_RX_ANTENNA_MASK 0x00ffffff
|
||||
#define RX_PPDU_END_INFO0_RX_ANTENNA_LSB 0
|
||||
#define RX_PPDU_END_INFO0_FLAGS_TX_HT_VHT_ACK (1 << 24)
|
||||
#define RX_PPDU_END_INFO0_BB_CAPTURED_CHANNEL (1 << 25)
|
||||
#define RX_PPDU_END_INFO0_FLAGS_TX_HT_VHT_ACK BIT(24)
|
||||
#define RX_PPDU_END_INFO0_BB_CAPTURED_CHANNEL BIT(25)
|
||||
|
||||
#define RX_PPDU_END_INFO1_PEER_IDX_MASK 0x1ffc
|
||||
#define RX_PPDU_END_INFO1_PEER_IDX_LSB 2
|
||||
@ -1265,9 +1267,9 @@ struct rx_ppdu_end {
|
||||
* to 0.
|
||||
*/
|
||||
|
||||
#define FW_RX_DESC_INFO0_DISCARD (1 << 0)
|
||||
#define FW_RX_DESC_INFO0_FORWARD (1 << 1)
|
||||
#define FW_RX_DESC_INFO0_INSPECT (1 << 5)
|
||||
#define FW_RX_DESC_INFO0_DISCARD BIT(0)
|
||||
#define FW_RX_DESC_INFO0_FORWARD BIT(1)
|
||||
#define FW_RX_DESC_INFO0_INSPECT BIT(5)
|
||||
#define FW_RX_DESC_INFO0_EXT_MASK 0xC0
|
||||
#define FW_RX_DESC_INFO0_EXT_LSB 6
|
||||
|
||||
|
@ -2011,7 +2011,7 @@ static int ath10k_sdio_probe(struct sdio_func *func,
|
||||
ret = -ENODEV;
|
||||
ath10k_err(ar, "unsupported device id %u (0x%x)\n",
|
||||
dev_id_base, id->device);
|
||||
goto err_core_destroy;
|
||||
goto err_free_wq;
|
||||
}
|
||||
|
||||
ar->id.vendor = id->vendor;
|
||||
|
@ -1385,7 +1385,6 @@ static struct platform_driver ath10k_snoc_driver = {
|
||||
.remove = ath10k_snoc_remove,
|
||||
.driver = {
|
||||
.name = "ath10k_snoc",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ath10k_snoc_dt_match,
|
||||
},
|
||||
};
|
||||
|
@ -55,6 +55,8 @@ struct wmi_ops {
|
||||
struct wmi_wow_ev_arg *arg);
|
||||
int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_echo_ev_arg *arg);
|
||||
int (*pull_dfs_status_ev)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_dfs_status_ev_arg *arg);
|
||||
int (*pull_svc_avail)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_svc_avail_ev_arg *arg);
|
||||
|
||||
@ -188,6 +190,9 @@ struct wmi_ops {
|
||||
const struct wmi_tdls_peer_update_cmd_arg *arg,
|
||||
const struct wmi_tdls_peer_capab_arg *cap,
|
||||
const struct wmi_channel_arg *chan);
|
||||
struct sk_buff *(*gen_radar_found)
|
||||
(struct ath10k *ar,
|
||||
const struct ath10k_radar_found_info *arg);
|
||||
struct sk_buff *(*gen_adaptive_qcs)(struct ath10k *ar, bool enable);
|
||||
struct sk_buff *(*gen_pdev_get_tpc_config)(struct ath10k *ar,
|
||||
u32 param);
|
||||
@ -395,6 +400,16 @@ ath10k_wmi_pull_echo_ev(struct ath10k *ar, struct sk_buff *skb,
|
||||
return ar->wmi.ops->pull_echo_ev(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_dfs_status(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_dfs_status_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_dfs_status_ev)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_dfs_status_ev(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline enum wmi_txbf_conf
|
||||
ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar)
|
||||
{
|
||||
@ -1511,4 +1526,21 @@ ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
|
||||
ar->wmi.cmd->pdev_get_tpc_table_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_report_radar_found(struct ath10k *ar,
|
||||
const struct ath10k_radar_found_info *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_radar_found)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_radar_found(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->radar_found_cmdid);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -3135,6 +3135,37 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
|
||||
u32 duration, u32 next_offset,
|
||||
u32 enabled)
|
||||
{
|
||||
struct wmi_tlv_set_quiet_cmd *cmd;
|
||||
struct wmi_tlv *tlv;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
tlv = (void *)skb->data;
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD);
|
||||
tlv->len = __cpu_to_le16(sizeof(*cmd));
|
||||
cmd = (void *)tlv->value;
|
||||
|
||||
/* vdev_id is not in use, set to 0 */
|
||||
cmd->vdev_id = __cpu_to_le32(0);
|
||||
cmd->period = __cpu_to_le32(period);
|
||||
cmd->duration = __cpu_to_le32(duration);
|
||||
cmd->next_start = __cpu_to_le32(next_offset);
|
||||
cmd->enabled = __cpu_to_le32(enabled);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi tlv quiet param: period %u duration %u enabled %d\n",
|
||||
period, duration, enabled);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
|
||||
{
|
||||
@ -3854,7 +3885,7 @@ static const struct wmi_ops wmi_tlv_ops = {
|
||||
.gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
|
||||
.gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
|
||||
.gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
|
||||
/* .gen_pdev_set_quiet_mode not implemented */
|
||||
.gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode,
|
||||
.gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature,
|
||||
/* .gen_addba_clear_resp not implemented */
|
||||
/* .gen_addba_send not implemented */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -1952,6 +1953,21 @@ struct wmi_tlv_wow_add_del_event_cmd {
|
||||
__le32 event_bitmap;
|
||||
} __packed;
|
||||
|
||||
/* Command to set/unset chip in quiet mode */
|
||||
struct wmi_tlv_set_quiet_cmd {
|
||||
__le32 vdev_id;
|
||||
|
||||
/* in TUs */
|
||||
__le32 period;
|
||||
|
||||
/* in TUs */
|
||||
__le32 duration;
|
||||
|
||||
/* offset in TUs */
|
||||
__le32 next_start;
|
||||
__le32 enabled;
|
||||
} __packed;
|
||||
|
||||
struct wmi_tlv_wow_enable_cmd {
|
||||
__le32 enable;
|
||||
} __packed;
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
|
||||
#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
|
||||
#define ATH10K_WMI_DFS_CONF_TIMEOUT_HZ (HZ / 6)
|
||||
|
||||
/* MAIN WMI cmd track */
|
||||
static struct wmi_cmd_map wmi_cmd_map = {
|
||||
@ -199,6 +200,7 @@ static struct wmi_cmd_map wmi_cmd_map = {
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.X WMI cmd track */
|
||||
@ -367,6 +369,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.2.4 WMI cmd track */
|
||||
@ -535,6 +538,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
|
||||
.pdev_bss_chan_info_request_cmdid =
|
||||
WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.4 WMI cmd track */
|
||||
@ -745,6 +749,7 @@ static struct wmi_cmd_map wmi_10_4_cmd_map = {
|
||||
.tdls_set_state_cmdid = WMI_10_4_TDLS_SET_STATE_CMDID,
|
||||
.tdls_peer_update_cmdid = WMI_10_4_TDLS_PEER_UPDATE_CMDID,
|
||||
.tdls_set_offchan_mode_cmdid = WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
|
||||
.radar_found_cmdid = WMI_10_4_RADAR_FOUND_CMDID,
|
||||
};
|
||||
|
||||
/* MAIN WMI VDEV param map */
|
||||
@ -1490,6 +1495,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
|
||||
.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
|
||||
@ -2318,7 +2324,6 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
u32 phy_mode;
|
||||
u32 snr;
|
||||
u32 rate;
|
||||
u32 buf_len;
|
||||
u16 fc;
|
||||
int ret;
|
||||
|
||||
@ -2330,7 +2335,6 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
channel = __le32_to_cpu(arg.channel);
|
||||
buf_len = __le32_to_cpu(arg.buf_len);
|
||||
rx_status = __le32_to_cpu(arg.status);
|
||||
snr = __le32_to_cpu(arg.snr);
|
||||
phy_mode = __le32_to_cpu(arg.phy_mode);
|
||||
@ -2740,14 +2744,13 @@ static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar,
|
||||
struct ath10k_fw_stats *stats)
|
||||
{
|
||||
const struct wmi_stats_event *ev = (void *)skb->data;
|
||||
u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
|
||||
u32 num_pdev_stats, num_peer_stats;
|
||||
int i;
|
||||
|
||||
if (!skb_pull(skb, sizeof(*ev)))
|
||||
return -EPROTO;
|
||||
|
||||
num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
||||
num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
||||
num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
||||
|
||||
for (i = 0; i < num_pdev_stats; i++) {
|
||||
@ -2795,14 +2798,13 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
|
||||
struct ath10k_fw_stats *stats)
|
||||
{
|
||||
const struct wmi_stats_event *ev = (void *)skb->data;
|
||||
u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
|
||||
u32 num_pdev_stats, num_peer_stats;
|
||||
int i;
|
||||
|
||||
if (!skb_pull(skb, sizeof(*ev)))
|
||||
return -EPROTO;
|
||||
|
||||
num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
||||
num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
||||
num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
||||
|
||||
for (i = 0; i < num_pdev_stats; i++) {
|
||||
@ -2856,7 +2858,6 @@ static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar,
|
||||
const struct wmi_10_2_stats_event *ev = (void *)skb->data;
|
||||
u32 num_pdev_stats;
|
||||
u32 num_pdev_ext_stats;
|
||||
u32 num_vdev_stats;
|
||||
u32 num_peer_stats;
|
||||
int i;
|
||||
|
||||
@ -2865,7 +2866,6 @@ static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar,
|
||||
|
||||
num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
||||
num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
|
||||
num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
||||
num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
||||
|
||||
for (i = 0; i < num_pdev_stats; i++) {
|
||||
@ -2935,7 +2935,6 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
|
||||
const struct wmi_10_2_stats_event *ev = (void *)skb->data;
|
||||
u32 num_pdev_stats;
|
||||
u32 num_pdev_ext_stats;
|
||||
u32 num_vdev_stats;
|
||||
u32 num_peer_stats;
|
||||
int i;
|
||||
|
||||
@ -2944,7 +2943,6 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
|
||||
|
||||
num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
||||
num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
|
||||
num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
||||
num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
||||
|
||||
for (i = 0; i < num_pdev_stats; i++) {
|
||||
@ -3691,6 +3689,68 @@ void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb)
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
|
||||
}
|
||||
|
||||
static void ath10k_radar_detected(struct ath10k *ar)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
|
||||
ATH10K_DFS_STAT_INC(ar, radar_detected);
|
||||
|
||||
/* Control radar events reporting in debugfs file
|
||||
* dfs_block_radar_events
|
||||
*/
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
ieee80211_radar_detected(ar->hw);
|
||||
}
|
||||
|
||||
static void ath10k_radar_confirmation_work(struct work_struct *work)
|
||||
{
|
||||
struct ath10k *ar = container_of(work, struct ath10k,
|
||||
radar_confirmation_work);
|
||||
struct ath10k_radar_found_info radar_info;
|
||||
int ret, time_left;
|
||||
|
||||
reinit_completion(&ar->wmi.radar_confirm);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
memcpy(&radar_info, &ar->last_radar_info, sizeof(radar_info));
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ret = ath10k_wmi_report_radar_found(ar, &radar_info);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to send radar found %d\n", ret);
|
||||
goto wait_complete;
|
||||
}
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->wmi.radar_confirm,
|
||||
ATH10K_WMI_DFS_CONF_TIMEOUT_HZ);
|
||||
if (time_left) {
|
||||
/* DFS Confirmation status event received and
|
||||
* necessary action completed.
|
||||
*/
|
||||
goto wait_complete;
|
||||
} else {
|
||||
/* DFS Confirmation event not received from FW.Considering this
|
||||
* as real radar.
|
||||
*/
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"dfs confirmation not received from fw, considering as radar\n");
|
||||
goto radar_detected;
|
||||
}
|
||||
|
||||
radar_detected:
|
||||
ath10k_radar_detected(ar);
|
||||
|
||||
/* Reset state to allow sending confirmation on consecutive radar
|
||||
* detections, unless radar confirmation is disabled/stopped.
|
||||
*/
|
||||
wait_complete:
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_STOPPED)
|
||||
ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
static void ath10k_dfs_radar_report(struct ath10k *ar,
|
||||
struct wmi_phyerr_ev_arg *phyerr,
|
||||
const struct phyerr_radar_report *rr,
|
||||
@ -3699,8 +3759,10 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
|
||||
u32 reg0, reg1, tsf32l;
|
||||
struct ieee80211_channel *ch;
|
||||
struct pulse_event pe;
|
||||
struct radar_detector_specs rs;
|
||||
u64 tsf64;
|
||||
u8 rssi, width;
|
||||
struct ath10k_radar_found_info *radar_info;
|
||||
|
||||
reg0 = __le32_to_cpu(rr->reg0);
|
||||
reg1 = __le32_to_cpu(rr->reg1);
|
||||
@ -3765,25 +3827,46 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
|
||||
|
||||
ATH10K_DFS_STAT_INC(ar, pulses_detected);
|
||||
|
||||
if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) {
|
||||
if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe, &rs)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"dfs no pulse pattern detected, yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
radar_detected:
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
|
||||
ATH10K_DFS_STAT_INC(ar, radar_detected);
|
||||
if ((test_bit(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, ar->wmi.svc_map)) &&
|
||||
ar->dfs_detector->region == NL80211_DFS_FCC) {
|
||||
/* Consecutive radar indications need not be
|
||||
* sent to the firmware until we get confirmation
|
||||
* for the previous detected radar.
|
||||
*/
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_IDLE) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
return;
|
||||
}
|
||||
ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_INPROGRESS;
|
||||
radar_info = &ar->last_radar_info;
|
||||
|
||||
/* Control radar events reporting in debugfs file
|
||||
* dfs_block_radar_events
|
||||
*/
|
||||
if (ar->dfs_block_radar_events) {
|
||||
ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
radar_info->pri_min = rs.pri_min;
|
||||
radar_info->pri_max = rs.pri_max;
|
||||
radar_info->width_min = rs.width_min;
|
||||
radar_info->width_max = rs.width_max;
|
||||
/*TODO Find sidx_min and sidx_max */
|
||||
radar_info->sidx_min = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
|
||||
radar_info->sidx_max = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"sending wmi radar found cmd pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
|
||||
radar_info->pri_min, radar_info->pri_max,
|
||||
radar_info->width_min, radar_info->width_max,
|
||||
radar_info->sidx_min, radar_info->sidx_max);
|
||||
ieee80211_queue_work(ar->hw, &ar->radar_confirmation_work);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
ieee80211_radar_detected(ar->hw);
|
||||
radar_detected:
|
||||
ath10k_radar_detected(ar);
|
||||
}
|
||||
|
||||
static int ath10k_dfs_fft_report(struct ath10k *ar,
|
||||
@ -4133,6 +4216,47 @@ void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_wmi_10_4_op_pull_dfs_status_ev(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_dfs_status_ev_arg *arg)
|
||||
{
|
||||
struct wmi_dfs_status_ev_arg *ev = (void *)skb->data;
|
||||
|
||||
if (skb->len < sizeof(*ev))
|
||||
return -EPROTO;
|
||||
|
||||
arg->status = ev->status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_wmi_event_dfs_status_check(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_dfs_status_ev_arg status_arg = {};
|
||||
int ret;
|
||||
|
||||
ret = ath10k_wmi_pull_dfs_status(ar, skb, &status_arg);
|
||||
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to parse dfs status event: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"dfs status event received from fw: %d\n",
|
||||
status_arg.status);
|
||||
|
||||
/* Even in case of radar detection failure we follow the same
|
||||
* behaviour as if radar is detected i.e to switch to a different
|
||||
* channel.
|
||||
*/
|
||||
if (status_arg.status == WMI_HW_RADAR_DETECTED ||
|
||||
status_arg.status == WMI_RADAR_DETECTION_FAIL)
|
||||
ath10k_radar_detected(ar);
|
||||
complete(&ar->wmi.radar_confirm);
|
||||
}
|
||||
|
||||
void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_roam_ev_arg arg = {};
|
||||
@ -4484,6 +4608,12 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
|
||||
|
||||
num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
|
||||
if (num_tx_chain > WMI_TPC_TX_N_CHAIN) {
|
||||
ath10k_warn(ar, "number of tx chain is %d greater than TPC configured tx chain %d\n",
|
||||
num_tx_chain, WMI_TPC_TX_N_CHAIN);
|
||||
return;
|
||||
}
|
||||
|
||||
ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
|
||||
num_tx_chain);
|
||||
|
||||
@ -5280,7 +5410,7 @@ void ath10k_wmi_event_service_available(struct ath10k *ar, struct sk_buff *skb)
|
||||
|
||||
ret = ath10k_wmi_pull_svc_avail(ar, skb, &arg);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to parse servive available event: %d\n",
|
||||
ath10k_warn(ar, "failed to parse service available event: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
@ -5878,6 +6008,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
|
||||
ath10k_wmi_event_tpc_final_table(ar, skb);
|
||||
break;
|
||||
case WMI_10_4_DFS_STATUS_CHECK_EVENTID:
|
||||
ath10k_wmi_event_dfs_status_check(ar, skb);
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
@ -8463,6 +8596,32 @@ ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_10_4_gen_radar_found(struct ath10k *ar,
|
||||
const struct ath10k_radar_found_info *arg)
|
||||
{
|
||||
struct wmi_radar_found_info *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cmd = (struct wmi_radar_found_info *)skb->data;
|
||||
cmd->pri_min = __cpu_to_le32(arg->pri_min);
|
||||
cmd->pri_max = __cpu_to_le32(arg->pri_max);
|
||||
cmd->width_min = __cpu_to_le32(arg->width_min);
|
||||
cmd->width_max = __cpu_to_le32(arg->width_max);
|
||||
cmd->sidx_min = __cpu_to_le32(arg->sidx_min);
|
||||
cmd->sidx_max = __cpu_to_le32(arg->sidx_max);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi radar found pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
|
||||
arg->pri_min, arg->pri_max, arg->width_min,
|
||||
arg->width_max, arg->sidx_min, arg->sidx_max);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
|
||||
{
|
||||
@ -8800,6 +8959,7 @@ static const struct wmi_ops wmi_10_4_ops = {
|
||||
.pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
|
||||
.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
|
||||
.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
|
||||
.pull_dfs_status_ev = ath10k_wmi_10_4_op_pull_dfs_status_ev,
|
||||
.get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme,
|
||||
|
||||
.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
|
||||
@ -8846,6 +9006,7 @@ static const struct wmi_ops wmi_10_4_ops = {
|
||||
.gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
|
||||
.gen_pdev_get_tpc_table_cmdid =
|
||||
ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
|
||||
.gen_radar_found = ath10k_wmi_10_4_gen_radar_found,
|
||||
|
||||
/* shared with 10.2 */
|
||||
.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
|
||||
@ -8908,8 +9069,11 @@ int ath10k_wmi_attach(struct ath10k *ar)
|
||||
init_completion(&ar->wmi.service_ready);
|
||||
init_completion(&ar->wmi.unified_ready);
|
||||
init_completion(&ar->wmi.barrier);
|
||||
init_completion(&ar->wmi.radar_confirm);
|
||||
|
||||
INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work);
|
||||
INIT_WORK(&ar->radar_confirmation_work,
|
||||
ath10k_radar_confirmation_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -969,6 +969,7 @@ struct wmi_cmd_map {
|
||||
u32 vdev_sifs_trigger_time_cmdid;
|
||||
u32 pdev_wds_entry_list_cmdid;
|
||||
u32 tdls_set_offchan_mode_cmdid;
|
||||
u32 radar_found_cmdid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1803,6 +1804,11 @@ enum wmi_10_4_cmd_id {
|
||||
WMI_10_4_TDLS_SET_STATE_CMDID,
|
||||
WMI_10_4_TDLS_PEER_UPDATE_CMDID,
|
||||
WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
|
||||
WMI_10_4_PDEV_SEND_FD_CMDID,
|
||||
WMI_10_4_ENABLE_FILS_CMDID,
|
||||
WMI_10_4_PDEV_SET_BRIDGE_MACADDR_CMDID,
|
||||
WMI_10_4_ATF_GROUP_WMM_AC_CONFIG_REQUEST_CMDID,
|
||||
WMI_10_4_RADAR_FOUND_CMDID,
|
||||
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
|
||||
};
|
||||
|
||||
@ -1878,6 +1884,9 @@ enum wmi_10_4_event_id {
|
||||
WMI_10_4_PDEV_TPC_TABLE_EVENTID,
|
||||
WMI_10_4_PDEV_WDS_ENTRY_LIST_EVENTID,
|
||||
WMI_10_4_TDLS_PEER_EVENTID,
|
||||
WMI_10_4_HOST_SWFDA_EVENTID,
|
||||
WMI_10_4_ESP_ESTIMATE_EVENTID,
|
||||
WMI_10_4_DFS_STATUS_CHECK_EVENTID,
|
||||
WMI_10_4_PDEV_UTF_EVENTID = WMI_10_4_END_EVENTID - 1,
|
||||
};
|
||||
|
||||
@ -3398,6 +3407,25 @@ struct wmi_10_4_phyerr_event {
|
||||
u8 buf[0];
|
||||
} __packed;
|
||||
|
||||
struct wmi_radar_found_info {
|
||||
__le32 pri_min;
|
||||
__le32 pri_max;
|
||||
__le32 width_min;
|
||||
__le32 width_max;
|
||||
__le32 sidx_min;
|
||||
__le32 sidx_max;
|
||||
} __packed;
|
||||
|
||||
enum wmi_radar_confirmation_status {
|
||||
/* Detected radar was due to SW pulses */
|
||||
WMI_SW_RADAR_DETECTED = 0,
|
||||
|
||||
WMI_RADAR_DETECTION_FAIL = 1,
|
||||
|
||||
/* Real radar detected */
|
||||
WMI_HW_RADAR_DETECTED = 2,
|
||||
};
|
||||
|
||||
#define PHYERR_TLV_SIG 0xBB
|
||||
#define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB
|
||||
#define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8
|
||||
@ -4026,9 +4054,9 @@ struct wmi_pdev_get_tpc_config_cmd {
|
||||
} __packed;
|
||||
|
||||
#define WMI_TPC_CONFIG_PARAM 1
|
||||
#define WMI_TPC_RATE_MAX 160
|
||||
#define WMI_TPC_FINAL_RATE_MAX 240
|
||||
#define WMI_TPC_TX_N_CHAIN 4
|
||||
#define WMI_TPC_RATE_MAX (WMI_TPC_TX_N_CHAIN * 65)
|
||||
#define WMI_TPC_PREAM_TABLE_MAX 10
|
||||
#define WMI_TPC_FLAG 3
|
||||
#define WMI_TPC_BUF_SIZE 10
|
||||
@ -6631,6 +6659,10 @@ struct wmi_phyerr_hdr_arg {
|
||||
const void *phyerrs;
|
||||
};
|
||||
|
||||
struct wmi_dfs_status_ev_arg {
|
||||
u32 status;
|
||||
};
|
||||
|
||||
struct wmi_svc_rdy_ev_arg {
|
||||
__le32 min_tx_power;
|
||||
__le32 max_tx_power;
|
||||
|
@ -914,7 +914,7 @@ void ath6kl_tx_data_cleanup(struct ath6kl *ar);
|
||||
|
||||
struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
|
||||
void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
|
||||
int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
|
||||
netdev_tx_t ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
|
||||
|
||||
struct aggr_info *aggr_init(struct ath6kl_vif *vif);
|
||||
void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
|
||||
|
@ -353,7 +353,7 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
||||
return status;
|
||||
}
|
||||
|
||||
int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
netdev_tx_t ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
struct ath6kl_cookie *cookie = NULL;
|
||||
|
@ -277,7 +277,7 @@ ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
|
||||
DFS_STAT_INC(sc, pulses_processed);
|
||||
if (pd == NULL)
|
||||
return;
|
||||
if (!pd->add_pulse(pd, pe))
|
||||
if (!pd->add_pulse(pd, pe, NULL))
|
||||
return;
|
||||
DFS_STAT_INC(sc, radar_detected);
|
||||
ieee80211_radar_detected(sc->hw);
|
||||
|
@ -268,7 +268,8 @@ static void dpd_exit(struct dfs_pattern_detector *dpd)
|
||||
}
|
||||
|
||||
static bool
|
||||
dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
|
||||
dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event,
|
||||
struct radar_detector_specs *rs)
|
||||
{
|
||||
u32 i;
|
||||
struct channel_detector *cd;
|
||||
@ -294,6 +295,8 @@ dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
|
||||
struct pri_detector *pd = cd->detectors[i];
|
||||
struct pri_sequence *ps = pd->add_pulse(pd, event);
|
||||
if (ps != NULL) {
|
||||
if (rs != NULL)
|
||||
memcpy(rs, pd->rs, sizeof(*rs));
|
||||
ath_dbg(dpd->common, DFS,
|
||||
"DFS: radar found on freq=%d: id=%d, pri=%d, "
|
||||
"count=%d, count_false=%d\n",
|
||||
|
@ -97,7 +97,8 @@ struct dfs_pattern_detector {
|
||||
bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd,
|
||||
enum nl80211_dfs_regions region);
|
||||
bool (*add_pulse)(struct dfs_pattern_detector *dpd,
|
||||
struct pulse_event *pe);
|
||||
struct pulse_event *pe,
|
||||
struct radar_detector_specs *rs);
|
||||
|
||||
struct ath_dfs_pool_stats (*get_stats)(struct dfs_pattern_detector *dpd);
|
||||
enum nl80211_dfs_regions region;
|
||||
|
@ -62,8 +62,9 @@ struct pri_detector {
|
||||
(*add_pulse)(struct pri_detector *de, struct pulse_event *e);
|
||||
void (*reset) (struct pri_detector *de, u64 ts);
|
||||
|
||||
/* private: internal use only */
|
||||
const struct radar_detector_specs *rs;
|
||||
|
||||
/* private: internal use only */
|
||||
u64 last_ts;
|
||||
struct list_head sequences;
|
||||
struct list_head pulses;
|
||||
|
@ -68,12 +68,14 @@ enum CountryCode {
|
||||
CTRY_AUSTRALIA = 36,
|
||||
CTRY_AUSTRIA = 40,
|
||||
CTRY_AZERBAIJAN = 31,
|
||||
CTRY_BAHAMAS = 44,
|
||||
CTRY_BAHRAIN = 48,
|
||||
CTRY_BANGLADESH = 50,
|
||||
CTRY_BARBADOS = 52,
|
||||
CTRY_BELARUS = 112,
|
||||
CTRY_BELGIUM = 56,
|
||||
CTRY_BELIZE = 84,
|
||||
CTRY_BERMUDA = 60,
|
||||
CTRY_BOLIVIA = 68,
|
||||
CTRY_BOSNIA_HERZ = 70,
|
||||
CTRY_BRAZIL = 76,
|
||||
@ -136,8 +138,10 @@ enum CountryCode {
|
||||
CTRY_MACEDONIA = 807,
|
||||
CTRY_MALAYSIA = 458,
|
||||
CTRY_MALTA = 470,
|
||||
CTRY_MAURITIUS = 480,
|
||||
CTRY_MEXICO = 484,
|
||||
CTRY_MONACO = 492,
|
||||
CTRY_MONTENEGRO = 499,
|
||||
CTRY_MOROCCO = 504,
|
||||
CTRY_NEPAL = 524,
|
||||
CTRY_NETHERLANDS = 528,
|
||||
@ -159,6 +163,7 @@ enum CountryCode {
|
||||
CTRY_ROMANIA = 642,
|
||||
CTRY_RUSSIA = 643,
|
||||
CTRY_SAUDI_ARABIA = 682,
|
||||
CTRY_SERBIA = 688,
|
||||
CTRY_SERBIA_MONTENEGRO = 891,
|
||||
CTRY_SINGAPORE = 702,
|
||||
CTRY_SLOVAKIA = 703,
|
||||
@ -170,11 +175,13 @@ enum CountryCode {
|
||||
CTRY_SWITZERLAND = 756,
|
||||
CTRY_SYRIA = 760,
|
||||
CTRY_TAIWAN = 158,
|
||||
CTRY_TANZANIA = 834,
|
||||
CTRY_THAILAND = 764,
|
||||
CTRY_TRINIDAD_Y_TOBAGO = 780,
|
||||
CTRY_TUNISIA = 788,
|
||||
CTRY_TURKEY = 792,
|
||||
CTRY_UAE = 784,
|
||||
CTRY_UGANDA = 800,
|
||||
CTRY_UKRAINE = 804,
|
||||
CTRY_UNITED_KINGDOM = 826,
|
||||
CTRY_UNITED_STATES = 840,
|
||||
|
@ -35,6 +35,7 @@ enum EnumRd {
|
||||
FRANCE_RES = 0x31,
|
||||
FCC3_FCCA = 0x3A,
|
||||
FCC3_WORLD = 0x3B,
|
||||
FCC3_ETSIC = 0x3F,
|
||||
|
||||
ETSI1_WORLD = 0x37,
|
||||
ETSI3_ETSIA = 0x32,
|
||||
@ -44,6 +45,8 @@ enum EnumRd {
|
||||
ETSI4_ETSIC = 0x38,
|
||||
ETSI5_WORLD = 0x39,
|
||||
ETSI6_WORLD = 0x34,
|
||||
ETSI8_WORLD = 0x3D,
|
||||
ETSI9_WORLD = 0x3E,
|
||||
ETSI_RESERVED = 0x33,
|
||||
|
||||
MKK1_MKKA = 0x40,
|
||||
@ -59,6 +62,7 @@ enum EnumRd {
|
||||
MKK1_MKKA1 = 0x4A,
|
||||
MKK1_MKKA2 = 0x4B,
|
||||
MKK1_MKKC = 0x4C,
|
||||
APL2_FCCA = 0x4D,
|
||||
|
||||
APL3_FCCA = 0x50,
|
||||
APL1_WORLD = 0x52,
|
||||
@ -67,6 +71,7 @@ enum EnumRd {
|
||||
APL1_ETSIC = 0x55,
|
||||
APL2_ETSIC = 0x56,
|
||||
APL5_WORLD = 0x58,
|
||||
APL13_WORLD = 0x5A,
|
||||
APL6_WORLD = 0x5B,
|
||||
APL7_FCCA = 0x5C,
|
||||
APL8_WORLD = 0x5D,
|
||||
@ -168,6 +173,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
|
||||
{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
|
||||
{FCC3_FCCA, CTL_FCC, CTL_FCC},
|
||||
{FCC3_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{FCC3_ETSIC, CTL_FCC, CTL_ETSI},
|
||||
{FCC4_FCCA, CTL_FCC, CTL_FCC},
|
||||
{FCC5_FCCA, CTL_FCC, CTL_FCC},
|
||||
{FCC6_FCCA, CTL_FCC, CTL_FCC},
|
||||
@ -179,6 +185,8 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
|
||||
{ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{ETSI8_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{ETSI9_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
|
||||
/* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
|
||||
{ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
|
||||
@ -188,9 +196,11 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
|
||||
{FCC1_FCCA, CTL_FCC, CTL_FCC},
|
||||
{APL1_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{APL2_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{APL2_FCCA, CTL_FCC, CTL_FCC},
|
||||
{APL3_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{APL4_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{APL5_WORLD, CTL_FCC, CTL_ETSI},
|
||||
{APL13_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{APL6_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{APL8_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
{APL9_WORLD, CTL_ETSI, CTL_ETSI},
|
||||
@ -289,37 +299,39 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
|
||||
static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_DEBUG, NO_ENUMRD, "DB"},
|
||||
{CTRY_DEFAULT, FCC1_FCCA, "CO"},
|
||||
{CTRY_ALBANIA, NULL1_WORLD, "AL"},
|
||||
{CTRY_ALGERIA, NULL1_WORLD, "DZ"},
|
||||
{CTRY_ALBANIA, ETSI1_WORLD, "AL"},
|
||||
{CTRY_ALGERIA, APL13_WORLD, "DZ"},
|
||||
{CTRY_ARGENTINA, FCC3_WORLD, "AR"},
|
||||
{CTRY_ARMENIA, ETSI4_WORLD, "AM"},
|
||||
{CTRY_ARUBA, ETSI1_WORLD, "AW"},
|
||||
{CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
|
||||
{CTRY_AUSTRALIA, FCC3_WORLD, "AU"},
|
||||
{CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
|
||||
{CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
|
||||
{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
|
||||
{CTRY_BAHAMAS, FCC3_WORLD, "BS"},
|
||||
{CTRY_BAHRAIN, APL6_WORLD, "BH"},
|
||||
{CTRY_BANGLADESH, NULL1_WORLD, "BD"},
|
||||
{CTRY_BANGLADESH, APL1_WORLD, "BD"},
|
||||
{CTRY_BARBADOS, FCC2_WORLD, "BB"},
|
||||
{CTRY_BELARUS, ETSI1_WORLD, "BY"},
|
||||
{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
|
||||
{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
|
||||
{CTRY_BELIZE, APL1_ETSIC, "BZ"},
|
||||
{CTRY_BERMUDA, FCC3_FCCA, "BM"},
|
||||
{CTRY_BOLIVIA, APL1_ETSIC, "BO"},
|
||||
{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
|
||||
{CTRY_BRAZIL, FCC3_WORLD, "BR"},
|
||||
{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
|
||||
{CTRY_BULGARIA, ETSI6_WORLD, "BG"},
|
||||
{CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN"},
|
||||
{CTRY_BULGARIA, ETSI1_WORLD, "BG"},
|
||||
{CTRY_CAMBODIA, ETSI1_WORLD, "KH"},
|
||||
{CTRY_CANADA, FCC3_FCCA, "CA"},
|
||||
{CTRY_CANADA2, FCC6_FCCA, "CA"},
|
||||
{CTRY_CHILE, APL6_WORLD, "CL"},
|
||||
{CTRY_CHINA, APL1_WORLD, "CN"},
|
||||
{CTRY_COLOMBIA, FCC1_FCCA, "CO"},
|
||||
{CTRY_COLOMBIA, FCC3_WORLD, "CO"},
|
||||
{CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
|
||||
{CTRY_CROATIA, ETSI1_WORLD, "HR"},
|
||||
{CTRY_CYPRUS, ETSI1_WORLD, "CY"},
|
||||
{CTRY_CZECH, ETSI3_WORLD, "CZ"},
|
||||
{CTRY_CZECH, ETSI1_WORLD, "CZ"},
|
||||
{CTRY_DENMARK, ETSI1_WORLD, "DK"},
|
||||
{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
|
||||
{CTRY_ECUADOR, FCC1_WORLD, "EC"},
|
||||
@ -336,7 +348,7 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_GUAM, FCC1_FCCA, "GU"},
|
||||
{CTRY_GUATEMALA, FCC1_FCCA, "GT"},
|
||||
{CTRY_HAITI, ETSI1_WORLD, "HT"},
|
||||
{CTRY_HONDURAS, NULL1_WORLD, "HN"},
|
||||
{CTRY_HONDURAS, FCC3_WORLD, "HN"},
|
||||
{CTRY_HONG_KONG, FCC3_WORLD, "HK"},
|
||||
{CTRY_HUNGARY, ETSI1_WORLD, "HU"},
|
||||
{CTRY_ICELAND, ETSI1_WORLD, "IS"},
|
||||
@ -344,7 +356,7 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_INDONESIA, NULL1_WORLD, "ID"},
|
||||
{CTRY_IRAN, APL1_WORLD, "IR"},
|
||||
{CTRY_IRELAND, ETSI1_WORLD, "IE"},
|
||||
{CTRY_ISRAEL, NULL1_WORLD, "IL"},
|
||||
{CTRY_ISRAEL, ETSI3_WORLD, "IL"},
|
||||
{CTRY_ITALY, ETSI1_WORLD, "IT"},
|
||||
{CTRY_JAMAICA, FCC3_WORLD, "JM"},
|
||||
|
||||
@ -409,6 +421,7 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
|
||||
{CTRY_JORDAN, ETSI2_WORLD, "JO"},
|
||||
{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
|
||||
{CTRY_KENYA, APL1_WORLD, "KE"},
|
||||
{CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
|
||||
{CTRY_KOREA_ROC, APL9_WORLD, "KR"},
|
||||
{CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
|
||||
@ -420,32 +433,37 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
|
||||
{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
|
||||
{CTRY_MACAU, FCC2_WORLD, "MO"},
|
||||
{CTRY_MACEDONIA, NULL1_WORLD, "MK"},
|
||||
{CTRY_MALAYSIA, APL8_WORLD, "MY"},
|
||||
{CTRY_MACEDONIA, ETSI1_WORLD, "MK"},
|
||||
{CTRY_MALAYSIA, FCC1_WORLD, "MY"},
|
||||
{CTRY_MALTA, ETSI1_WORLD, "MT"},
|
||||
{CTRY_MAURITIUS, ETSI1_WORLD, "MU"},
|
||||
{CTRY_MEXICO, FCC1_FCCA, "MX"},
|
||||
{CTRY_MONACO, ETSI4_WORLD, "MC"},
|
||||
{CTRY_MONTENEGRO, ETSI1_WORLD, "ME"},
|
||||
{CTRY_MOROCCO, APL4_WORLD, "MA"},
|
||||
{CTRY_NEPAL, APL1_WORLD, "NP"},
|
||||
{CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
|
||||
{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
|
||||
{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
|
||||
{CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ"},
|
||||
{CTRY_NICARAGUA, FCC3_FCCA, "NI"},
|
||||
{CTRY_NORWAY, ETSI1_WORLD, "NO"},
|
||||
{CTRY_OMAN, FCC3_WORLD, "OM"},
|
||||
{CTRY_PAKISTAN, NULL1_WORLD, "PK"},
|
||||
{CTRY_PANAMA, FCC1_FCCA, "PA"},
|
||||
{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
|
||||
{CTRY_PERU, APL1_WORLD, "PE"},
|
||||
{CTRY_PHILIPPINES, APL1_WORLD, "PH"},
|
||||
{CTRY_PARAGUAY, FCC3_WORLD, "PY"},
|
||||
{CTRY_PERU, FCC3_WORLD, "PE"},
|
||||
{CTRY_PHILIPPINES, FCC3_WORLD, "PH"},
|
||||
{CTRY_POLAND, ETSI1_WORLD, "PL"},
|
||||
{CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
|
||||
{CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
|
||||
{CTRY_QATAR, APL1_WORLD, "QA"},
|
||||
{CTRY_ROMANIA, NULL1_WORLD, "RO"},
|
||||
{CTRY_RUSSIA, NULL1_WORLD, "RU"},
|
||||
{CTRY_ROMANIA, ETSI1_WORLD, "RO"},
|
||||
{CTRY_RUSSIA, ETSI8_WORLD, "RU"},
|
||||
{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
|
||||
{CTRY_SERBIA, ETSI1_WORLD, "RS"},
|
||||
{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
|
||||
{CTRY_SINGAPORE, APL6_WORLD, "SG"},
|
||||
{CTRY_SINGAPORE, FCC3_WORLD, "SG"},
|
||||
{CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
|
||||
{CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
|
||||
{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
|
||||
@ -455,11 +473,13 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
|
||||
{CTRY_SYRIA, NULL1_WORLD, "SY"},
|
||||
{CTRY_TAIWAN, APL3_FCCA, "TW"},
|
||||
{CTRY_TANZANIA, APL1_WORLD, "TZ"},
|
||||
{CTRY_THAILAND, FCC3_WORLD, "TH"},
|
||||
{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
|
||||
{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
|
||||
{CTRY_TURKEY, ETSI3_WORLD, "TR"},
|
||||
{CTRY_UKRAINE, NULL1_WORLD, "UA"},
|
||||
{CTRY_UGANDA, FCC3_WORLD, "UG"},
|
||||
{CTRY_UKRAINE, ETSI9_WORLD, "UA"},
|
||||
{CTRY_UAE, NULL1_WORLD, "AE"},
|
||||
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
|
||||
{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
|
||||
@ -472,7 +492,7 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
{CTRY_VENEZUELA, APL2_ETSIC, "VE"},
|
||||
{CTRY_VIET_NAM, NULL1_WORLD, "VN"},
|
||||
{CTRY_YEMEN, NULL1_WORLD, "YE"},
|
||||
{CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
|
||||
{CTRY_ZIMBABWE, ETSI1_WORLD, "ZW"},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,3 +6,5 @@ wcn36xx-y += main.o \
|
||||
smd.o \
|
||||
pmc.o \
|
||||
debug.o
|
||||
|
||||
wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
|
@ -370,7 +370,9 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
|
||||
do {
|
||||
if (READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_VLD)
|
||||
break;
|
||||
if (ctl->skb) {
|
||||
|
||||
if (ctl->skb &&
|
||||
READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_EOP) {
|
||||
dma_unmap_single(wcn->dev, ctl->desc->src_addr_l,
|
||||
ctl->skb->len, DMA_TO_DEVICE);
|
||||
info = IEEE80211_SKB_CB(ctl->skb);
|
||||
@ -430,8 +432,12 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
|
||||
WCN36XX_INT_MASK_CHAN_TX_H);
|
||||
}
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n");
|
||||
reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch);
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high, reason %08x\n",
|
||||
int_reason);
|
||||
|
||||
if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK |
|
||||
WCN36XX_CH_STAT_INT_ED_MASK))
|
||||
reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch);
|
||||
}
|
||||
|
||||
if (int_src & WCN36XX_INT_MASK_CHAN_TX_L) {
|
||||
@ -465,8 +471,12 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
|
||||
WCN36XX_INT_MASK_CHAN_TX_L);
|
||||
}
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n");
|
||||
reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch);
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low, reason %08x\n",
|
||||
int_reason);
|
||||
|
||||
if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK |
|
||||
WCN36XX_CH_STAT_INT_ED_MASK))
|
||||
reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@ -476,9 +486,8 @@ static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev)
|
||||
{
|
||||
struct wcn36xx *wcn = (struct wcn36xx *)dev;
|
||||
|
||||
disable_irq_nosync(wcn->rx_irq);
|
||||
wcn36xx_dxe_rx_frame(wcn);
|
||||
enable_irq(wcn->rx_irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -512,23 +521,49 @@ static int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn)
|
||||
}
|
||||
|
||||
static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
|
||||
struct wcn36xx_dxe_ch *ch)
|
||||
struct wcn36xx_dxe_ch *ch,
|
||||
u32 ctrl,
|
||||
u32 en_mask,
|
||||
u32 int_mask,
|
||||
u32 status_reg)
|
||||
{
|
||||
struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl;
|
||||
struct wcn36xx_dxe_desc *dxe = ctl->desc;
|
||||
struct wcn36xx_dxe_desc *dxe;
|
||||
struct wcn36xx_dxe_ctl *ctl;
|
||||
dma_addr_t dma_addr;
|
||||
struct sk_buff *skb;
|
||||
int ret = 0, int_mask;
|
||||
u32 value;
|
||||
u32 int_reason;
|
||||
int ret;
|
||||
|
||||
if (ch->ch_type == WCN36XX_DXE_CH_RX_L) {
|
||||
value = WCN36XX_DXE_CTRL_RX_L;
|
||||
int_mask = WCN36XX_DXE_INT_CH1_MASK;
|
||||
} else {
|
||||
value = WCN36XX_DXE_CTRL_RX_H;
|
||||
int_mask = WCN36XX_DXE_INT_CH3_MASK;
|
||||
wcn36xx_dxe_read_register(wcn, status_reg, &int_reason);
|
||||
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR, int_mask);
|
||||
|
||||
if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK) {
|
||||
wcn36xx_dxe_write_register(wcn,
|
||||
WCN36XX_DXE_0_INT_ERR_CLR,
|
||||
int_mask);
|
||||
|
||||
wcn36xx_err("DXE IRQ reported error on RX channel\n");
|
||||
}
|
||||
|
||||
if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK)
|
||||
wcn36xx_dxe_write_register(wcn,
|
||||
WCN36XX_DXE_0_INT_DONE_CLR,
|
||||
int_mask);
|
||||
|
||||
if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK)
|
||||
wcn36xx_dxe_write_register(wcn,
|
||||
WCN36XX_DXE_0_INT_ED_CLR,
|
||||
int_mask);
|
||||
|
||||
if (!(int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK |
|
||||
WCN36XX_CH_STAT_INT_ED_MASK)))
|
||||
return 0;
|
||||
|
||||
spin_lock(&ch->lock);
|
||||
|
||||
ctl = ch->head_blk_ctl;
|
||||
dxe = ctl->desc;
|
||||
|
||||
while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) {
|
||||
skb = ctl->skb;
|
||||
dma_addr = dxe->dst_addr_l;
|
||||
@ -542,13 +577,16 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
|
||||
wcn36xx_rx_skb(wcn, skb);
|
||||
} /* else keep old skb not submitted and use it for rx DMA */
|
||||
|
||||
dxe->ctrl = value;
|
||||
dxe->ctrl = ctrl;
|
||||
ctl = ctl->next;
|
||||
dxe = ctl->desc;
|
||||
}
|
||||
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, int_mask);
|
||||
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, en_mask);
|
||||
|
||||
ch->head_blk_ctl = ctl;
|
||||
|
||||
spin_unlock(&ch->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -559,19 +597,20 @@ void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn)
|
||||
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src);
|
||||
|
||||
/* RX_LOW_PRI */
|
||||
if (int_src & WCN36XX_DXE_INT_CH1_MASK) {
|
||||
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR,
|
||||
WCN36XX_DXE_INT_CH1_MASK);
|
||||
wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_l_ch));
|
||||
}
|
||||
if (int_src & WCN36XX_DXE_INT_CH1_MASK)
|
||||
wcn36xx_rx_handle_packets(wcn, &wcn->dxe_rx_l_ch,
|
||||
WCN36XX_DXE_CTRL_RX_L,
|
||||
WCN36XX_DXE_INT_CH1_MASK,
|
||||
WCN36XX_INT_MASK_CHAN_RX_L,
|
||||
WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L);
|
||||
|
||||
/* RX_HIGH_PRI */
|
||||
if (int_src & WCN36XX_DXE_INT_CH3_MASK) {
|
||||
/* Clean up all the INT within this channel */
|
||||
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR,
|
||||
WCN36XX_DXE_INT_CH3_MASK);
|
||||
wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_h_ch));
|
||||
}
|
||||
if (int_src & WCN36XX_DXE_INT_CH3_MASK)
|
||||
wcn36xx_rx_handle_packets(wcn, &wcn->dxe_rx_h_ch,
|
||||
WCN36XX_DXE_CTRL_RX_H,
|
||||
WCN36XX_DXE_INT_CH3_MASK,
|
||||
WCN36XX_INT_MASK_CHAN_RX_H,
|
||||
WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H);
|
||||
|
||||
if (!int_src)
|
||||
wcn36xx_warn("No DXE interrupt pending\n");
|
||||
@ -642,8 +681,8 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
|
||||
struct sk_buff *skb,
|
||||
bool is_low)
|
||||
{
|
||||
struct wcn36xx_dxe_ctl *ctl = NULL;
|
||||
struct wcn36xx_dxe_desc *desc = NULL;
|
||||
struct wcn36xx_dxe_desc *desc_bd, *desc_skb;
|
||||
struct wcn36xx_dxe_ctl *ctl_bd, *ctl_skb;
|
||||
struct wcn36xx_dxe_ch *ch = NULL;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
@ -651,74 +690,75 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
|
||||
ch = is_low ? &wcn->dxe_tx_l_ch : &wcn->dxe_tx_h_ch;
|
||||
|
||||
spin_lock_irqsave(&ch->lock, flags);
|
||||
ctl = ch->head_blk_ctl;
|
||||
ctl_bd = ch->head_blk_ctl;
|
||||
ctl_skb = ctl_bd->next;
|
||||
|
||||
/*
|
||||
* If skb is not null that means that we reached the tail of the ring
|
||||
* hence ring is full. Stop queues to let mac80211 back off until ring
|
||||
* has an empty slot again.
|
||||
*/
|
||||
if (NULL != ctl->next->skb) {
|
||||
if (NULL != ctl_skb->skb) {
|
||||
ieee80211_stop_queues(wcn->hw);
|
||||
wcn->queues_stopped = true;
|
||||
spin_unlock_irqrestore(&ch->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ctl->skb = NULL;
|
||||
desc = ctl->desc;
|
||||
|
||||
/* write buffer descriptor */
|
||||
memcpy(ctl->bd_cpu_addr, bd, sizeof(*bd));
|
||||
|
||||
/* Set source address of the BD we send */
|
||||
desc->src_addr_l = ctl->bd_phy_addr;
|
||||
|
||||
desc->dst_addr_l = ch->dxe_wq;
|
||||
desc->fr_len = sizeof(struct wcn36xx_tx_bd);
|
||||
desc->ctrl = ch->ctrl_bd;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "DXE TX\n");
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC1 >>> ",
|
||||
(char *)desc, sizeof(*desc));
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP,
|
||||
"BD >>> ", (char *)ctl->bd_cpu_addr,
|
||||
sizeof(struct wcn36xx_tx_bd));
|
||||
|
||||
/* Set source address of the SKB we send */
|
||||
ctl = ctl->next;
|
||||
desc = ctl->desc;
|
||||
if (ctl->bd_cpu_addr) {
|
||||
if (unlikely(ctl_skb->bd_cpu_addr)) {
|
||||
wcn36xx_err("bd_cpu_addr cannot be NULL for skb DXE\n");
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
desc->src_addr_l = dma_map_single(wcn->dev,
|
||||
skb->data,
|
||||
skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(wcn->dev, desc->src_addr_l)) {
|
||||
desc_bd = ctl_bd->desc;
|
||||
desc_skb = ctl_skb->desc;
|
||||
|
||||
ctl_bd->skb = NULL;
|
||||
|
||||
/* write buffer descriptor */
|
||||
memcpy(ctl_bd->bd_cpu_addr, bd, sizeof(*bd));
|
||||
|
||||
/* Set source address of the BD we send */
|
||||
desc_bd->src_addr_l = ctl_bd->bd_phy_addr;
|
||||
desc_bd->dst_addr_l = ch->dxe_wq;
|
||||
desc_bd->fr_len = sizeof(struct wcn36xx_tx_bd);
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_DXE, "DXE TX\n");
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC1 >>> ",
|
||||
(char *)desc_bd, sizeof(*desc_bd));
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP,
|
||||
"BD >>> ", (char *)ctl_bd->bd_cpu_addr,
|
||||
sizeof(struct wcn36xx_tx_bd));
|
||||
|
||||
desc_skb->src_addr_l = dma_map_single(wcn->dev,
|
||||
skb->data,
|
||||
skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(wcn->dev, desc_skb->src_addr_l)) {
|
||||
dev_err(wcn->dev, "unable to DMA map src_addr_l\n");
|
||||
ret = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ctl->skb = skb;
|
||||
desc->dst_addr_l = ch->dxe_wq;
|
||||
desc->fr_len = ctl->skb->len;
|
||||
|
||||
/* set dxe descriptor to VALID */
|
||||
desc->ctrl = ch->ctrl_skb;
|
||||
ctl_skb->skb = skb;
|
||||
desc_skb->dst_addr_l = ch->dxe_wq;
|
||||
desc_skb->fr_len = ctl_skb->skb->len;
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC2 >>> ",
|
||||
(char *)desc, sizeof(*desc));
|
||||
(char *)desc_skb, sizeof(*desc_skb));
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "SKB >>> ",
|
||||
(char *)ctl->skb->data, ctl->skb->len);
|
||||
(char *)ctl_skb->skb->data, ctl_skb->skb->len);
|
||||
|
||||
/* Move the head of the ring to the next empty descriptor */
|
||||
ch->head_blk_ctl = ctl->next;
|
||||
ch->head_blk_ctl = ctl_skb->next;
|
||||
|
||||
/* Commit all previous writes and set descriptors to VALID */
|
||||
wmb();
|
||||
desc_skb->ctrl = ch->ctrl_skb;
|
||||
wmb();
|
||||
desc_bd->ctrl = ch->ctrl_bd;
|
||||
|
||||
/*
|
||||
* When connected and trying to send data frame chip can be in sleep
|
||||
|
@ -2236,6 +2236,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
|
||||
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_process_ptt_msg_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
/* Actual FTM Command body */
|
||||
u8 ptt_msg[0];
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_process_ptt_msg_rsp_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
/* FTM Command response status */
|
||||
u32 ptt_msg_resp_status;
|
||||
/* Actual FTM Command body */
|
||||
u8 ptt_msg[0];
|
||||
} __packed;
|
||||
|
||||
struct update_edca_params_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/soc/qcom/smem_state.h>
|
||||
#include <linux/soc/qcom/wcnss_ctrl.h>
|
||||
#include "wcn36xx.h"
|
||||
#include "testmode.h"
|
||||
|
||||
unsigned int wcn36xx_dbg_mask;
|
||||
module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
|
||||
@ -798,6 +799,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
||||
if (!is_zero_ether_addr(bss_conf->bssid)) {
|
||||
vif_priv->is_joining = true;
|
||||
vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
|
||||
wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr,
|
||||
WCN36XX_HAL_LINK_PREASSOC_STATE);
|
||||
wcn36xx_smd_join(wcn, bss_conf->bssid,
|
||||
vif->addr, WCN36XX_HW_CHANNEL(wcn));
|
||||
wcn36xx_smd_config_bss(wcn, vif, NULL,
|
||||
@ -805,6 +808,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
||||
} else {
|
||||
vif_priv->is_joining = false;
|
||||
wcn36xx_smd_delete_bss(wcn, vif);
|
||||
wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr,
|
||||
WCN36XX_HAL_LINK_IDLE_STATE);
|
||||
vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE;
|
||||
}
|
||||
}
|
||||
@ -1142,6 +1147,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
|
||||
.sta_add = wcn36xx_sta_add,
|
||||
.sta_remove = wcn36xx_sta_remove,
|
||||
.ampdu_action = wcn36xx_ampdu_action,
|
||||
|
||||
CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
|
||||
};
|
||||
|
||||
static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
||||
@ -1309,6 +1316,12 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
||||
mutex_init(&wcn->hal_mutex);
|
||||
mutex_init(&wcn->scan_lock);
|
||||
|
||||
ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
|
||||
if (ret < 0) {
|
||||
wcn36xx_err("failed to set DMA mask: %d\n", ret);
|
||||
goto out_wq;
|
||||
}
|
||||
|
||||
INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
|
||||
|
||||
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
|
||||
|
@ -252,23 +252,29 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long start;
|
||||
struct wcn36xx_hal_msg_header *hdr =
|
||||
(struct wcn36xx_hal_msg_header *)wcn->hal_buf;
|
||||
u16 req_type = hdr->msg_type;
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "HAL >>> ", wcn->hal_buf, len);
|
||||
|
||||
init_completion(&wcn->hal_rsp_compl);
|
||||
start = jiffies;
|
||||
ret = rpmsg_send(wcn->smd_channel, wcn->hal_buf, len);
|
||||
if (ret) {
|
||||
wcn36xx_err("HAL TX failed\n");
|
||||
wcn36xx_err("HAL TX failed for req %d\n", req_type);
|
||||
goto out;
|
||||
}
|
||||
if (wait_for_completion_timeout(&wcn->hal_rsp_compl,
|
||||
msecs_to_jiffies(HAL_MSG_TIMEOUT)) <= 0) {
|
||||
wcn36xx_err("Timeout! No SMD response in %dms\n",
|
||||
HAL_MSG_TIMEOUT);
|
||||
wcn36xx_err("Timeout! No SMD response to req %d in %dms\n",
|
||||
req_type, HAL_MSG_TIMEOUT);
|
||||
ret = -ETIME;
|
||||
goto out;
|
||||
}
|
||||
wcn36xx_dbg(WCN36XX_DBG_SMD, "SMD command completed in %dms",
|
||||
wcn36xx_dbg(WCN36XX_DBG_SMD,
|
||||
"SMD command (req %d, rsp %d) completed in %dms\n",
|
||||
req_type, hdr->msg_type,
|
||||
jiffies_to_msecs(jiffies - start));
|
||||
out:
|
||||
return ret;
|
||||
@ -292,12 +298,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header *hdr,
|
||||
msg_body.header.len = sizeof(msg_body); \
|
||||
} while (0) \
|
||||
|
||||
#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
|
||||
do { \
|
||||
memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
|
||||
p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
|
||||
p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
|
||||
p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
|
||||
} while (0)
|
||||
|
||||
#define PREPARE_HAL_BUF(send_buf, msg_body) \
|
||||
do { \
|
||||
memset(send_buf, 0, msg_body.header.len); \
|
||||
memcpy(send_buf, &msg_body, sizeof(msg_body)); \
|
||||
} while (0) \
|
||||
|
||||
#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
|
||||
do { \
|
||||
memset(send_buf, 0, p_msg_body->header.len); \
|
||||
memcpy(send_buf, p_msg_body, p_msg_body->header.len); \
|
||||
} while (0)
|
||||
|
||||
static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
|
||||
{
|
||||
struct wcn36xx_fw_msg_status_rsp *rsp;
|
||||
@ -754,6 +774,71 @@ int wcn36xx_smd_switch_channel(struct wcn36xx *wcn,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len,
|
||||
void **p_ptt_rsp_msg)
|
||||
{
|
||||
struct wcn36xx_hal_process_ptt_msg_rsp_msg *rsp;
|
||||
int ret;
|
||||
|
||||
ret = wcn36xx_smd_rsp_status_check(buf, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n",
|
||||
rsp->header.len);
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_HAL_DUMP, "HAL_PTT_MSG_RSP:", rsp->ptt_msg,
|
||||
rsp->header.len - sizeof(rsp->ptt_msg_resp_status));
|
||||
|
||||
if (rsp->header.len > 0) {
|
||||
*p_ptt_rsp_msg = kmalloc(rsp->header.len, GFP_ATOMIC);
|
||||
if (!*p_ptt_rsp_msg)
|
||||
return -ENOMEM;
|
||||
memcpy(*p_ptt_rsp_msg, rsp->ptt_msg, rsp->header.len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif, void *ptt_msg, size_t len,
|
||||
void **ptt_rsp_msg)
|
||||
{
|
||||
struct wcn36xx_hal_process_ptt_msg_req_msg *p_msg_body;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
p_msg_body = kmalloc(
|
||||
sizeof(struct wcn36xx_hal_process_ptt_msg_req_msg) + len,
|
||||
GFP_ATOMIC);
|
||||
if (!p_msg_body) {
|
||||
ret = -ENOMEM;
|
||||
goto out_nomem;
|
||||
}
|
||||
INIT_HAL_PTT_MSG(p_msg_body, len);
|
||||
|
||||
memcpy(&p_msg_body->ptt_msg, ptt_msg, len);
|
||||
|
||||
PREPARE_HAL_PTT_MSG_BUF(wcn->hal_buf, p_msg_body);
|
||||
|
||||
ret = wcn36xx_smd_send_and_wait(wcn, p_msg_body->header.len);
|
||||
if (ret) {
|
||||
wcn36xx_err("Sending hal_process_ptt_msg failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_process_ptt_msg_rsp(wcn->hal_buf, wcn->hal_rsp_len,
|
||||
ptt_rsp_msg);
|
||||
if (ret) {
|
||||
wcn36xx_err("process_ptt_msg response failed err=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
kfree(p_msg_body);
|
||||
out_nomem:
|
||||
mutex_unlock(&wcn->hal_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
|
||||
{
|
||||
struct wcn36xx_hal_update_scan_params_resp *rsp;
|
||||
@ -2390,6 +2475,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
|
||||
case WCN36XX_HAL_JOIN_RSP:
|
||||
case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP:
|
||||
case WCN36XX_HAL_CH_SWITCH_RSP:
|
||||
case WCN36XX_HAL_PROCESS_PTT_RSP:
|
||||
case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP:
|
||||
case WCN36XX_HAL_8023_MULTICAST_LIST_RSP:
|
||||
case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP:
|
||||
@ -2430,6 +2516,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcn36xx_ind_smd_work(struct work_struct *work)
|
||||
{
|
||||
struct wcn36xx *wcn =
|
||||
@ -2494,24 +2581,24 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
|
||||
}
|
||||
int wcn36xx_smd_open(struct wcn36xx *wcn)
|
||||
{
|
||||
int ret = 0;
|
||||
wcn->hal_ind_wq = create_freezable_workqueue("wcn36xx_smd_ind");
|
||||
if (!wcn->hal_ind_wq) {
|
||||
wcn36xx_err("failed to allocate wq\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!wcn->hal_ind_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work);
|
||||
INIT_LIST_HEAD(&wcn->hal_ind_queue);
|
||||
spin_lock_init(&wcn->hal_ind_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wcn36xx_smd_close(struct wcn36xx *wcn)
|
||||
{
|
||||
struct wcn36xx_hal_ind_msg *msg, *tmp;
|
||||
|
||||
cancel_work_sync(&wcn->hal_ind_work);
|
||||
destroy_workqueue(wcn->hal_ind_wq);
|
||||
|
||||
list_for_each_entry_safe(msg, tmp, &wcn->hal_ind_queue, list)
|
||||
kfree(msg);
|
||||
}
|
||||
|
@ -86,6 +86,10 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif,
|
||||
u16 p2p_off);
|
||||
int wcn36xx_smd_switch_channel(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif, int ch);
|
||||
int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif,
|
||||
void *ptt_msg, size_t len,
|
||||
void **ptt_rsp_msg);
|
||||
int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif,
|
||||
struct sk_buff *skb);
|
||||
|
149
drivers/net/wireless/ath/wcn36xx/testmode.c
Normal file
149
drivers/net/wireless/ath/wcn36xx/testmode.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <net/netlink.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include "wcn36xx.h"
|
||||
|
||||
#include "testmode.h"
|
||||
#include "testmode_i.h"
|
||||
#include "hal.h"
|
||||
#include "smd.h"
|
||||
|
||||
static const struct nla_policy wcn36xx_tm_policy[WCN36XX_TM_ATTR_MAX + 1] = {
|
||||
[WCN36XX_TM_ATTR_CMD] = { .type = NLA_U16 },
|
||||
[WCN36XX_TM_ATTR_DATA] = { .type = NLA_BINARY,
|
||||
.len = WCN36XX_TM_DATA_MAX_LEN },
|
||||
};
|
||||
|
||||
struct build_release_number {
|
||||
u16 drv_major;
|
||||
u16 drv_minor;
|
||||
u16 drv_patch;
|
||||
u16 drv_build;
|
||||
u16 ptt_max;
|
||||
u16 ptt_min;
|
||||
u16 fw_ver;
|
||||
} __packed;
|
||||
|
||||
static int wcn36xx_tm_cmd_ptt(struct wcn36xx *wcn, struct ieee80211_vif *vif,
|
||||
struct nlattr *tb[])
|
||||
{
|
||||
int ret = 0, buf_len;
|
||||
void *buf;
|
||||
struct ftm_rsp_msg *msg, *rsp = NULL;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!tb[WCN36XX_TM_ATTR_DATA])
|
||||
return -EINVAL;
|
||||
|
||||
buf = nla_data(tb[WCN36XX_TM_ATTR_DATA]);
|
||||
buf_len = nla_len(tb[WCN36XX_TM_ATTR_DATA]);
|
||||
msg = (struct ftm_rsp_msg *)buf;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
|
||||
"testmode cmd wmi msg_id 0x%04X msg_len %d buf %pK buf_len %d\n",
|
||||
msg->msg_id, msg->msg_body_length,
|
||||
buf, buf_len);
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "REQ ", buf, buf_len);
|
||||
|
||||
if (msg->msg_id == MSG_GET_BUILD_RELEASE_NUMBER) {
|
||||
struct build_release_number *body =
|
||||
(struct build_release_number *)
|
||||
msg->msg_response;
|
||||
|
||||
body->drv_major = wcn->fw_major;
|
||||
body->drv_minor = wcn->fw_minor;
|
||||
body->drv_patch = wcn->fw_version;
|
||||
body->drv_build = wcn->fw_revision;
|
||||
body->ptt_max = 10;
|
||||
body->ptt_min = 0;
|
||||
|
||||
rsp = msg;
|
||||
rsp->resp_status = 0;
|
||||
} else {
|
||||
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
|
||||
"PPT Request >> HAL size %d\n",
|
||||
msg->msg_body_length);
|
||||
|
||||
msg->resp_status = wcn36xx_smd_process_ptt_msg(wcn, vif, msg,
|
||||
msg->msg_body_length, (void *)(&rsp));
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
|
||||
"Response status = %d\n",
|
||||
msg->resp_status);
|
||||
if (rsp)
|
||||
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
|
||||
"PPT Response << HAL size %d\n",
|
||||
rsp->msg_body_length);
|
||||
}
|
||||
|
||||
if (!rsp) {
|
||||
rsp = msg;
|
||||
wcn36xx_warn("No response! Echoing request with response status %d\n",
|
||||
rsp->resp_status);
|
||||
}
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "RSP ",
|
||||
rsp, rsp->msg_body_length);
|
||||
|
||||
skb = cfg80211_testmode_alloc_reply_skb(wcn->hw->wiphy,
|
||||
nla_total_size(msg->msg_body_length));
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put(skb, WCN36XX_TM_ATTR_DATA, rsp->msg_body_length, rsp);
|
||||
if (ret) {
|
||||
kfree_skb(skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = cfg80211_testmode_reply(skb);
|
||||
|
||||
out:
|
||||
if (rsp != msg)
|
||||
kfree(rsp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
void *data, int len)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct nlattr *tb[WCN36XX_TM_ATTR_MAX + 1];
|
||||
int ret = 0;
|
||||
unsigned short attr;
|
||||
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "Data:", data, len);
|
||||
ret = nla_parse(tb, WCN36XX_TM_ATTR_MAX, data, len,
|
||||
wcn36xx_tm_policy, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!tb[WCN36XX_TM_ATTR_CMD])
|
||||
return -EINVAL;
|
||||
|
||||
attr = nla_get_u16(tb[WCN36XX_TM_ATTR_CMD]);
|
||||
|
||||
if (attr != WCN36XX_TM_CMD_PTT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return wcn36xx_tm_cmd_ptt(wcn, vif, tb);
|
||||
}
|
46
drivers/net/wireless/ath/wcn36xx/testmode.h
Normal file
46
drivers/net/wireless/ath/wcn36xx/testmode.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "wcn36xx.h"
|
||||
|
||||
struct ftm_rsp_msg {
|
||||
u16 msg_id;
|
||||
u16 msg_body_length;
|
||||
u32 resp_status;
|
||||
u8 msg_response[0];
|
||||
} __packed;
|
||||
|
||||
/* The request buffer of FTM which contains a byte of command and the request */
|
||||
struct ftm_payload {
|
||||
u16 ftm_cmd_type;
|
||||
struct ftm_rsp_msg ftm_cmd_msg;
|
||||
} __packed;
|
||||
|
||||
#define MSG_GET_BUILD_RELEASE_NUMBER 0x32A2
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
void *data, int len);
|
||||
|
||||
#else
|
||||
static inline int wcn36xx_tm_cmd(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void *data, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
29
drivers/net/wireless/ath/wcn36xx/testmode_i.h
Normal file
29
drivers/net/wireless/ath/wcn36xx/testmode_i.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define WCN36XX_TM_DATA_MAX_LEN 5000
|
||||
|
||||
enum wcn36xx_tm_attr {
|
||||
__WCN36XX_TM_ATTR_INVALID = 0,
|
||||
WCN36XX_TM_ATTR_CMD = 1,
|
||||
WCN36XX_TM_ATTR_DATA = 2,
|
||||
|
||||
/* keep last */
|
||||
__WCN36XX_TM_ATTR_AFTER_LAST,
|
||||
WCN36XX_TM_ATTR_MAX = __WCN36XX_TM_ATTR_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
#define WCN36XX_TM_CMD_PTT 3
|
@ -50,6 +50,8 @@ enum wcn36xx_debug_mask {
|
||||
WCN36XX_DBG_BEACON_DUMP = 0x00001000,
|
||||
WCN36XX_DBG_PMC = 0x00002000,
|
||||
WCN36XX_DBG_PMC_DUMP = 0x00004000,
|
||||
WCN36XX_DBG_TESTMODE = 0x00008000,
|
||||
WCN36XX_DBG_TESTMODE_DUMP = 0x00010000,
|
||||
WCN36XX_DBG_ANY = 0xffffffff,
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ config WIL6210_TRACING
|
||||
bool "wil6210 tracing support"
|
||||
depends on WIL6210
|
||||
depends on EVENT_TRACING
|
||||
default y
|
||||
default n
|
||||
---help---
|
||||
Say Y here to enable tracepoints for the wil6210 driver
|
||||
using the kernel tracing infrastructure. Select this
|
||||
|
@ -276,6 +276,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
|
||||
struct wil_net_stats *stats = &wil->sta[cid].stats;
|
||||
int rc;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd),
|
||||
WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
|
||||
if (rc)
|
||||
@ -1081,17 +1083,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
u64 *cookie)
|
||||
{
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len, total;
|
||||
size_t len = params->len;
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
|
||||
int rc;
|
||||
bool tx_status = false;
|
||||
struct ieee80211_mgmt *mgmt_frame = (void *)buf;
|
||||
struct wmi_sw_tx_req_cmd *cmd;
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_sw_tx_complete_event evt;
|
||||
} __packed evt;
|
||||
bool tx_status;
|
||||
|
||||
/* Note, currently we do not support the "wait" parameter, user-space
|
||||
* must call remain_on_channel before mgmt_tx or listen on a channel
|
||||
@ -1100,34 +1096,9 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
* different from currently "listened" channel and fail if it is.
|
||||
*/
|
||||
|
||||
wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid);
|
||||
wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
|
||||
len, true);
|
||||
rc = wmi_mgmt_tx(vif, buf, len);
|
||||
tx_status = (rc == 0);
|
||||
|
||||
if (len < sizeof(struct ieee80211_hdr_3addr))
|
||||
return -EINVAL;
|
||||
|
||||
total = sizeof(*cmd) + len;
|
||||
if (total < len)
|
||||
return -EINVAL;
|
||||
|
||||
cmd = kmalloc(total, GFP_KERNEL);
|
||||
if (!cmd) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
|
||||
cmd->len = cpu_to_le16(len);
|
||||
memcpy(cmd->payload, buf, len);
|
||||
|
||||
rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total,
|
||||
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
|
||||
if (rc == 0)
|
||||
tx_status = !evt.evt.status;
|
||||
|
||||
kfree(cmd);
|
||||
out:
|
||||
cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
|
||||
tx_status, GFP_KERNEL);
|
||||
return rc;
|
||||
@ -2277,7 +2248,9 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_get_rf_sector_params_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
|
||||
};
|
||||
struct sk_buff *msg;
|
||||
struct nlattr *nl_cfgs, *nl_cfg;
|
||||
u32 i;
|
||||
@ -2323,7 +2296,6 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
|
||||
cmd.sector_idx = cpu_to_le16(sector_index);
|
||||
cmd.sector_type = sector_type;
|
||||
cmd.rf_modules_vec = rf_modules_vec & 0xFF;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
|
||||
&reply, sizeof(reply),
|
||||
@ -2398,7 +2370,9 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_set_rf_sector_params_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
|
||||
};
|
||||
struct nlattr *nl_cfg;
|
||||
struct wmi_rf_sector_info *si;
|
||||
|
||||
@ -2481,7 +2455,6 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
cmd.rf_modules_vec = rf_modules_vec & 0xFF;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
|
||||
&reply, sizeof(reply),
|
||||
@ -2505,7 +2478,9 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_get_selected_rf_sector_index_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
|
||||
};
|
||||
struct sk_buff *msg;
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
|
||||
@ -2545,7 +2520,6 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cid = (u8)cid;
|
||||
cmd.sector_type = sector_type;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
|
||||
@ -2586,14 +2560,15 @@ static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_set_selected_rf_sector_index_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
|
||||
};
|
||||
int rc;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.sector_idx = cpu_to_le16(sector_index);
|
||||
cmd.sector_type = sector_type;
|
||||
cmd.cid = (u8)cid;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
|
||||
|
@ -1078,6 +1078,8 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data)
|
||||
struct wmi_notify_req_done_event evt;
|
||||
} __packed reply;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
|
||||
u32 status;
|
||||
|
||||
@ -1383,8 +1385,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
|
||||
u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
|
||||
unsigned long long drop_dup = r->drop_dup, drop_old = r->drop_old;
|
||||
|
||||
seq_printf(s, "([%2d] %3d TU) 0x%03x [", r->buf_size, r->timeout,
|
||||
r->head_seq_num);
|
||||
seq_printf(s, "([%2d]) 0x%03x [", r->buf_size, r->head_seq_num);
|
||||
for (i = 0; i < r->buf_size; i++) {
|
||||
if (i == index)
|
||||
seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|');
|
||||
|
@ -342,6 +342,8 @@ void wil_disconnect_worker(struct work_struct *work)
|
||||
/* already disconnected */
|
||||
return;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0,
|
||||
WMI_DISCONNECT_EVENTID, &reply, sizeof(reply),
|
||||
WIL6210_DISCONNECT_TO_MS);
|
||||
|
@ -457,16 +457,16 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
||||
ndev = vif_to_ndev(vif);
|
||||
/* during unregister_netdevice cfg80211_leave may perform operations
|
||||
* such as stop AP, disconnect, so we only clear the VIF afterwards
|
||||
*/
|
||||
unregister_netdevice(ndev);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
||||
if (any_active && vif->mid != 0)
|
||||
wmi_port_delete(wil, vif->mid);
|
||||
|
||||
|
@ -206,7 +206,6 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
|
||||
|
||||
/* put the frame in the reordering buffer */
|
||||
r->reorder_buf[index] = skb;
|
||||
r->reorder_time[index] = jiffies;
|
||||
r->stored_mpdu_num++;
|
||||
wil_reorder_release(ndev, r);
|
||||
|
||||
@ -252,11 +251,8 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
|
||||
|
||||
r->reorder_buf =
|
||||
kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL);
|
||||
r->reorder_time =
|
||||
kcalloc(size, sizeof(unsigned long), GFP_KERNEL);
|
||||
if (!r->reorder_buf || !r->reorder_time) {
|
||||
if (!r->reorder_buf) {
|
||||
kfree(r->reorder_buf);
|
||||
kfree(r->reorder_time);
|
||||
kfree(r);
|
||||
return NULL;
|
||||
}
|
||||
@ -286,7 +282,6 @@ void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
|
||||
kfree_skb(r->reorder_buf[i]);
|
||||
|
||||
kfree(r->reorder_buf);
|
||||
kfree(r->reorder_time);
|
||||
kfree(r);
|
||||
}
|
||||
|
||||
|
@ -652,8 +652,8 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
|
||||
v->swtail = next_tail) {
|
||||
rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom);
|
||||
if (unlikely(rc)) {
|
||||
wil_err(wil, "Error %d in wil_rx_refill[%d]\n",
|
||||
rc, v->swtail);
|
||||
wil_err_ratelimited(wil, "Error %d in rx refill[%d]\n",
|
||||
rc, v->swtail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -963,7 +963,9 @@ int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_vring_cfg_done_event cmd;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.cmd = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
struct vring *vring = &wil->vring_tx[id];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[id];
|
||||
|
||||
@ -1045,7 +1047,9 @@ int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_vring_cfg_done_event cmd;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.cmd = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
struct vring *vring = &wil->vring_tx[id];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[id];
|
||||
|
||||
|
@ -493,38 +493,28 @@ struct pci_dev;
|
||||
* struct tid_ampdu_rx - TID aggregation information (Rx).
|
||||
*
|
||||
* @reorder_buf: buffer to reorder incoming aggregated MPDUs
|
||||
* @reorder_time: jiffies when skb was added
|
||||
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
|
||||
* @reorder_timer: releases expired frames from the reorder buffer.
|
||||
* @last_rx: jiffies of last rx activity
|
||||
* @head_seq_num: head sequence number in reordering buffer.
|
||||
* @stored_mpdu_num: number of MPDUs in reordering buffer
|
||||
* @ssn: Starting Sequence Number expected to be aggregated.
|
||||
* @buf_size: buffer size for incoming A-MPDUs
|
||||
* @timeout: reset timer value (in TUs).
|
||||
* @ssn_last_drop: SSN of the last dropped frame
|
||||
* @total: total number of processed incoming frames
|
||||
* @drop_dup: duplicate frames dropped for this reorder buffer
|
||||
* @drop_old: old frames dropped for this reorder buffer
|
||||
* @dialog_token: dialog token for aggregation session
|
||||
* @first_time: true when this buffer used 1-st time
|
||||
*/
|
||||
struct wil_tid_ampdu_rx {
|
||||
struct sk_buff **reorder_buf;
|
||||
unsigned long *reorder_time;
|
||||
struct timer_list session_timer;
|
||||
struct timer_list reorder_timer;
|
||||
unsigned long last_rx;
|
||||
u16 head_seq_num;
|
||||
u16 stored_mpdu_num;
|
||||
u16 ssn;
|
||||
u16 buf_size;
|
||||
u16 timeout;
|
||||
u16 ssn_last_drop;
|
||||
unsigned long long total; /* frames processed */
|
||||
unsigned long long drop_dup;
|
||||
unsigned long long drop_old;
|
||||
u8 dialog_token;
|
||||
bool first_time; /* is it 1-st time this buffer used? */
|
||||
};
|
||||
|
||||
@ -986,7 +976,7 @@ int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
|
||||
int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len);
|
||||
void wmi_recv_cmd(struct wil6210_priv *wil);
|
||||
int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len,
|
||||
u16 reply_id, void *reply, u8 reply_size, int to_msec);
|
||||
u16 reply_id, void *reply, u16 reply_size, int to_msec);
|
||||
void wmi_event_worker(struct work_struct *work);
|
||||
void wmi_event_flush(struct wil6210_priv *wil);
|
||||
int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid);
|
||||
@ -1150,5 +1140,6 @@ void wil6210_clear_halp(struct wil6210_priv *wil);
|
||||
int wmi_start_sched_scan(struct wil6210_priv *wil,
|
||||
struct cfg80211_sched_scan_request *request);
|
||||
int wmi_stop_sched_scan(struct wil6210_priv *wil);
|
||||
int wmi_mgmt_tx(struct wil6210_vif *vif, const u8 *buf, size_t len);
|
||||
|
||||
#endif /* __WIL6210_H__ */
|
||||
|
@ -1423,7 +1423,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
|
||||
}
|
||||
|
||||
int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len,
|
||||
u16 reply_id, void *reply, u8 reply_size, int to_msec)
|
||||
u16 reply_id, void *reply, u16 reply_size, int to_msec)
|
||||
{
|
||||
int rc;
|
||||
unsigned long remain;
|
||||
@ -1516,7 +1516,9 @@ int wmi_led_cfg(struct wil6210_priv *wil, bool enable)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_led_cfg_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = cpu_to_le32(WMI_FW_STATUS_FAILURE)},
|
||||
};
|
||||
|
||||
if (led_id == WIL_LED_INVALID_ID)
|
||||
goto out;
|
||||
@ -1561,13 +1563,17 @@ int wmi_pcp_start(struct wil6210_vif *vif,
|
||||
.pcp_max_assoc_sta = max_assoc_sta,
|
||||
.hidden_ssid = hidden_ssid,
|
||||
.is_go = is_go,
|
||||
.disable_ap_sme = disable_ap_sme,
|
||||
.ap_sme_offload_mode = disable_ap_sme ?
|
||||
WMI_AP_SME_OFFLOAD_PARTIAL :
|
||||
WMI_AP_SME_OFFLOAD_FULL,
|
||||
.abft_len = wil->abft_len,
|
||||
};
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_pcp_started_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
if (!vif->privacy)
|
||||
cmd.disable_sec = 1;
|
||||
@ -1581,7 +1587,7 @@ int wmi_pcp_start(struct wil6210_vif *vif,
|
||||
}
|
||||
|
||||
if (disable_ap_sme &&
|
||||
!test_bit(WMI_FW_CAPABILITY_DISABLE_AP_SME,
|
||||
!test_bit(WMI_FW_CAPABILITY_AP_SME_OFFLOAD_PARTIAL,
|
||||
wil->fw_capabilities)) {
|
||||
wil_err(wil, "disable_ap_sme not supported by FW\n");
|
||||
return -EOPNOTSUPP;
|
||||
@ -1644,6 +1650,8 @@ int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid)
|
||||
} __packed reply;
|
||||
int len; /* reply.cmd.ssid_len in CPU order */
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
rc = wmi_call(wil, WMI_GET_SSID_CMDID, vif->mid, NULL, 0,
|
||||
WMI_GET_SSID_EVENTID, &reply, sizeof(reply), 20);
|
||||
if (rc)
|
||||
@ -1679,6 +1687,8 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel)
|
||||
struct wmi_set_pcp_channel_cmd cmd;
|
||||
} __packed reply;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, vif->mid, NULL, 0,
|
||||
WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20);
|
||||
if (rc)
|
||||
@ -1704,7 +1714,9 @@ int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_p2p_cfg_done_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n");
|
||||
|
||||
@ -1725,7 +1737,9 @@ int wmi_start_listen(struct wil6210_vif *vif)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_listen_started_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n");
|
||||
|
||||
@ -1747,7 +1761,9 @@ int wmi_start_search(struct wil6210_vif *vif)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_search_started_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n");
|
||||
|
||||
@ -1873,7 +1889,9 @@ int wmi_rxon(struct wil6210_priv *wil, bool on)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_listen_started_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_info(wil, "(%s)\n", on ? "on" : "off");
|
||||
|
||||
@ -1915,6 +1933,8 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
|
||||
} __packed evt;
|
||||
int rc;
|
||||
|
||||
memset(&evt, 0, sizeof(evt));
|
||||
|
||||
if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
|
||||
struct ieee80211_channel *ch = wil->monitor_chandef.chan;
|
||||
|
||||
@ -1944,14 +1964,14 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
|
||||
rc = -EINVAL;
|
||||
|
||||
vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
|
||||
|
||||
wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n",
|
||||
le32_to_cpu(evt.evt.status), vring->hwtail);
|
||||
|
||||
if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
|
||||
rc = -EINVAL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1969,6 +1989,8 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
|
||||
struct wmi_temp_sense_done_event evt;
|
||||
} __packed reply;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, vif->mid, &cmd, sizeof(cmd),
|
||||
WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100);
|
||||
if (rc)
|
||||
@ -2001,6 +2023,7 @@ int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
|
||||
|
||||
wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
vif->locally_generated_disc = true;
|
||||
if (del_sta) {
|
||||
ether_addr_copy(del_sta_cmd.dst_mac, mac);
|
||||
@ -2099,7 +2122,9 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_rcp_addba_resp_sent_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = cpu_to_le16(WMI_FW_STATUS_FAILURE)},
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil,
|
||||
"ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n",
|
||||
@ -2132,13 +2157,13 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_ps_dev_profile_cfg_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR)},
|
||||
};
|
||||
u32 status;
|
||||
|
||||
wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile);
|
||||
|
||||
reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR);
|
||||
|
||||
rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply),
|
||||
@ -2167,15 +2192,15 @@ int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_set_mgmt_retry_limit_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "Setting mgmt retry short %d\n", retry_short);
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
reply.evt.status = WMI_FW_STATUS_FAILURE;
|
||||
|
||||
rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
|
||||
@ -2206,7 +2231,7 @@ int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
|
||||
if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
reply.evt.mgmt_retry_limit = 0;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, vif->mid, NULL, 0,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
|
||||
100);
|
||||
@ -2289,14 +2314,15 @@ int wmi_suspend(struct wil6210_priv *wil)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_traffic_suspend_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE},
|
||||
};
|
||||
|
||||
u32 suspend_to = WIL_WAIT_FOR_SUSPEND_RESUME_COMP;
|
||||
|
||||
wil->suspend_resp_rcvd = false;
|
||||
wil->suspend_resp_comp = false;
|
||||
|
||||
reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE;
|
||||
|
||||
rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply),
|
||||
@ -2372,10 +2398,11 @@ int wmi_resume(struct wil6210_priv *wil)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_traffic_resume_event evt;
|
||||
} __packed reply;
|
||||
|
||||
reply.evt.status = WMI_TRAFFIC_RESUME_FAILED;
|
||||
reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_TRAFFIC_RESUME_FAILED,
|
||||
.resume_triggers =
|
||||
cpu_to_le32(WMI_RESUME_TRIGGER_UNKNOWN)},
|
||||
};
|
||||
|
||||
rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, vif->mid, NULL, 0,
|
||||
WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply),
|
||||
@ -2401,7 +2428,9 @@ int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_port_allocated_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_misc(wil, "port allocate, mid %d iftype %d, mac %pM\n",
|
||||
mid, iftype, mac);
|
||||
@ -2426,8 +2455,6 @@ int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reply.evt.status = WMI_FW_STATUS_FAILURE;
|
||||
|
||||
rc = wmi_call(wil, WMI_PORT_ALLOCATE_CMDID, mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_PORT_ALLOCATED_EVENTID, &reply,
|
||||
@ -2454,12 +2481,12 @@ int wmi_port_delete(struct wil6210_priv *wil, u8 mid)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_port_deleted_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
wil_dbg_misc(wil, "port delete, mid %d\n", mid);
|
||||
|
||||
reply.evt.status = WMI_FW_STATUS_FAILURE;
|
||||
|
||||
rc = wmi_call(wil, WMI_PORT_DELETE_CMDID, mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_PORT_DELETED_EVENTID, &reply,
|
||||
@ -2716,7 +2743,9 @@ int wmi_start_sched_scan(struct wil6210_priv *wil,
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_start_sched_scan_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.result = WMI_PNO_REJECT},
|
||||
};
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
@ -2732,8 +2761,6 @@ int wmi_start_sched_scan(struct wil6210_priv *wil,
|
||||
wmi_sched_scan_set_plans(wil, &cmd,
|
||||
request->scan_plans, request->n_scan_plans);
|
||||
|
||||
reply.evt.result = WMI_PNO_REJECT;
|
||||
|
||||
rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd),
|
||||
WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply),
|
||||
@ -2757,13 +2784,13 @@ int wmi_stop_sched_scan(struct wil6210_priv *wil)
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_stop_sched_scan_event evt;
|
||||
} __packed reply;
|
||||
} __packed reply = {
|
||||
.evt = {.result = WMI_PNO_REJECT},
|
||||
};
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
reply.evt.result = WMI_PNO_REJECT;
|
||||
|
||||
rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, vif->mid, NULL, 0,
|
||||
WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply),
|
||||
WIL_WMI_CALL_GENERAL_TO_MS);
|
||||
@ -2778,3 +2805,50 @@ int wmi_stop_sched_scan(struct wil6210_priv *wil)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmi_mgmt_tx(struct wil6210_vif *vif, const u8 *buf, size_t len)
|
||||
{
|
||||
size_t total;
|
||||
struct wil6210_priv *wil = vif_to_wil(vif);
|
||||
struct ieee80211_mgmt *mgmt_frame = (void *)buf;
|
||||
struct wmi_sw_tx_req_cmd *cmd;
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
struct wmi_sw_tx_complete_event evt;
|
||||
} __packed evt = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid);
|
||||
wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
|
||||
len, true);
|
||||
|
||||
if (len < sizeof(struct ieee80211_hdr_3addr))
|
||||
return -EINVAL;
|
||||
|
||||
total = sizeof(*cmd) + len;
|
||||
if (total < len) {
|
||||
wil_err(wil, "mgmt_tx invalid len %zu\n", len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd = kmalloc(total, GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
|
||||
cmd->len = cpu_to_le16(len);
|
||||
memcpy(cmd->payload, buf, len);
|
||||
|
||||
rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total,
|
||||
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
|
||||
if (!rc && evt.evt.status != WMI_FW_STATUS_SUCCESS) {
|
||||
wil_err(wil, "mgmt_tx failed with status %d\n", evt.evt.status);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2006-2012 Wilocity
|
||||
*
|
||||
@ -29,8 +30,6 @@
|
||||
#ifndef __WILOCITY_WMI_H__
|
||||
#define __WILOCITY_WMI_H__
|
||||
|
||||
/* General */
|
||||
#define WMI_MAX_ASSOC_STA (8)
|
||||
#define WMI_DEFAULT_ASSOC_STA (1)
|
||||
#define WMI_MAC_LEN (6)
|
||||
#define WMI_PROX_RANGE_NUM (3)
|
||||
@ -41,6 +40,19 @@
|
||||
#define WMI_RF_ETYPE_LENGTH (3)
|
||||
#define WMI_RF_RX2TX_LENGTH (3)
|
||||
#define WMI_RF_ETYPE_VAL_PER_RANGE (5)
|
||||
/* DTYPE configuration array size
|
||||
* must always be kept equal to (WMI_RF_DTYPE_LENGTH+1)
|
||||
*/
|
||||
#define WMI_RF_DTYPE_CONF_LENGTH (4)
|
||||
/* ETYPE configuration array size
|
||||
* must always be kept equal to
|
||||
* (WMI_RF_ETYPE_LENGTH+WMI_RF_ETYPE_VAL_PER_RANGE)
|
||||
*/
|
||||
#define WMI_RF_ETYPE_CONF_LENGTH (8)
|
||||
/* RX2TX configuration array size
|
||||
* must always be kept equal to (WMI_RF_RX2TX_LENGTH+1)
|
||||
*/
|
||||
#define WMI_RF_RX2TX_CONF_LENGTH (4)
|
||||
|
||||
/* Mailbox interface
|
||||
* used for commands and events
|
||||
@ -61,7 +73,7 @@ enum wmi_fw_capability {
|
||||
WMI_FW_CAPABILITY_PS_CONFIG = 1,
|
||||
WMI_FW_CAPABILITY_RF_SECTORS = 2,
|
||||
WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
|
||||
WMI_FW_CAPABILITY_DISABLE_AP_SME = 4,
|
||||
WMI_FW_CAPABILITY_AP_SME_OFFLOAD_PARTIAL = 4,
|
||||
WMI_FW_CAPABILITY_WMI_ONLY = 5,
|
||||
WMI_FW_CAPABILITY_THERMAL_THROTTLING = 7,
|
||||
WMI_FW_CAPABILITY_D3_SUSPEND = 8,
|
||||
@ -73,6 +85,7 @@ enum wmi_fw_capability {
|
||||
WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP = 14,
|
||||
WMI_FW_CAPABILITY_PNO = 15,
|
||||
WMI_FW_CAPABILITY_REF_CLOCK_CONTROL = 18,
|
||||
WMI_FW_CAPABILITY_AP_SME_OFFLOAD_NONE = 19,
|
||||
WMI_FW_CAPABILITY_MAX,
|
||||
};
|
||||
|
||||
@ -164,12 +177,14 @@ enum wmi_command_id {
|
||||
WMI_SET_ACTIVE_SILENT_RSSI_TABLE_CMDID = 0x85C,
|
||||
WMI_RF_PWR_ON_DELAY_CMDID = 0x85D,
|
||||
WMI_SET_HIGH_POWER_TABLE_PARAMS_CMDID = 0x85E,
|
||||
WMI_FIXED_SCHEDULING_UL_CONFIG_CMDID = 0x85F,
|
||||
/* Performance monitoring commands */
|
||||
WMI_BF_CTRL_CMDID = 0x862,
|
||||
WMI_NOTIFY_REQ_CMDID = 0x863,
|
||||
WMI_GET_STATUS_CMDID = 0x864,
|
||||
WMI_GET_RF_STATUS_CMDID = 0x866,
|
||||
WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
|
||||
WMI_VRING_SWITCH_TIMING_CONFIG_CMDID = 0x868,
|
||||
WMI_UNIT_TEST_CMDID = 0x900,
|
||||
WMI_FLASH_READ_CMDID = 0x902,
|
||||
WMI_FLASH_WRITE_CMDID = 0x903,
|
||||
@ -202,6 +217,7 @@ enum wmi_command_id {
|
||||
WMI_GET_THERMAL_THROTTLING_CFG_CMDID = 0x941,
|
||||
/* Read Power Save profile type */
|
||||
WMI_PS_DEV_PROFILE_CFG_READ_CMDID = 0x942,
|
||||
WMI_TSF_SYNC_CMDID = 0x973,
|
||||
WMI_TOF_SESSION_START_CMDID = 0x991,
|
||||
WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
|
||||
WMI_TOF_SET_LCR_CMDID = 0x993,
|
||||
@ -218,11 +234,16 @@ enum wmi_command_id {
|
||||
WMI_PRIO_TX_SECTORS_ORDER_CMDID = 0x9A5,
|
||||
WMI_PRIO_TX_SECTORS_NUMBER_CMDID = 0x9A6,
|
||||
WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_CMDID = 0x9A7,
|
||||
WMI_BF_CONTROL_CMDID = 0x9AA,
|
||||
WMI_SCHEDULING_SCHEME_CMDID = 0xA01,
|
||||
WMI_FIXED_SCHEDULING_CONFIG_CMDID = 0xA02,
|
||||
WMI_ENABLE_FIXED_SCHEDULING_CMDID = 0xA03,
|
||||
WMI_SET_MULTI_DIRECTED_OMNIS_CONFIG_CMDID = 0xA04,
|
||||
WMI_SET_LONG_RANGE_CONFIG_CMDID = 0xA05,
|
||||
WMI_GET_ASSOC_LIST_CMDID = 0xA06,
|
||||
WMI_GET_CCA_INDICATIONS_CMDID = 0xA07,
|
||||
WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_CMDID = 0xA08,
|
||||
WMI_INTERNAL_FW_IOCTL_CMDID = 0xA0B,
|
||||
WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
|
||||
WMI_ABORT_SCAN_CMDID = 0xF007,
|
||||
WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
|
||||
@ -484,6 +505,18 @@ enum wmi_rf_mgmt_type {
|
||||
WMI_RF_MGMT_GET_STATUS = 0x02,
|
||||
};
|
||||
|
||||
/* WMI_BF_CONTROL_CMDID */
|
||||
enum wmi_bf_triggers {
|
||||
WMI_BF_TRIGGER_RS_MCS1_TH_FAILURE = 0x01,
|
||||
WMI_BF_TRIGGER_RS_MCS1_NO_BACK_FAILURE = 0x02,
|
||||
WMI_BF_TRIGGER_MAX_CTS_FAILURE_IN_TXOP = 0x04,
|
||||
WMI_BF_TRIGGER_MAX_BACK_FAILURE = 0x08,
|
||||
WMI_BF_TRIGGER_FW = 0x10,
|
||||
WMI_BF_TRIGGER_MAX_CTS_FAILURE_IN_KEEP_ALIVE = 0x20,
|
||||
WMI_BF_TRIGGER_AOA = 0x40,
|
||||
WMI_BF_TRIGGER_MAX_CTS_FAILURE_IN_UPM = 0x80,
|
||||
};
|
||||
|
||||
/* WMI_RF_MGMT_CMDID */
|
||||
struct wmi_rf_mgmt_cmd {
|
||||
__le32 rf_mgmt_type;
|
||||
@ -519,7 +552,9 @@ struct wmi_bcon_ctrl_cmd {
|
||||
u8 disable_sec;
|
||||
u8 hidden_ssid;
|
||||
u8 is_go;
|
||||
u8 reserved[2];
|
||||
/* A-BFT length override if non-0 */
|
||||
u8 abft_len;
|
||||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
/* WMI_PORT_ALLOCATE_CMDID */
|
||||
@ -584,6 +619,16 @@ struct wmi_power_mgmt_cfg_cmd {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_PCP_START_CMDID */
|
||||
enum wmi_ap_sme_offload_mode {
|
||||
/* Full AP SME in FW */
|
||||
WMI_AP_SME_OFFLOAD_FULL = 0x00,
|
||||
/* Probe AP SME in FW */
|
||||
WMI_AP_SME_OFFLOAD_PARTIAL = 0x01,
|
||||
/* AP SME in host */
|
||||
WMI_AP_SME_OFFLOAD_NONE = 0x02,
|
||||
};
|
||||
|
||||
/* WMI_PCP_START_CMDID */
|
||||
struct wmi_pcp_start_cmd {
|
||||
__le16 bcon_interval;
|
||||
@ -593,7 +638,8 @@ struct wmi_pcp_start_cmd {
|
||||
u8 reserved0[5];
|
||||
/* A-BFT length override if non-0 */
|
||||
u8 abft_len;
|
||||
u8 disable_ap_sme;
|
||||
/* enum wmi_ap_sme_offload_mode_e */
|
||||
u8 ap_sme_offload_mode;
|
||||
u8 network_type;
|
||||
u8 channel;
|
||||
u8 disable_sec_offload;
|
||||
@ -607,6 +653,17 @@ struct wmi_sw_tx_req_cmd {
|
||||
u8 payload[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_VRING_SWITCH_TIMING_CONFIG_CMDID */
|
||||
struct wmi_vring_switch_timing_config_cmd {
|
||||
/* Set vring timing configuration:
|
||||
*
|
||||
* defined interval for vring switch
|
||||
*/
|
||||
__le32 interval_usec;
|
||||
/* vring inactivity threshold */
|
||||
__le32 idle_th_usec;
|
||||
} __packed;
|
||||
|
||||
struct wmi_sw_ring_cfg {
|
||||
__le64 ring_mem_base;
|
||||
__le16 ring_size;
|
||||
@ -642,6 +699,7 @@ enum wmi_vring_cfg_schd_params_priority {
|
||||
WMI_SCH_PRIO_HIGH = 0x01,
|
||||
};
|
||||
|
||||
#define CIDXTID_EXTENDED_CID_TID (0xFF)
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
@ -662,6 +720,9 @@ struct wmi_vring_cfg {
|
||||
struct wmi_sw_ring_cfg tx_sw_ring;
|
||||
/* 0-23 vrings */
|
||||
u8 ringid;
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 encap_trans_type;
|
||||
/* 802.3 DS cfg */
|
||||
@ -671,6 +732,11 @@ struct wmi_vring_cfg {
|
||||
u8 to_resolution;
|
||||
u8 agg_max_wsize;
|
||||
struct wmi_vring_cfg_schd schd_params;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
enum wmi_vring_cfg_cmd_action {
|
||||
@ -868,23 +934,42 @@ struct wmi_cfg_rx_chain_cmd {
|
||||
|
||||
/* WMI_RCP_ADDBA_RESP_CMDID */
|
||||
struct wmi_rcp_addba_resp_cmd {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 dialog_token;
|
||||
__le16 status_code;
|
||||
/* ieee80211_ba_parameterset field to send */
|
||||
__le16 ba_param_set;
|
||||
__le16 ba_timeout;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_RCP_DELBA_CMDID */
|
||||
struct wmi_rcp_delba_cmd {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 reserved;
|
||||
__le16 reason;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved2[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_RCP_ADDBA_REQ_CMDID */
|
||||
struct wmi_rcp_addba_req_cmd {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 dialog_token;
|
||||
/* ieee80211_ba_parameterset field as it received */
|
||||
@ -892,6 +977,11 @@ struct wmi_rcp_addba_req_cmd {
|
||||
__le16 ba_timeout;
|
||||
/* ieee80211_ba_seqstrl field as it received */
|
||||
__le16 ba_seq_ctrl;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_MAC_ADDRESS_CMDID */
|
||||
@ -902,15 +992,20 @@ struct wmi_set_mac_address_cmd {
|
||||
|
||||
/* WMI_ECHO_CMDID
|
||||
* Check FW is alive
|
||||
* WMI_DEEP_ECHO_CMDID
|
||||
* Check FW and ucode are alive
|
||||
* Returned event: WMI_ECHO_RSP_EVENTID
|
||||
* same event for both commands
|
||||
*/
|
||||
struct wmi_echo_cmd {
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
/* WMI_DEEP_ECHO_CMDID
|
||||
* Check FW and ucode are alive
|
||||
* Returned event: WMI_ECHO_RSP_EVENTID
|
||||
*/
|
||||
struct wmi_deep_echo_cmd {
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
/* WMI_RF_PWR_ON_DELAY_CMDID
|
||||
* set FW time parameters used through RF resetting
|
||||
* RF reset consists of bringing its power down for a period of time, then
|
||||
@ -928,7 +1023,7 @@ struct wmi_rf_pwr_on_delay_cmd {
|
||||
__le16 up_delay_usec;
|
||||
} __packed;
|
||||
|
||||
/* \WMI_SET_HIGH_POWER_TABLE_PARAMS_CMDID
|
||||
/* WMI_SET_HIGH_POWER_TABLE_PARAMS_CMDID
|
||||
* This API controls the Tx and Rx gain over temperature.
|
||||
* It controls the Tx D-type, Rx D-type and Rx E-type amplifiers.
|
||||
* It also controls the Tx gain index, by controlling the Rx to Tx gain index
|
||||
@ -942,25 +1037,46 @@ struct wmi_set_high_power_table_params_cmd {
|
||||
u8 tx_dtype_temp[WMI_RF_DTYPE_LENGTH];
|
||||
u8 reserved0;
|
||||
/* Tx D-type values to be used for each temperature range */
|
||||
__le32 tx_dtype_conf[WMI_RF_DTYPE_LENGTH + 1];
|
||||
__le32 tx_dtype_conf[WMI_RF_DTYPE_CONF_LENGTH];
|
||||
/* Temperature range for Tx E-type parameters */
|
||||
u8 tx_etype_temp[WMI_RF_ETYPE_LENGTH];
|
||||
u8 reserved1;
|
||||
/* Tx E-type values to be used for each temperature range.
|
||||
* The last 4 values of any range are the first 4 values of the next
|
||||
* range and so on
|
||||
*/
|
||||
__le32 tx_etype_conf[WMI_RF_ETYPE_CONF_LENGTH];
|
||||
/* Temperature range for Rx D-type parameters */
|
||||
u8 rx_dtype_temp[WMI_RF_DTYPE_LENGTH];
|
||||
u8 reserved1;
|
||||
u8 reserved2;
|
||||
/* Rx D-type values to be used for each temperature range */
|
||||
__le32 rx_dtype_conf[WMI_RF_DTYPE_LENGTH + 1];
|
||||
__le32 rx_dtype_conf[WMI_RF_DTYPE_CONF_LENGTH];
|
||||
/* Temperature range for Rx E-type parameters */
|
||||
u8 rx_etype_temp[WMI_RF_ETYPE_LENGTH];
|
||||
u8 reserved2;
|
||||
u8 reserved3;
|
||||
/* Rx E-type values to be used for each temperature range.
|
||||
* The last 4 values of any range are the first 4 values of the next
|
||||
* range and so on
|
||||
*/
|
||||
__le32 rx_etype_conf[WMI_RF_ETYPE_VAL_PER_RANGE + WMI_RF_ETYPE_LENGTH];
|
||||
__le32 rx_etype_conf[WMI_RF_ETYPE_CONF_LENGTH];
|
||||
/* Temperature range for rx_2_tx_offs parameters */
|
||||
u8 rx_2_tx_temp[WMI_RF_RX2TX_LENGTH];
|
||||
u8 reserved3;
|
||||
u8 reserved4;
|
||||
/* Rx to Tx gain index offset */
|
||||
s8 rx_2_tx_offs[WMI_RF_RX2TX_LENGTH + 1];
|
||||
s8 rx_2_tx_offs[WMI_RF_RX2TX_CONF_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/* WMI_FIXED_SCHEDULING_UL_CONFIG_CMDID
|
||||
* This API sets rd parameter per mcs.
|
||||
* Relevant only in Fixed Scheduling mode.
|
||||
* Returned event: WMI_FIXED_SCHEDULING_UL_CONFIG_EVENTID
|
||||
*/
|
||||
struct wmi_fixed_scheduling_ul_config_cmd {
|
||||
/* Use mcs -1 to set for every mcs */
|
||||
s8 mcs;
|
||||
/* Number of frames with rd bit set in a single virtual slot */
|
||||
u8 rd_count_per_slot;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* CMD: WMI_RF_XPM_READ_CMDID */
|
||||
@ -1267,6 +1383,93 @@ struct wmi_set_long_range_config_complete_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* payload max size is 236 bytes: max event buffer size (256) - WMI headers
|
||||
* (16) - prev struct field size (4)
|
||||
*/
|
||||
#define WMI_MAX_IOCTL_PAYLOAD_SIZE (236)
|
||||
#define WMI_MAX_IOCTL_REPLY_PAYLOAD_SIZE (236)
|
||||
#define WMI_MAX_INTERNAL_EVENT_PAYLOAD_SIZE (236)
|
||||
|
||||
enum wmi_internal_fw_ioctl_code {
|
||||
WMI_INTERNAL_FW_CODE_NONE = 0x0,
|
||||
WMI_INTERNAL_FW_CODE_QCOM = 0x1,
|
||||
};
|
||||
|
||||
/* WMI_INTERNAL_FW_IOCTL_CMDID */
|
||||
struct wmi_internal_fw_ioctl_cmd {
|
||||
/* enum wmi_internal_fw_ioctl_code */
|
||||
__le16 code;
|
||||
__le16 length;
|
||||
/* payload max size is WMI_MAX_IOCTL_PAYLOAD_SIZE
|
||||
* Must be the last member of the struct
|
||||
*/
|
||||
__le32 payload[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_INTERNAL_FW_IOCTL_EVENTID */
|
||||
struct wmi_internal_fw_ioctl_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved;
|
||||
__le16 length;
|
||||
/* payload max size is WMI_MAX_IOCTL_REPLY_PAYLOAD_SIZE
|
||||
* Must be the last member of the struct
|
||||
*/
|
||||
__le32 payload[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_INTERNAL_FW_EVENT_EVENTID */
|
||||
struct wmi_internal_fw_event_event {
|
||||
__le16 id;
|
||||
__le16 length;
|
||||
/* payload max size is WMI_MAX_INTERNAL_EVENT_PAYLOAD_SIZE
|
||||
* Must be the last member of the struct
|
||||
*/
|
||||
__le32 payload[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_BF_CONTROL_CMDID */
|
||||
struct wmi_bf_control_cmd {
|
||||
/* wmi_bf_triggers */
|
||||
__le32 triggers;
|
||||
u8 cid;
|
||||
/* DISABLED = 0, ENABLED = 1 , DRY_RUN = 2 */
|
||||
u8 txss_mode;
|
||||
/* DISABLED = 0, ENABLED = 1, DRY_RUN = 2 */
|
||||
u8 brp_mode;
|
||||
/* Max cts threshold (correspond to
|
||||
* WMI_BF_TRIGGER_MAX_CTS_FAILURE_IN_TXOP)
|
||||
*/
|
||||
u8 bf_trigger_max_cts_failure_thr;
|
||||
/* Max cts threshold in dense (correspond to
|
||||
* WMI_BF_TRIGGER_MAX_CTS_FAILURE_IN_TXOP)
|
||||
*/
|
||||
u8 bf_trigger_max_cts_failure_dense_thr;
|
||||
/* Max b-ack threshold (correspond to
|
||||
* WMI_BF_TRIGGER_MAX_BACK_FAILURE)
|
||||
*/
|
||||
u8 bf_trigger_max_back_failure_thr;
|
||||
/* Max b-ack threshold in dense (correspond to
|
||||
* WMI_BF_TRIGGER_MAX_BACK_FAILURE)
|
||||
*/
|
||||
u8 bf_trigger_max_back_failure_dense_thr;
|
||||
u8 reserved0;
|
||||
/* Wrong sectors threshold */
|
||||
__le32 wrong_sector_bis_thr;
|
||||
/* BOOL to enable/disable long term trigger */
|
||||
u8 long_term_enable;
|
||||
/* 1 = Update long term thresholds from the long_term_mbps_th_tbl and
|
||||
* long_term_trig_timeout_per_mcs arrays, 0 = Ignore
|
||||
*/
|
||||
u8 long_term_update_thr;
|
||||
/* Long term throughput threshold [Mbps] */
|
||||
u8 long_term_mbps_th_tbl[WMI_NUM_MCS];
|
||||
u8 reserved1;
|
||||
/* Long term timeout threshold table [msec] */
|
||||
__le16 long_term_trig_timeout_per_mcs[WMI_NUM_MCS];
|
||||
u8 reserved2[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI Events
|
||||
* List of Events (target to host)
|
||||
*/
|
||||
@ -1325,6 +1528,7 @@ enum wmi_event_id {
|
||||
WMI_SET_SILENT_RSSI_TABLE_DONE_EVENTID = 0x185C,
|
||||
WMI_RF_PWR_ON_DELAY_RSP_EVENTID = 0x185D,
|
||||
WMI_SET_HIGH_POWER_TABLE_PARAMS_EVENTID = 0x185E,
|
||||
WMI_FIXED_SCHEDULING_UL_CONFIG_EVENTID = 0x185F,
|
||||
/* Performance monitoring events */
|
||||
WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
|
||||
WMI_WBE_LINK_DOWN_EVENTID = 0x1861,
|
||||
@ -1334,6 +1538,7 @@ enum wmi_event_id {
|
||||
WMI_VRING_EN_EVENTID = 0x1865,
|
||||
WMI_GET_RF_STATUS_EVENTID = 0x1866,
|
||||
WMI_GET_BASEBAND_TYPE_EVENTID = 0x1867,
|
||||
WMI_VRING_SWITCH_TIMING_CONFIG_EVENTID = 0x1868,
|
||||
WMI_UNIT_TEST_EVENTID = 0x1900,
|
||||
WMI_FLASH_READ_DONE_EVENTID = 0x1902,
|
||||
WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
|
||||
@ -1363,6 +1568,7 @@ enum wmi_event_id {
|
||||
WMI_GET_THERMAL_THROTTLING_CFG_EVENTID = 0x1941,
|
||||
/* return the Power Save profile */
|
||||
WMI_PS_DEV_PROFILE_CFG_READ_EVENTID = 0x1942,
|
||||
WMI_TSF_SYNC_STATUS_EVENTID = 0x1973,
|
||||
WMI_TOF_SESSION_END_EVENTID = 0x1991,
|
||||
WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992,
|
||||
WMI_TOF_SET_LCR_EVENTID = 0x1993,
|
||||
@ -1380,17 +1586,24 @@ enum wmi_event_id {
|
||||
WMI_PRIO_TX_SECTORS_ORDER_EVENTID = 0x19A5,
|
||||
WMI_PRIO_TX_SECTORS_NUMBER_EVENTID = 0x19A6,
|
||||
WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID = 0x19A7,
|
||||
WMI_BF_CONTROL_EVENTID = 0x19AA,
|
||||
WMI_SCHEDULING_SCHEME_EVENTID = 0x1A01,
|
||||
WMI_FIXED_SCHEDULING_CONFIG_COMPLETE_EVENTID = 0x1A02,
|
||||
WMI_ENABLE_FIXED_SCHEDULING_COMPLETE_EVENTID = 0x1A03,
|
||||
WMI_SET_MULTI_DIRECTED_OMNIS_CONFIG_EVENTID = 0x1A04,
|
||||
WMI_SET_LONG_RANGE_CONFIG_COMPLETE_EVENTID = 0x1A05,
|
||||
WMI_GET_ASSOC_LIST_RES_EVENTID = 0x1A06,
|
||||
WMI_GET_CCA_INDICATIONS_EVENTID = 0x1A07,
|
||||
WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_EVENTID = 0x1A08,
|
||||
WMI_INTERNAL_FW_EVENT_EVENTID = 0x1A0A,
|
||||
WMI_INTERNAL_FW_IOCTL_EVENTID = 0x1A0B,
|
||||
WMI_SET_CHANNEL_EVENTID = 0x9000,
|
||||
WMI_ASSOC_REQ_EVENTID = 0x9001,
|
||||
WMI_EAPOL_RX_EVENTID = 0x9002,
|
||||
WMI_MAC_ADDR_RESP_EVENTID = 0x9003,
|
||||
WMI_FW_VER_EVENTID = 0x9004,
|
||||
WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID = 0x9005,
|
||||
WMI_INTERNAL_FW_SET_CHANNEL = 0x9006,
|
||||
WMI_COMMAND_NOT_SUPPORTED_EVENTID = 0xFFFF,
|
||||
};
|
||||
|
||||
@ -1462,12 +1675,16 @@ enum rf_type {
|
||||
RF_UNKNOWN = 0x00,
|
||||
RF_MARLON = 0x01,
|
||||
RF_SPARROW = 0x02,
|
||||
RF_TALYNA1 = 0x03,
|
||||
RF_TALYNA2 = 0x04,
|
||||
};
|
||||
|
||||
/* WMI_GET_RF_STATUS_EVENTID */
|
||||
enum board_file_rf_type {
|
||||
BF_RF_MARLON = 0x00,
|
||||
BF_RF_SPARROW = 0x01,
|
||||
BF_RF_TALYNA1 = 0x02,
|
||||
BF_RF_TALYNA2 = 0x03,
|
||||
};
|
||||
|
||||
/* WMI_GET_RF_STATUS_EVENTID */
|
||||
@ -1507,6 +1724,7 @@ enum baseband_type {
|
||||
BASEBAND_SPARROW_M_C0 = 0x06,
|
||||
BASEBAND_SPARROW_M_D0 = 0x07,
|
||||
BASEBAND_TALYN_M_A0 = 0x08,
|
||||
BASEBAND_TALYN_M_B0 = 0x09,
|
||||
};
|
||||
|
||||
/* WMI_GET_BASEBAND_TYPE_EVENTID */
|
||||
@ -1551,7 +1769,11 @@ struct wmi_ready_event {
|
||||
u8 numof_additional_mids;
|
||||
/* rfc read calibration result. 5..15 */
|
||||
u8 rfc_read_calib_result;
|
||||
u8 reserved[3];
|
||||
/* Max associated STAs supported by FW in AP mode (default 0 means 8
|
||||
* STA)
|
||||
*/
|
||||
u8 max_assoc_sta;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_NOTIFY_REQ_DONE_EVENTID */
|
||||
@ -1666,13 +1888,13 @@ enum wmi_pno_result {
|
||||
};
|
||||
|
||||
struct wmi_start_sched_scan_event {
|
||||
/* pno_result */
|
||||
/* wmi_pno_result */
|
||||
u8 result;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
struct wmi_stop_sched_scan_event {
|
||||
/* pno_result */
|
||||
/* wmi_pno_result */
|
||||
u8 result;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
@ -1739,9 +1961,17 @@ struct wmi_ba_status_event {
|
||||
|
||||
/* WMI_DELBA_EVENTID */
|
||||
struct wmi_delba_event {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 from_initiator;
|
||||
__le16 reason;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_VRING_CFG_DONE_EVENTID */
|
||||
@ -1754,13 +1984,24 @@ struct wmi_vring_cfg_done_event {
|
||||
|
||||
/* WMI_RCP_ADDBA_RESP_SENT_EVENTID */
|
||||
struct wmi_rcp_addba_resp_sent_event {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 reserved;
|
||||
__le16 status;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved2[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_RCP_ADDBA_REQ_EVENTID */
|
||||
struct wmi_rcp_addba_req_event {
|
||||
/* Used for cid less than 8. For higher cid set
|
||||
* CIDXTID_EXTENDED_CID_TID here and use cid and tid members instead
|
||||
*/
|
||||
u8 cidxtid;
|
||||
u8 dialog_token;
|
||||
/* ieee80211_ba_parameterset as it received */
|
||||
@ -1768,6 +2009,11 @@ struct wmi_rcp_addba_req_event {
|
||||
__le16 ba_timeout;
|
||||
/* ieee80211_ba_seqstrl field as it received */
|
||||
__le16 ba_seq_ctrl;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 cid;
|
||||
/* Used when cidxtid = CIDXTID_EXTENDED_CID_TID */
|
||||
u8 tid;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_CFG_RX_CHAIN_DONE_EVENTID */
|
||||
@ -1942,6 +2188,13 @@ struct wmi_set_high_power_table_params_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_FIXED_SCHEDULING_UL_CONFIG_EVENTID */
|
||||
struct wmi_fixed_scheduling_ul_config_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_TEMP_SENSE_DONE_EVENTID
|
||||
*
|
||||
* Measure MAC and radio temperatures
|
||||
@ -2290,6 +2543,8 @@ struct wmi_link_maintain_cfg {
|
||||
__le32 bad_beacons_num_threshold;
|
||||
/* SNR limit for bad_beacons_detector */
|
||||
__le32 bad_beacons_snr_threshold_db;
|
||||
/* timeout for disassoc response frame in uSec */
|
||||
__le32 disconnect_timeout;
|
||||
} __packed;
|
||||
|
||||
/* WMI_LINK_MAINTAIN_CFG_WRITE_CMDID */
|
||||
@ -2519,6 +2774,7 @@ enum wmi_tof_session_end_status {
|
||||
WMI_TOF_SESSION_END_FAIL = 0x01,
|
||||
WMI_TOF_SESSION_END_PARAMS_ERROR = 0x02,
|
||||
WMI_TOF_SESSION_END_ABORTED = 0x03,
|
||||
WMI_TOF_SESSION_END_BUSY = 0x04,
|
||||
};
|
||||
|
||||
/* WMI_TOF_SESSION_END_EVENTID */
|
||||
@ -2925,7 +3181,40 @@ struct wmi_set_silent_rssi_table_done_event {
|
||||
__le32 table;
|
||||
} __packed;
|
||||
|
||||
/* \WMI_COMMAND_NOT_SUPPORTED_EVENTID */
|
||||
/* WMI_VRING_SWITCH_TIMING_CONFIG_EVENTID */
|
||||
struct wmi_vring_switch_timing_config_event {
|
||||
/* enum wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_GET_ASSOC_LIST_RES_EVENTID */
|
||||
struct wmi_assoc_sta_info {
|
||||
u8 mac[WMI_MAC_LEN];
|
||||
u8 omni_index_address;
|
||||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
#define WMI_GET_ASSOC_LIST_SIZE (8)
|
||||
|
||||
/* WMI_GET_ASSOC_LIST_RES_EVENTID
|
||||
* Returns up to MAX_ASSOC_STA_LIST_SIZE associated STAs
|
||||
*/
|
||||
struct wmi_get_assoc_list_res_event {
|
||||
struct wmi_assoc_sta_info assoc_sta_list[WMI_GET_ASSOC_LIST_SIZE];
|
||||
/* STA count */
|
||||
u8 count;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_BF_CONTROL_EVENTID */
|
||||
struct wmi_bf_control_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_COMMAND_NOT_SUPPORTED_EVENTID */
|
||||
struct wmi_command_not_supported_event {
|
||||
/* device id */
|
||||
u8 mid;
|
||||
@ -2936,4 +3225,62 @@ struct wmi_command_not_supported_event {
|
||||
__le16 reserved1;
|
||||
} __packed;
|
||||
|
||||
/* WMI_TSF_SYNC_CMDID */
|
||||
struct wmi_tsf_sync_cmd {
|
||||
/* The time interval to send announce frame in one BI */
|
||||
u8 interval_ms;
|
||||
/* The mcs to send announce frame */
|
||||
u8 mcs;
|
||||
u8 reserved[6];
|
||||
} __packed;
|
||||
|
||||
/* WMI_TSF_SYNC_STATUS_EVENTID */
|
||||
enum wmi_tsf_sync_status {
|
||||
WMI_TSF_SYNC_SUCCESS = 0x00,
|
||||
WMI_TSF_SYNC_FAILED = 0x01,
|
||||
WMI_TSF_SYNC_REJECTED = 0x02,
|
||||
};
|
||||
|
||||
/* WMI_TSF_SYNC_STATUS_EVENTID */
|
||||
struct wmi_tsf_sync_status_event {
|
||||
/* enum wmi_tsf_sync_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_GET_CCA_INDICATIONS_EVENTID */
|
||||
struct wmi_get_cca_indications_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
/* CCA-Energy Detect in percentage over last BI (0..100) */
|
||||
u8 cca_ed_percent;
|
||||
/* Averaged CCA-Energy Detect in percent over number of BIs (0..100) */
|
||||
u8 cca_ed_avg_percent;
|
||||
/* NAV percent over last BI (0..100) */
|
||||
u8 nav_percent;
|
||||
/* Averaged NAV percent over number of BIs (0..100) */
|
||||
u8 nav_avg_percent;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_CMDID */
|
||||
struct wmi_set_cca_indications_bi_avg_num_cmd {
|
||||
/* set the number of bis to average cca_ed (0..255) */
|
||||
u8 bi_number;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_EVENTID */
|
||||
struct wmi_set_cca_indications_bi_avg_num_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_INTERNAL_FW_SET_CHANNEL */
|
||||
struct wmi_internal_fw_set_channel_event {
|
||||
u8 channel_num;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
#endif /* __WILOCITY_WMI_H__ */
|
||||
|
@ -61,8 +61,10 @@ static int atmel_pci_probe(struct pci_dev *pdev,
|
||||
dev = init_atmel_card(pdev->irq, pdev->resource[1].start,
|
||||
ATMEL_FW_TYPE_506,
|
||||
&pdev->dev, NULL, NULL);
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
pci_disable_device(pdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
return 0;
|
||||
|
@ -1165,6 +1165,7 @@ static struct sdio_driver brcmf_sdmmc_driver = {
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.pm = &brcmf_sdio_pm_ops,
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
.coredump = brcmf_dev_coredump,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -250,6 +250,8 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
|
||||
void brcmf_detach(struct device *dev);
|
||||
/* Indication from bus module that dongle should be reset */
|
||||
void brcmf_dev_reset(struct device *dev);
|
||||
/* Request from bus module to initiate a coredump */
|
||||
void brcmf_dev_coredump(struct device *dev);
|
||||
|
||||
/* Configure the "global" bus state used by upper layers */
|
||||
void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
|
||||
|
@ -36,8 +36,6 @@ MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
||||
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include <linux/platform_data/brcmfmac.h>
|
||||
#include "fwil_types.h"
|
||||
|
||||
extern const u8 ALLFFMAC[ETH_ALEN];
|
||||
|
||||
#define BRCMF_FW_ALTPATH_LEN 256
|
||||
|
||||
/* Definitions for the module global and device specific settings are defined
|
||||
|
@ -1180,6 +1180,14 @@ void brcmf_dev_reset(struct device *dev)
|
||||
brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
|
||||
}
|
||||
|
||||
void brcmf_dev_coredump(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
|
||||
if (brcmf_debug_create_memdump(bus_if, NULL, 0) < 0)
|
||||
brcmf_dbg(TRACE, "failed to create coredump\n");
|
||||
}
|
||||
|
||||
void brcmf_detach(struct device *dev)
|
||||
{
|
||||
s32 i;
|
||||
|
@ -40,7 +40,8 @@ int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
if (!dump)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(dump, data, len);
|
||||
if (data && len > 0)
|
||||
memcpy(dump, data, len);
|
||||
err = brcmf_bus_get_memdump(bus, dump + len, ramsize);
|
||||
if (err) {
|
||||
vfree(dump);
|
||||
|
@ -165,6 +165,41 @@ static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* brcmf_feat_fwcap_debugfs_read() - expose firmware capabilities to debugfs.
|
||||
*
|
||||
* @seq: sequence for debugfs entry.
|
||||
* @data: raw data pointer.
|
||||
*/
|
||||
static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
|
||||
struct brcmf_if *ifp = brcmf_get_ifp(bus_if->drvr, 0);
|
||||
char caps[MAX_CAPS_BUFFER_SIZE + 1] = { };
|
||||
char *tmp;
|
||||
int err;
|
||||
|
||||
err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
|
||||
if (err) {
|
||||
brcmf_err("could not get firmware cap (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Put every capability in a new line */
|
||||
for (tmp = caps; *tmp; tmp++) {
|
||||
if (*tmp == ' ')
|
||||
*tmp = '\n';
|
||||
}
|
||||
|
||||
/* Usually there is a space at the end of capabilities string */
|
||||
seq_printf(seq, "%s", caps);
|
||||
/* So make sure we don't print two line breaks */
|
||||
if (tmp > caps && *(tmp - 1) != '\n')
|
||||
seq_printf(seq, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcmf_feat_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
|
||||
@ -233,6 +268,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
|
||||
void brcmf_feat_debugfs_create(struct brcmf_pub *drvr)
|
||||
{
|
||||
brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read);
|
||||
brcmf_debugfs_add_entry(drvr, "fwcap", brcmf_feat_fwcap_debugfs_read);
|
||||
}
|
||||
|
||||
bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id)
|
||||
|
@ -46,6 +46,8 @@ static const u8 brcmf_flowring_prio2fifo[] = {
|
||||
3
|
||||
};
|
||||
|
||||
static const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
|
||||
static bool
|
||||
brcmf_flowring_is_tdls_mac(struct brcmf_flowring *flow, u8 mac[ETH_ALEN])
|
||||
|
@ -182,6 +182,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
#define BRCMF_D2H_DEV_D3_ACK 0x00000001
|
||||
#define BRCMF_D2H_DEV_DS_ENTER_REQ 0x00000002
|
||||
#define BRCMF_D2H_DEV_DS_EXIT_NOTE 0x00000004
|
||||
#define BRCMF_D2H_DEV_FWHALT 0x10000000
|
||||
|
||||
#define BRCMF_H2D_HOST_D3_INFORM 0x00000001
|
||||
#define BRCMF_H2D_HOST_DS_ACK 0x00000002
|
||||
@ -717,6 +718,10 @@ static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
|
||||
devinfo->mbdata_completed = true;
|
||||
wake_up(&devinfo->mbdata_resp_wait);
|
||||
}
|
||||
if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) {
|
||||
brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n");
|
||||
brcmf_dev_coredump(&devinfo->pdev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2044,6 +2049,7 @@ static struct pci_driver brcmf_pciedrvr = {
|
||||
#ifdef CONFIG_PM
|
||||
.driver.pm = &brcmf_pciedrvr_pm,
|
||||
#endif
|
||||
.driver.coredump = brcmf_dev_coredump,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1072,8 +1072,10 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
|
||||
/* dongle indicates the firmware has halted/crashed */
|
||||
if (hmb_data & HMB_DATA_FWHALT)
|
||||
if (hmb_data & HMB_DATA_FWHALT) {
|
||||
brcmf_err("mailbox indicates firmware halted\n");
|
||||
brcmf_dev_coredump(&sdiod->func1->dev);
|
||||
}
|
||||
|
||||
/* Dongle recomposed rx frames, accept them again */
|
||||
if (hmb_data & HMB_DATA_NAKHANDLED) {
|
||||
|
@ -373,6 +373,7 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
.eeprom_params = &iwl6000_eeprom_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.csr = &iwl_csr_v1,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
|
@ -137,7 +137,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.base_params = &iwl9000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_9000, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
.dccm2_offset = IWL9000_DCCM2_OFFSET, \
|
||||
|
@ -295,6 +295,7 @@ enum iwl_rx_mpdu_status {
|
||||
IWL_RX_MPDU_STATUS_MIC_OK = BIT(6),
|
||||
IWL_RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
|
||||
IWL_RX_MPDU_STATUS_SEC_MASK = 0x7 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_UNKNOWN = IWL_RX_MPDU_STATUS_SEC_MASK,
|
||||
IWL_RX_MPDU_STATUS_SEC_NONE = 0x0 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_WEP = 0x1 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_CCM = 0x2 << 8,
|
||||
|
@ -1025,8 +1025,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
continue;
|
||||
|
||||
copy_rd->reg_rules[i].wmm_rule = d_wmm +
|
||||
(regd->reg_rules[i].wmm_rule - s_wmm) /
|
||||
sizeof(struct ieee80211_wmm_rule);
|
||||
(regd->reg_rules[i].wmm_rule - s_wmm);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -2685,7 +2685,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
/* track whether or not the station is associated */
|
||||
mvm_sta->associated = new_state >= IEEE80211_STA_ASSOC;
|
||||
mvm_sta->sta_state = new_state;
|
||||
|
||||
if (old_state == IEEE80211_STA_NOTEXIST &&
|
||||
new_state == IEEE80211_STA_NONE) {
|
||||
@ -2737,8 +2737,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
|
||||
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
|
||||
true);
|
||||
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
|
||||
ret = iwl_mvm_update_sta(mvm, vif, sta);
|
||||
} else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
new_state == IEEE80211_STA_AUTHORIZED) {
|
||||
@ -2754,8 +2753,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
/* enable beacon filtering */
|
||||
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
|
||||
|
||||
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
|
||||
false);
|
||||
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
|
||||
|
||||
ret = 0;
|
||||
} else if (old_state == IEEE80211_STA_AUTHORIZED &&
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -13,10 +14,6 @@
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
@ -651,9 +648,10 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
||||
}
|
||||
|
||||
tid_data = &mvmsta->tid_data[tid];
|
||||
if ((tid_data->state == IWL_AGG_OFF) &&
|
||||
if (mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED &&
|
||||
tid_data->state == IWL_AGG_OFF &&
|
||||
(lq_sta->tx_agg_tid_en & BIT(tid)) &&
|
||||
(tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
|
||||
tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD) {
|
||||
IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
|
||||
if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0)
|
||||
tid_data->state = IWL_AGG_QUEUED;
|
||||
@ -1257,7 +1255,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
(unsigned long)(lq_sta->last_tx +
|
||||
(IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
|
||||
IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
|
||||
iwl_mvm_rs_rate_init(mvm, sta, info->band, false);
|
||||
iwl_mvm_rs_rate_init(mvm, sta, info->band);
|
||||
return;
|
||||
}
|
||||
lq_sta->last_tx = jiffies;
|
||||
@ -2690,9 +2688,9 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
enum nl80211_band band,
|
||||
struct rs_rate *rate,
|
||||
bool init)
|
||||
struct rs_rate *rate)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
int i, nentries;
|
||||
unsigned long active_rate;
|
||||
s8 best_rssi = S8_MIN;
|
||||
@ -2754,7 +2752,8 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
|
||||
* bandwidth rate, and after authorization, when the phy context
|
||||
* is already up-to-date, re-init rs with the correct bw.
|
||||
*/
|
||||
u32 bw = init ? RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta);
|
||||
u32 bw = mvmsta->sta_state < IEEE80211_STA_AUTHORIZED ?
|
||||
RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta);
|
||||
|
||||
switch (bw) {
|
||||
case RATE_MCS_CHAN_WIDTH_40:
|
||||
@ -2839,9 +2838,9 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
|
||||
static void rs_initialize_lq(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
enum nl80211_band band,
|
||||
bool init)
|
||||
enum nl80211_band band)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_scale_tbl_info *tbl;
|
||||
struct rs_rate *rate;
|
||||
u8 active_tbl = 0;
|
||||
@ -2857,7 +2856,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
||||
tbl = &(lq_sta->lq_info[active_tbl]);
|
||||
rate = &tbl->rate;
|
||||
|
||||
rs_get_initial_rate(mvm, sta, lq_sta, band, rate, init);
|
||||
rs_get_initial_rate(mvm, sta, lq_sta, band, rate);
|
||||
rs_init_optimal_rate(mvm, sta, lq_sta);
|
||||
|
||||
WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B,
|
||||
@ -2870,7 +2869,8 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
||||
rs_set_expected_tpt_table(lq_sta, tbl);
|
||||
rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
|
||||
/* TODO restore station should remember the lq cmd */
|
||||
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
|
||||
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq,
|
||||
mvmsta->sta_state < IEEE80211_STA_AUTHORIZED);
|
||||
}
|
||||
|
||||
static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
|
||||
@ -3123,7 +3123,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
|
||||
* Called after adding a new station to initialize rate scaling
|
||||
*/
|
||||
static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
enum nl80211_band band, bool init)
|
||||
enum nl80211_band band)
|
||||
{
|
||||
int i, j;
|
||||
struct ieee80211_hw *hw = mvm->hw;
|
||||
@ -3203,7 +3203,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_mvm_reset_frame_stats(mvm);
|
||||
#endif
|
||||
rs_initialize_lq(mvm, sta, lq_sta, band, init);
|
||||
rs_initialize_lq(mvm, sta, lq_sta, band);
|
||||
}
|
||||
|
||||
static void rs_drv_rate_update(void *mvm_r,
|
||||
@ -3223,7 +3223,7 @@ static void rs_drv_rate_update(void *mvm_r,
|
||||
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
|
||||
ieee80211_stop_tx_ba_session(sta, tid);
|
||||
|
||||
iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
|
||||
iwl_mvm_rs_rate_init(mvm, sta, sband->band);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
@ -4069,12 +4069,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
|
||||
};
|
||||
|
||||
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
enum nl80211_band band, bool init)
|
||||
enum nl80211_band band)
|
||||
{
|
||||
if (iwl_mvm_has_tlc_offload(mvm))
|
||||
rs_fw_rate_init(mvm, sta, band);
|
||||
else
|
||||
rs_drv_rate_init(mvm, sta, band, init);
|
||||
rs_drv_rate_init(mvm, sta, band);
|
||||
}
|
||||
|
||||
int iwl_mvm_rate_control_register(void)
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -13,10 +14,6 @@
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
@ -410,7 +407,7 @@ struct iwl_lq_sta {
|
||||
|
||||
/* Initialize station's rate scaling information after adding station */
|
||||
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
enum nl80211_band band, bool init);
|
||||
enum nl80211_band band);
|
||||
|
||||
/* Notify RS about Tx status */
|
||||
void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
|
@ -227,12 +227,24 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *stats,
|
||||
struct iwl_rx_mpdu_desc *desc, u32 pkt_flags,
|
||||
int queue, u8 *crypt_len)
|
||||
struct ieee80211_rx_status *stats, u16 phy_info,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
u32 pkt_flags, int queue, u8 *crypt_len)
|
||||
{
|
||||
u16 status = le16_to_cpu(desc->status);
|
||||
|
||||
/*
|
||||
* Drop UNKNOWN frames in aggregation, unless in monitor mode
|
||||
* (where we don't have the keys).
|
||||
* We limit this to aggregation because in TKIP this is a valid
|
||||
* scenario, since we may not have the (correct) TTAK (phase 1
|
||||
* key) in the firmware.
|
||||
*/
|
||||
if (phy_info & IWL_RX_MPDU_PHY_AMPDU &&
|
||||
(status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
|
||||
IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on)
|
||||
return -1;
|
||||
|
||||
if (!ieee80211_has_protected(hdr->frame_control) ||
|
||||
(status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
|
||||
IWL_RX_MPDU_STATUS_SEC_NONE)
|
||||
@ -578,14 +590,10 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
|
||||
notif = (void *)pkt->data;
|
||||
internal_notif = (void *)notif->payload;
|
||||
|
||||
if (internal_notif->sync) {
|
||||
if (mvm->queue_sync_cookie != internal_notif->cookie) {
|
||||
WARN_ONCE(1,
|
||||
"Received expired RX queue sync message\n");
|
||||
return;
|
||||
}
|
||||
if (!atomic_dec_return(&mvm->queue_sync_counter))
|
||||
wake_up(&mvm->rx_sync_waitq);
|
||||
if (internal_notif->sync &&
|
||||
mvm->queue_sync_cookie != internal_notif->cookie) {
|
||||
WARN_ONCE(1, "Received expired RX queue sync message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (internal_notif->type) {
|
||||
@ -597,6 +605,10 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
|
||||
default:
|
||||
WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
|
||||
}
|
||||
|
||||
if (internal_notif->sync &&
|
||||
!atomic_dec_return(&mvm->queue_sync_counter))
|
||||
wake_up(&mvm->rx_sync_waitq);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -870,7 +882,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
|
||||
rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, desc,
|
||||
if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, phy_info, desc,
|
||||
le32_to_cpu(pkt->len_n_flags), queue,
|
||||
&crypt_len)) {
|
||||
kfree_skb(skb);
|
||||
|
@ -216,7 +216,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
|
||||
add_sta_cmd.station_flags |=
|
||||
cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
|
||||
if (mvm_sta->associated)
|
||||
if (mvm_sta->sta_state >= IEEE80211_STA_ASSOC)
|
||||
add_sta_cmd.assoc_id = cpu_to_le16(sta->aid);
|
||||
|
||||
if (sta->wme) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,11 +19,6 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
@ -35,6 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -376,6 +373,7 @@ struct iwl_mvm_rxq_dup_data {
|
||||
* tid.
|
||||
* @max_agg_bufsize: the maximal size of the AGG buffer for this station
|
||||
* @sta_type: station type
|
||||
* @sta_state: station state according to enum %ieee80211_sta_state
|
||||
* @bt_reduced_txpower: is reduced tx power enabled for this station
|
||||
* @next_status_eosp: the next reclaimed packet is a PS-Poll response and
|
||||
* we need to signal the EOSP
|
||||
@ -416,6 +414,7 @@ struct iwl_mvm_sta {
|
||||
u16 tid_disable_agg;
|
||||
u8 max_agg_bufsize;
|
||||
enum iwl_sta_type sta_type;
|
||||
enum ieee80211_sta_state sta_state;
|
||||
bool bt_reduced_txpower;
|
||||
bool next_status_eosp;
|
||||
spinlock_t lock;
|
||||
@ -441,7 +440,6 @@ struct iwl_mvm_sta {
|
||||
u16 amsdu_enabled;
|
||||
u16 max_amsdu_len;
|
||||
bool sleeping;
|
||||
bool associated;
|
||||
u8 agg_tids;
|
||||
u8 sleep_tx_count;
|
||||
u8 avg_energy;
|
||||
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(C) 2018 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,9 +19,7 @@
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
* along with this program.
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
@ -33,6 +32,7 @@
|
||||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(C) 2018 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -188,8 +188,14 @@ void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
if (tdls_sta_cnt == 1 && sta_added)
|
||||
iwl_mvm_power_update_mac(mvm);
|
||||
|
||||
/* configure the FW with TDLS peer info */
|
||||
iwl_mvm_tdls_config(mvm, vif);
|
||||
/* Configure the FW with TDLS peer info only if TDLS channel switch
|
||||
* capability is set.
|
||||
* TDLS config data is used currently only in TDLS channel switch code.
|
||||
* Supposed to serve also TDLS buffer station which is not implemneted
|
||||
* yet in FW*/
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH))
|
||||
iwl_mvm_tdls_config(mvm, vif);
|
||||
|
||||
/* when the last peer leaves, send a power update last */
|
||||
if (tdls_sta_cnt == 0 && !sta_added)
|
||||
|
@ -843,8 +843,10 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
* N * subf_len + (N - 1) * pad.
|
||||
*/
|
||||
num_subframes = (max_amsdu_len + pad) / (subf_len + pad);
|
||||
if (num_subframes > 1)
|
||||
*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
|
||||
|
||||
if (sta->max_amsdu_subframes &&
|
||||
num_subframes > sta->max_amsdu_subframes)
|
||||
num_subframes = sta->max_amsdu_subframes;
|
||||
|
||||
tcp_payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
|
||||
tcp_hdrlen(skb) + skb->data_len;
|
||||
@ -855,10 +857,12 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
* 1 more for each fragment
|
||||
* 1 more for the potential data in the header
|
||||
*/
|
||||
num_subframes =
|
||||
min_t(unsigned int, num_subframes,
|
||||
(mvm->trans->max_skb_frags - 1 -
|
||||
skb_shinfo(skb)->nr_frags) / 2);
|
||||
if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) >
|
||||
mvm->trans->max_skb_frags)
|
||||
num_subframes = 1;
|
||||
|
||||
if (num_subframes > 1)
|
||||
*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
|
||||
|
||||
/* This skb fits in one single A-MSDU */
|
||||
if (num_subframes * mss >= tcp_payload_len) {
|
||||
|
@ -836,6 +836,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
struct iwl_trans *iwl_trans;
|
||||
int ret;
|
||||
|
||||
if (WARN_ONCE(!cfg->csr, "CSR addresses aren't configured\n"))
|
||||
return -EINVAL;
|
||||
|
||||
iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
|
||||
if (IS_ERR(iwl_trans))
|
||||
return PTR_ERR(iwl_trans);
|
||||
|
@ -902,6 +902,8 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
|
||||
}
|
||||
def_rxq = trans_pcie->rxq;
|
||||
|
||||
cancel_work_sync(&rba->rx_alloc);
|
||||
|
||||
spin_lock(&rba->lock);
|
||||
atomic_set(&rba->req_pending, 0);
|
||||
atomic_set(&rba->req_ready, 0);
|
||||
|
@ -1158,6 +1158,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as IBSS\n", dev->name);
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
@ -1188,6 +1189,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as STA\n", dev->name);
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_STATION: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
@ -1210,6 +1212,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as AP\n", dev->name);
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_AP: /* This shouldn't happen */
|
||||
return 0;
|
||||
default:
|
||||
@ -1249,6 +1252,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%s: kept type as P2P\n", dev->name);
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
return 0;
|
||||
@ -2258,7 +2262,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
|
||||
|
||||
if (!bss) {
|
||||
if (is_scanning_required) {
|
||||
mwifiex_dbg(priv->adapter, WARN,
|
||||
mwifiex_dbg(priv->adapter, MSG,
|
||||
"assoc: requested bss not found in scan results\n");
|
||||
break;
|
||||
}
|
||||
@ -3555,6 +3559,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
|
||||
HostCmd_ACT_GEN_SET, 0, data, true);
|
||||
}
|
||||
@ -4190,6 +4197,16 @@ static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
|
||||
.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
|
||||
.max_nd_match_sets = MWIFIEX_MAX_ND_MATCH_SETS,
|
||||
};
|
||||
|
||||
static const struct wiphy_wowlan_support mwifiex_wowlan_support_no_gtk = {
|
||||
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
|
||||
WIPHY_WOWLAN_NET_DETECT,
|
||||
.n_patterns = MWIFIEX_MEF_MAX_FILTERS,
|
||||
.pattern_min_len = 1,
|
||||
.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
|
||||
.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
|
||||
.max_nd_match_sets = MWIFIEX_MAX_ND_MATCH_SETS,
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool mwifiex_is_valid_alpha2(const char *alpha2)
|
||||
@ -4308,7 +4325,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
wiphy->wowlan = &mwifiex_wowlan_support;
|
||||
if (ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
|
||||
wiphy->wowlan = &mwifiex_wowlan_support;
|
||||
else
|
||||
wiphy->wowlan = &mwifiex_wowlan_support_no_gtk;
|
||||
#endif
|
||||
|
||||
wiphy->coalesce = &mwifiex_coalesce_support;
|
||||
|
@ -153,34 +153,6 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Proc device dump read handler.
|
||||
*
|
||||
* This function is called when the 'device_dump' file is opened for
|
||||
* reading.
|
||||
* This function dumps driver information and firmware memory segments
|
||||
* (ex. DTCM, ITCM, SQRAM etc.) for
|
||||
* debugging.
|
||||
*/
|
||||
static ssize_t
|
||||
mwifiex_device_dump_read(struct file *file, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct mwifiex_private *priv = file->private_data;
|
||||
|
||||
/* For command timeouts, USB firmware will automatically emit
|
||||
* firmware dump events, so we don't implement device_dump().
|
||||
* For user-initiated dumps, we trigger it ourselves.
|
||||
*/
|
||||
if (priv->adapter->iface_type == MWIFIEX_USB)
|
||||
mwifiex_send_cmd(priv, HostCmd_CMD_FW_DUMP_EVENT,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL, true);
|
||||
else
|
||||
priv->adapter->if_ops.device_dump(priv->adapter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Proc getlog file read handler.
|
||||
*
|
||||
@ -980,7 +952,6 @@ static const struct file_operations mwifiex_dfs_##name##_fops = { \
|
||||
MWIFIEX_DFS_FILE_READ_OPS(info);
|
||||
MWIFIEX_DFS_FILE_READ_OPS(debug);
|
||||
MWIFIEX_DFS_FILE_READ_OPS(getlog);
|
||||
MWIFIEX_DFS_FILE_READ_OPS(device_dump);
|
||||
MWIFIEX_DFS_FILE_OPS(regrdwr);
|
||||
MWIFIEX_DFS_FILE_OPS(rdeeprom);
|
||||
MWIFIEX_DFS_FILE_OPS(memrw);
|
||||
@ -1011,7 +982,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
|
||||
MWIFIEX_DFS_ADD_FILE(getlog);
|
||||
MWIFIEX_DFS_ADD_FILE(regrdwr);
|
||||
MWIFIEX_DFS_ADD_FILE(rdeeprom);
|
||||
MWIFIEX_DFS_ADD_FILE(device_dump);
|
||||
|
||||
MWIFIEX_DFS_ADD_FILE(memrw);
|
||||
MWIFIEX_DFS_ADD_FILE(hscfg);
|
||||
MWIFIEX_DFS_ADD_FILE(histogram);
|
||||
|
@ -249,6 +249,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
|
||||
#define ISSUPP_ADHOC_ENABLED(FwCapInfo) (FwCapInfo & BIT(25))
|
||||
#define ISSUPP_RANDOM_MAC(FwCapInfo) (FwCapInfo & BIT(27))
|
||||
#define ISSUPP_FIRMWARE_SUPPLICANT(FwCapInfo) (FwCapInfo & BIT(21))
|
||||
|
||||
#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
|
||||
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
|
||||
|
@ -1691,6 +1691,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter);
|
||||
void mwifiex_prepare_fw_dump_info(struct mwifiex_adapter *adapter);
|
||||
void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter);
|
||||
void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
|
||||
void mwifiex_fw_dump_event(struct mwifiex_private *priv);
|
||||
void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
|
||||
int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
|
||||
int cmd_type,
|
||||
|
@ -320,6 +320,19 @@ static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
|
||||
return;
|
||||
}
|
||||
|
||||
static void mwifiex_pcie_coredump(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
struct pcie_service_card *card;
|
||||
|
||||
pdev = container_of(dev, struct pci_dev, dev);
|
||||
card = pci_get_drvdata(pdev);
|
||||
|
||||
if (!test_and_set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
|
||||
&card->work_flags))
|
||||
schedule_work(&card->work);
|
||||
}
|
||||
|
||||
static const struct pci_device_id mwifiex_ids[] = {
|
||||
{
|
||||
PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
|
||||
@ -415,11 +428,12 @@ static struct pci_driver __refdata mwifiex_pcie = {
|
||||
.id_table = mwifiex_ids,
|
||||
.probe = mwifiex_pcie_probe,
|
||||
.remove = mwifiex_pcie_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.driver = {
|
||||
.coredump = mwifiex_pcie_coredump,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.pm = &mwifiex_pcie_pm_ops,
|
||||
},
|
||||
#endif
|
||||
},
|
||||
.shutdown = mwifiex_pcie_shutdown,
|
||||
.err_handler = &mwifiex_pcie_err_handler,
|
||||
};
|
||||
|
@ -482,7 +482,8 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16((u16) user_scan_in->
|
||||
chan_list[0].scan_time);
|
||||
else if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
else if ((ch->flags & IEEE80211_CHAN_NO_IR) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16(adapter->passive_scan_time);
|
||||
else
|
||||
@ -502,10 +503,12 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
||||
scan_chan_list[chan_idx].chan_scan_mode_bitmap
|
||||
|= MWIFIEX_DISABLE_CHAN_FILT;
|
||||
|
||||
if (filtered_scan) {
|
||||
if (filtered_scan &&
|
||||
!((ch->flags & IEEE80211_CHAN_NO_IR) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR)))
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16(adapter->specific_scan_time);
|
||||
}
|
||||
|
||||
chan_idx++;
|
||||
}
|
||||
|
||||
@ -1308,6 +1311,7 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||
|
||||
case WLAN_EID_CHANNEL_SWITCH:
|
||||
bss_entry->chan_sw_ie_present = true;
|
||||
/* fall through */
|
||||
case WLAN_EID_PWR_CAPABILITY:
|
||||
case WLAN_EID_TPC_REPORT:
|
||||
case WLAN_EID_QUIET:
|
||||
|
@ -466,6 +466,17 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mwifiex_sdio_coredump(struct device *dev)
|
||||
{
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
struct sdio_mmc_card *card;
|
||||
|
||||
card = sdio_get_drvdata(func);
|
||||
if (!test_and_set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
|
||||
&card->work_flags))
|
||||
schedule_work(&card->work);
|
||||
}
|
||||
|
||||
/* Device ID for SD8786 */
|
||||
#define SDIO_DEVICE_ID_MARVELL_8786 (0x9116)
|
||||
/* Device ID for SD8787 */
|
||||
@ -515,6 +526,7 @@ static struct sdio_driver mwifiex_sdio = {
|
||||
.remove = mwifiex_sdio_remove,
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.coredump = mwifiex_sdio_coredump,
|
||||
.pm = &mwifiex_sdio_pm_ops,
|
||||
}
|
||||
};
|
||||
|
@ -241,6 +241,9 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
|
||||
if (netif_carrier_ok(priv->netdev))
|
||||
netif_carrier_off(priv->netdev);
|
||||
|
||||
if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
|
||||
return;
|
||||
|
||||
mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
|
||||
HostCmd_ACT_GEN_REMOVE, 0, NULL, false);
|
||||
}
|
||||
|
@ -644,6 +644,9 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
|
||||
MWIFIEX_FUNC_SHUTDOWN);
|
||||
}
|
||||
|
||||
if (adapter->workqueue)
|
||||
flush_workqueue(adapter->workqueue);
|
||||
|
||||
mwifiex_usb_free(card);
|
||||
|
||||
mwifiex_dbg(adapter, FATAL,
|
||||
@ -653,6 +656,15 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
|
||||
usb_put_dev(interface_to_usbdev(intf));
|
||||
}
|
||||
|
||||
static void mwifiex_usb_coredump(struct device *dev)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
struct usb_card_rec *card = usb_get_intfdata(intf);
|
||||
|
||||
mwifiex_fw_dump_event(mwifiex_get_priv(card->adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY));
|
||||
}
|
||||
|
||||
static struct usb_driver mwifiex_usb_driver = {
|
||||
.name = "mwifiex_usb",
|
||||
.probe = mwifiex_usb_probe,
|
||||
@ -661,6 +673,9 @@ static struct usb_driver mwifiex_usb_driver = {
|
||||
.suspend = mwifiex_usb_suspend,
|
||||
.resume = mwifiex_usb_resume,
|
||||
.soft_unbind = 1,
|
||||
.drvwrap.driver = {
|
||||
.coredump = mwifiex_usb_coredump,
|
||||
},
|
||||
};
|
||||
|
||||
static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
|
||||
|
@ -708,12 +708,14 @@ void mwifiex_hist_data_set(struct mwifiex_private *priv, u8 rx_rate, s8 snr,
|
||||
s8 nflr)
|
||||
{
|
||||
struct mwifiex_histogram_data *phist_data = priv->hist_data;
|
||||
s8 nf = -nflr;
|
||||
s8 rssi = snr - nflr;
|
||||
|
||||
atomic_inc(&phist_data->num_samples);
|
||||
atomic_inc(&phist_data->rx_rate[rx_rate]);
|
||||
atomic_inc(&phist_data->snr[snr]);
|
||||
atomic_inc(&phist_data->noise_flr[128 + nflr]);
|
||||
atomic_inc(&phist_data->sig_str[nflr - snr]);
|
||||
atomic_inc(&phist_data->snr[snr + 128]);
|
||||
atomic_inc(&phist_data->noise_flr[nf + 128]);
|
||||
atomic_inc(&phist_data->sig_str[rssi + 128]);
|
||||
}
|
||||
|
||||
/* function to reset histogram data during init/reset */
|
||||
@ -755,3 +757,10 @@ void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags)
|
||||
return skb;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mwifiex_alloc_dma_align_buf);
|
||||
|
||||
void mwifiex_fw_dump_event(struct mwifiex_private *priv)
|
||||
{
|
||||
mwifiex_send_cmd(priv, HostCmd_CMD_FW_DUMP_EVENT, HostCmd_ACT_GEN_SET,
|
||||
0, NULL, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mwifiex_fw_dump_event);
|
||||
|
@ -178,6 +178,10 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
|
||||
mt76_dma_sync_idx(dev, q);
|
||||
|
||||
wake = wake && qid < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
|
||||
|
||||
if (!q->queued)
|
||||
wake_up(&dev->tx_wait);
|
||||
|
||||
spin_unlock_bh(&q->lock);
|
||||
|
||||
if (wake)
|
||||
|
@ -268,6 +268,27 @@ mt76_check_sband(struct mt76_dev *dev, int band)
|
||||
dev->hw->wiphy->bands[band] = NULL;
|
||||
}
|
||||
|
||||
struct mt76_dev *
|
||||
mt76_alloc_device(unsigned int size, const struct ieee80211_ops *ops)
|
||||
{
|
||||
struct ieee80211_hw *hw;
|
||||
struct mt76_dev *dev;
|
||||
|
||||
hw = ieee80211_alloc_hw(size, ops);
|
||||
if (!hw)
|
||||
return NULL;
|
||||
|
||||
dev = hw->priv;
|
||||
dev->hw = hw;
|
||||
spin_lock_init(&dev->rx_lock);
|
||||
spin_lock_init(&dev->lock);
|
||||
spin_lock_init(&dev->cc_lock);
|
||||
init_waitqueue_head(&dev->tx_wait);
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_alloc_device);
|
||||
|
||||
int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
struct ieee80211_rate *rates, int n_rates)
|
||||
{
|
||||
@ -277,8 +298,6 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
|
||||
dev_set_drvdata(dev->dev, dev);
|
||||
|
||||
spin_lock_init(&dev->lock);
|
||||
spin_lock_init(&dev->cc_lock);
|
||||
INIT_LIST_HEAD(&dev->txwi_cache);
|
||||
|
||||
SET_IEEE80211_DEV(hw, dev->dev);
|
||||
@ -359,12 +378,32 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_rx);
|
||||
|
||||
static bool mt76_has_tx_pending(struct mt76_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
|
||||
if (dev->q_tx[i].queued)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void mt76_set_channel(struct mt76_dev *dev)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev->hw;
|
||||
struct cfg80211_chan_def *chandef = &hw->conf.chandef;
|
||||
struct mt76_channel_state *state;
|
||||
bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
|
||||
int timeout = HZ / 5;
|
||||
|
||||
if (offchannel)
|
||||
set_bit(MT76_OFFCHANNEL, &dev->state);
|
||||
else
|
||||
clear_bit(MT76_OFFCHANNEL, &dev->state);
|
||||
|
||||
wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), timeout);
|
||||
|
||||
if (dev->drv->update_survey)
|
||||
dev->drv->update_survey(dev);
|
||||
|
@ -189,6 +189,7 @@ enum {
|
||||
MT76_STATE_RUNNING,
|
||||
MT76_SCANNING,
|
||||
MT76_RESET,
|
||||
MT76_OFFCHANNEL,
|
||||
};
|
||||
|
||||
struct mt76_hw_cap {
|
||||
@ -250,6 +251,8 @@ struct mt76_dev {
|
||||
struct mt76_queue q_rx[__MT_RXQ_MAX];
|
||||
const struct mt76_queue_ops *queue_ops;
|
||||
|
||||
wait_queue_head_t tx_wait;
|
||||
|
||||
u8 macaddr[ETH_ALEN];
|
||||
u32 rev;
|
||||
unsigned long state;
|
||||
@ -376,6 +379,8 @@ mt76_channel_state(struct mt76_dev *dev, struct ieee80211_channel *c)
|
||||
return &msband->chan[idx];
|
||||
}
|
||||
|
||||
struct mt76_dev *mt76_alloc_device(unsigned int size,
|
||||
const struct ieee80211_ops *ops);
|
||||
int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
struct ieee80211_rate *rates, int n_rates);
|
||||
void mt76_unregister_device(struct mt76_dev *dev);
|
||||
|
@ -39,6 +39,9 @@
|
||||
|
||||
#define MT_CALIBRATE_INTERVAL HZ
|
||||
|
||||
#define MT_MAX_VIFS 8
|
||||
#define MT_VIF_WCID(_n) (254 - ((_n) & 7))
|
||||
|
||||
#include "mt76.h"
|
||||
#include "mt76x2_regs.h"
|
||||
#include "mt76x2_mac.h"
|
||||
|
@ -296,6 +296,9 @@ static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
|
||||
for (i = 0; i < 256; i++)
|
||||
mt76x2_mac_wcid_setup(dev, i, 0, NULL);
|
||||
|
||||
for (i = 0; i < MT_MAX_VIFS; i++)
|
||||
mt76x2_mac_wcid_setup(dev, MT_VIF_WCID(i), i, NULL);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (k = 0; k < 4; k++)
|
||||
mt76x2_mac_shared_key_setup(dev, i, k, NULL);
|
||||
@ -373,7 +376,7 @@ void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force)
|
||||
if ((mt76_rr(dev, MT_MAC_STATUS) &
|
||||
(MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) ||
|
||||
mt76_rr(dev, MT_BBP(IBI, 12))) {
|
||||
usleep_range(10, 20);
|
||||
udelay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -482,7 +485,10 @@ void mt76x2_set_tx_ackto(struct mt76x2_dev *dev)
|
||||
{
|
||||
u8 ackto, sifs, slottime = dev->slottime;
|
||||
|
||||
/* As defined by IEEE 802.11-2007 17.3.8.6 */
|
||||
slottime += 3 * dev->coverage_class;
|
||||
mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
|
||||
MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
|
||||
|
||||
sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
|
||||
MT_XIFS_TIME_CFG_OFDM_SIFS);
|
||||
@ -632,20 +638,18 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
|
||||
.rx_poll_complete = mt76x2_rx_poll_complete,
|
||||
.sta_ps = mt76x2_sta_ps,
|
||||
};
|
||||
struct ieee80211_hw *hw;
|
||||
struct mt76x2_dev *dev;
|
||||
struct mt76_dev *mdev;
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(*dev), &mt76x2_ops);
|
||||
if (!hw)
|
||||
mdev = mt76_alloc_device(sizeof(*dev), &mt76x2_ops);
|
||||
if (!mdev)
|
||||
return NULL;
|
||||
|
||||
dev = hw->priv;
|
||||
dev->mt76.dev = pdev;
|
||||
dev->mt76.hw = hw;
|
||||
dev->mt76.drv = &drv_ops;
|
||||
dev = container_of(mdev, struct mt76x2_dev, mt76);
|
||||
mdev->dev = pdev;
|
||||
mdev->drv = &drv_ops;
|
||||
mutex_init(&dev->mutex);
|
||||
spin_lock_init(&dev->irq_lock);
|
||||
spin_lock_init(&dev->mt76.rx_lock);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -301,6 +301,9 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
|
||||
u8 wcid;
|
||||
int len;
|
||||
|
||||
if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
|
||||
return -EINVAL;
|
||||
|
||||
if (rxinfo & MT_RXINFO_L2PAD)
|
||||
pad_len += 2;
|
||||
|
||||
|
@ -104,7 +104,7 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
idx += 8;
|
||||
|
||||
mvif->idx = idx;
|
||||
mvif->group_wcid.idx = 254 - idx;
|
||||
mvif->group_wcid.idx = MT_VIF_WCID(idx);
|
||||
mvif->group_wcid.hw_key_idx = -1;
|
||||
mt76x2_txq_init(dev, vif->txq);
|
||||
|
||||
@ -124,11 +124,14 @@ mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
|
||||
set_bit(MT76_RESET, &dev->mt76.state);
|
||||
|
||||
mt76_set_channel(&dev->mt76);
|
||||
|
||||
tasklet_disable(&dev->pre_tbtt_tasklet);
|
||||
tasklet_disable(&dev->dfs_pd.dfs_tasklet);
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
|
||||
mt76x2_mac_stop(dev, true);
|
||||
ret = mt76x2_phy_set_channel(dev, chandef);
|
||||
@ -143,6 +146,10 @@ mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef)
|
||||
tasklet_enable(&dev->dfs_pd.dfs_tasklet);
|
||||
tasklet_enable(&dev->pre_tbtt_tasklet);
|
||||
|
||||
clear_bit(MT76_RESET, &dev->mt76.state);
|
||||
|
||||
mt76_txq_schedule_all(&dev->mt76);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -247,8 +254,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
int slottime = info->use_short_slot ? 9 : 20;
|
||||
|
||||
dev->slottime = slottime;
|
||||
mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
|
||||
MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
|
||||
mt76x2_set_tx_ackto(dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mutex);
|
||||
@ -453,7 +459,6 @@ mt76x2_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
|
||||
clear_bit(MT76_SCANNING, &dev->mt76.state);
|
||||
tasklet_enable(&dev->pre_tbtt_tasklet);
|
||||
mt76_txq_schedule_all(&dev->mt76);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -332,7 +332,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
|
||||
if (probe)
|
||||
break;
|
||||
|
||||
if (test_bit(MT76_SCANNING, &dev->state) ||
|
||||
if (test_bit(MT76_OFFCHANNEL, &dev->state) ||
|
||||
test_bit(MT76_RESET, &dev->state))
|
||||
return -EBUSY;
|
||||
|
||||
@ -385,7 +385,7 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)
|
||||
bool empty = false;
|
||||
int cur;
|
||||
|
||||
if (test_bit(MT76_SCANNING, &dev->state) ||
|
||||
if (test_bit(MT76_OFFCHANNEL, &dev->state) ||
|
||||
test_bit(MT76_RESET, &dev->state))
|
||||
return -EBUSY;
|
||||
|
||||
|
@ -27,7 +27,8 @@ enum qtnf_fw_state {
|
||||
QTNF_FW_STATE_FW_DNLD_DONE,
|
||||
QTNF_FW_STATE_BOOT_DONE,
|
||||
QTNF_FW_STATE_ACTIVE,
|
||||
QTNF_FW_STATE_DEAD,
|
||||
QTNF_FW_STATE_DETACHED,
|
||||
QTNF_FW_STATE_EP_DEAD,
|
||||
};
|
||||
|
||||
struct qtnf_bus;
|
||||
|
@ -177,8 +177,6 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||
vif->netdev->ieee80211_ptr = NULL;
|
||||
vif->netdev = NULL;
|
||||
vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
eth_zero_addr(vif->mac_addr);
|
||||
eth_zero_addr(vif->bssid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -216,10 +214,12 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
eth_zero_addr(vif->mac_addr);
|
||||
eth_zero_addr(vif->bssid);
|
||||
vif->bss_priority = QTNF_DEF_BSS_PRIORITY;
|
||||
vif->sta_state = QTNF_STA_DISCONNECTED;
|
||||
memset(&vif->wdev, 0, sizeof(vif->wdev));
|
||||
vif->wdev.wiphy = wiphy;
|
||||
vif->wdev.iftype = type;
|
||||
vif->sta_state = QTNF_STA_DISCONNECTED;
|
||||
break;
|
||||
default:
|
||||
pr_err("MAC%u: unsupported IF type %d\n", mac->macid, type);
|
||||
@ -255,8 +255,6 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
|
||||
qtnf_cmd_send_del_intf(vif);
|
||||
err_cmd:
|
||||
vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
eth_zero_addr(vif->mac_addr);
|
||||
eth_zero_addr(vif->bssid);
|
||||
|
||||
return ERR_PTR(-EFAULT);
|
||||
}
|
||||
@ -651,28 +649,37 @@ qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct qtnf_vif *vif;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
vif = qtnf_mac_get_base_vif(mac);
|
||||
if (!vif) {
|
||||
pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
|
||||
return -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
|
||||
return -EOPNOTSUPP;
|
||||
if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
qtnf_scan_done(mac, true);
|
||||
|
||||
if (vif->sta_state == QTNF_STA_DISCONNECTED)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
ret = qtnf_cmd_send_disconnect(vif, reason_code);
|
||||
if (ret) {
|
||||
pr_err("VIF%u.%u: failed to disconnect\n", mac->macid,
|
||||
vif->vifid);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (vif->sta_state == QTNF_STA_CONNECTING)
|
||||
vif->sta_state = QTNF_STA_DISCONNECTED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -955,6 +962,7 @@ qtnf_wiphy_setup_if_comb(struct wiphy *wiphy, struct qtnf_mac_info *mac_info)
|
||||
int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
|
||||
{
|
||||
struct wiphy *wiphy = priv_to_wiphy(mac);
|
||||
struct qtnf_mac_info *macinfo = &mac->macinfo;
|
||||
int ret;
|
||||
|
||||
if (!wiphy) {
|
||||
@ -962,20 +970,20 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
wiphy->frag_threshold = mac->macinfo.frag_thr;
|
||||
wiphy->rts_threshold = mac->macinfo.rts_thr;
|
||||
wiphy->retry_short = mac->macinfo.sretry_limit;
|
||||
wiphy->retry_long = mac->macinfo.lretry_limit;
|
||||
wiphy->coverage_class = mac->macinfo.coverage_class;
|
||||
wiphy->frag_threshold = macinfo->frag_thr;
|
||||
wiphy->rts_threshold = macinfo->rts_thr;
|
||||
wiphy->retry_short = macinfo->sretry_limit;
|
||||
wiphy->retry_long = macinfo->lretry_limit;
|
||||
wiphy->coverage_class = macinfo->coverage_class;
|
||||
|
||||
wiphy->max_scan_ssids = QTNF_MAX_SSID_LIST_LENGTH;
|
||||
wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN;
|
||||
wiphy->mgmt_stypes = qtnf_mgmt_stypes;
|
||||
wiphy->max_remain_on_channel_duration = 5000;
|
||||
wiphy->max_acl_mac_addrs = mac->macinfo.max_acl_mac_addrs;
|
||||
wiphy->max_acl_mac_addrs = macinfo->max_acl_mac_addrs;
|
||||
wiphy->max_num_csa_counters = 2;
|
||||
|
||||
ret = qtnf_wiphy_setup_if_comb(wiphy, &mac->macinfo);
|
||||
ret = qtnf_wiphy_setup_if_comb(wiphy, macinfo);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -994,12 +1002,12 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
|
||||
wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;
|
||||
|
||||
wiphy->available_antennas_tx = mac->macinfo.num_tx_chain;
|
||||
wiphy->available_antennas_rx = mac->macinfo.num_rx_chain;
|
||||
wiphy->available_antennas_tx = macinfo->num_tx_chain;
|
||||
wiphy->available_antennas_rx = macinfo->num_rx_chain;
|
||||
|
||||
wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta;
|
||||
wiphy->ht_capa_mod_mask = &mac->macinfo.ht_cap_mod_mask;
|
||||
wiphy->vht_capa_mod_mask = &mac->macinfo.vht_cap_mod_mask;
|
||||
wiphy->max_ap_assoc_sta = macinfo->max_ap_assoc_sta;
|
||||
wiphy->ht_capa_mod_mask = &macinfo->ht_cap_mod_mask;
|
||||
wiphy->vht_capa_mod_mask = &macinfo->vht_cap_mod_mask;
|
||||
|
||||
ether_addr_copy(wiphy->perm_addr, mac->macaddr);
|
||||
|
||||
|
@ -55,6 +55,28 @@ static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qtnf_cmd_resp_result_decode(enum qlink_cmd_result qcode)
|
||||
{
|
||||
switch (qcode) {
|
||||
case QLINK_CMD_RESULT_OK:
|
||||
return 0;
|
||||
case QLINK_CMD_RESULT_INVALID:
|
||||
return -EINVAL;
|
||||
case QLINK_CMD_RESULT_ENOTSUPP:
|
||||
return -ENOTSUPP;
|
||||
case QLINK_CMD_RESULT_ENOTFOUND:
|
||||
return -ENOENT;
|
||||
case QLINK_CMD_RESULT_EALREADY:
|
||||
return -EALREADY;
|
||||
case QLINK_CMD_RESULT_EADDRINUSE:
|
||||
return -EADDRINUSE;
|
||||
case QLINK_CMD_RESULT_EADDRNOTAVAIL:
|
||||
return -EADDRNOTAVAIL;
|
||||
default:
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus,
|
||||
struct sk_buff *cmd_skb,
|
||||
struct sk_buff **response_skb,
|
||||
@ -80,6 +102,7 @@ static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus,
|
||||
pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n",
|
||||
mac_id, vif_id, le16_to_cpu(cmd->cmd_id),
|
||||
bus->fw_state);
|
||||
dev_kfree_skb(cmd_skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -810,10 +833,10 @@ static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
|
||||
if (unlikely(ret))
|
||||
goto out;
|
||||
|
||||
if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
|
||||
ret = qtnf_cmd_resp_result_decode(res_code);
|
||||
if (ret) {
|
||||
pr_err("VIF%u.%u: CMD %d failed: %u\n", vif->mac->macid,
|
||||
vif->vifid, cmd_type, res_code);
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2316,13 +2339,11 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
|
||||
else
|
||||
eth_zero_addr(cmd->prev_bssid);
|
||||
|
||||
if ((sme->bg_scan_period > 0) &&
|
||||
(sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
|
||||
if ((sme->bg_scan_period >= 0) &&
|
||||
(sme->bg_scan_period <= SHRT_MAX))
|
||||
cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period);
|
||||
else if (sme->bg_scan_period == -1)
|
||||
cmd->bg_scan_period = cpu_to_le16(QTNF_DEFAULT_BG_SCAN_PERIOD);
|
||||
else
|
||||
cmd->bg_scan_period = 0; /* disabled */
|
||||
cmd->bg_scan_period = cpu_to_le16(-1); /* use default value */
|
||||
|
||||
if (sme->flags & ASSOC_REQ_DISABLE_HT)
|
||||
connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
|
||||
|
@ -58,11 +58,6 @@ int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac,
|
||||
struct station_parameters *params);
|
||||
int qtnf_cmd_send_del_sta(struct qtnf_vif *vif,
|
||||
struct station_del_parameters *params);
|
||||
|
||||
int qtnf_cmd_resp_parse(struct qtnf_bus *bus, struct sk_buff *resp_skb);
|
||||
int qtnf_cmd_resp_check(const struct qtnf_vif *vif,
|
||||
const struct sk_buff *resp_skb, u16 cmd_id,
|
||||
u16 *result, const u8 **payload, size_t *payload_size);
|
||||
int qtnf_cmd_send_scan(struct qtnf_wmac *mac);
|
||||
int qtnf_cmd_send_connect(struct qtnf_vif *vif,
|
||||
struct cfg80211_connect_params *sme);
|
||||
|
@ -394,7 +394,6 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name,
|
||||
name_assign_type, ether_setup, 1, 1);
|
||||
if (!dev) {
|
||||
memset(&vif->wdev, 0, sizeof(vif->wdev));
|
||||
vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -629,7 +628,7 @@ void qtnf_core_detach(struct qtnf_bus *bus)
|
||||
if (bus->fw_state == QTNF_FW_STATE_ACTIVE)
|
||||
qtnf_cmd_send_deinit_fw(bus);
|
||||
|
||||
bus->fw_state = QTNF_FW_STATE_DEAD;
|
||||
bus->fw_state = QTNF_FW_STATE_DETACHED;
|
||||
|
||||
if (bus->workqueue) {
|
||||
flush_workqueue(bus->workqueue);
|
||||
|
@ -44,8 +44,6 @@
|
||||
#define QTNF_MAX_VSIE_LEN 255
|
||||
#define QTNF_MAX_INTF 8
|
||||
#define QTNF_MAX_EVENT_QUEUE_LEN 255
|
||||
#define QTNF_DEFAULT_BG_SCAN_PERIOD 300
|
||||
#define QTNF_MAX_BG_SCAN_PERIOD 0xffff
|
||||
#define QTNF_SCAN_TIMEOUT_SEC 15
|
||||
|
||||
#define QTNF_DEF_BSS_PRIORITY 0
|
||||
|
@ -211,11 +211,9 @@ qtnf_event_handle_bss_leave(struct qtnf_vif *vif,
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (vif->sta_state != QTNF_STA_CONNECTED) {
|
||||
pr_err("VIF%u.%u: BSS_LEAVE event when STA is not connected\n",
|
||||
vif->mac->macid, vif->vifid);
|
||||
return -EPROTO;
|
||||
}
|
||||
if (vif->sta_state != QTNF_STA_CONNECTED)
|
||||
pr_warn("VIF%u.%u: BSS_LEAVE event when STA is not connected\n",
|
||||
vif->mac->macid, vif->vifid);
|
||||
|
||||
pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);
|
||||
|
||||
|
@ -751,8 +751,16 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
|
||||
static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)
|
||||
{
|
||||
struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
|
||||
int ret;
|
||||
|
||||
return qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len);
|
||||
ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len);
|
||||
|
||||
if (ret == -ETIMEDOUT) {
|
||||
pr_err("EP firmware is dead\n");
|
||||
bus->fw_state = QTNF_FW_STATE_EP_DEAD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t qtnf_interrupt(int irq, void *data)
|
||||
@ -1238,7 +1246,7 @@ static void qtnf_fw_work_handler(struct work_struct *work)
|
||||
goto fw_load_exit;
|
||||
|
||||
fw_load_fail:
|
||||
bus->fw_state = QTNF_FW_STATE_DEAD;
|
||||
bus->fw_state = QTNF_FW_STATE_DETACHED;
|
||||
|
||||
fw_load_exit:
|
||||
complete(&bus->firmware_init_complete);
|
||||
@ -1408,7 +1416,8 @@ static void qtnf_pcie_remove(struct pci_dev *pdev)
|
||||
|
||||
wait_for_completion(&bus->firmware_init_complete);
|
||||
|
||||
if (bus->fw_state == QTNF_FW_STATE_ACTIVE)
|
||||
if (bus->fw_state == QTNF_FW_STATE_ACTIVE ||
|
||||
bus->fw_state == QTNF_FW_STATE_EP_DEAD)
|
||||
qtnf_core_detach(bus);
|
||||
|
||||
priv = get_bus_priv(bus);
|
||||
|
@ -674,6 +674,8 @@ enum qlink_cmd_result {
|
||||
QLINK_CMD_RESULT_ENOTSUPP,
|
||||
QLINK_CMD_RESULT_ENOTFOUND,
|
||||
QLINK_CMD_RESULT_EALREADY,
|
||||
QLINK_CMD_RESULT_EADDRINUSE,
|
||||
QLINK_CMD_RESULT_EADDRNOTAVAIL,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -35,8 +35,10 @@ int qtnf_trans_send_cmd_with_resp(struct qtnf_bus *bus, struct sk_buff *cmd_skb,
|
||||
bool resp_not_handled = true;
|
||||
struct sk_buff *resp_skb = NULL;
|
||||
|
||||
if (unlikely(!response_skb))
|
||||
if (unlikely(!response_skb)) {
|
||||
dev_kfree_skb(cmd_skb);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
spin_lock(&ctl_node->resp_lock);
|
||||
ctl_node->seq_num++;
|
||||
|
@ -396,7 +396,6 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
|
||||
ieee80211_hw_set(hw, SIGNAL_DBM);
|
||||
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
|
||||
ieee80211_hw_set(hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(hw, CONNECTION_MONITOR);
|
||||
ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
|
||||
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
|
||||
@ -572,8 +571,9 @@ int rtl_init_core(struct ieee80211_hw *hw)
|
||||
spin_lock_init(&rtlpriv->locks.iqk_lock);
|
||||
/* <5> init list */
|
||||
INIT_LIST_HEAD(&rtlpriv->entry_list);
|
||||
INIT_LIST_HEAD(&rtlpriv->c2hcmd_list);
|
||||
INIT_LIST_HEAD(&rtlpriv->scan_list.list);
|
||||
skb_queue_head_init(&rtlpriv->tx_report.queue);
|
||||
skb_queue_head_init(&rtlpriv->c2hcmd_queue);
|
||||
|
||||
rtlmac->link_state = MAC80211_NOLINK;
|
||||
|
||||
@ -585,11 +585,14 @@ int rtl_init_core(struct ieee80211_hw *hw)
|
||||
EXPORT_SYMBOL_GPL(rtl_init_core);
|
||||
|
||||
static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw);
|
||||
static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,
|
||||
bool timeout);
|
||||
|
||||
void rtl_deinit_core(struct ieee80211_hw *hw)
|
||||
{
|
||||
rtl_c2hcmd_launcher(hw, 0);
|
||||
rtl_free_entries_from_scan_list(hw);
|
||||
rtl_free_entries_from_ack_queue(hw, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl_deinit_core);
|
||||
|
||||
@ -1575,22 +1578,52 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl_is_special_data);
|
||||
|
||||
void rtl_tx_ackqueue(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
|
||||
|
||||
__skb_queue_tail(&tx_report->queue, skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl_tx_ackqueue);
|
||||
|
||||
static void rtl_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
bool ack)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_tx_info *info;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
if (ack) {
|
||||
RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD,
|
||||
"tx report: ack\n");
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
} else {
|
||||
RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD,
|
||||
"tx report: not ack\n");
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
}
|
||||
ieee80211_tx_status_irqsafe(hw, skb);
|
||||
}
|
||||
|
||||
bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
u16 ether_type;
|
||||
const u8 *ether_type_ptr;
|
||||
__le16 fc = rtl_get_fc(skb);
|
||||
|
||||
ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, true);
|
||||
ether_type = be16_to_cpup((__be16 *)ether_type_ptr);
|
||||
|
||||
/* EAPOL */
|
||||
if (ether_type == ETH_P_PAE)
|
||||
if (ether_type == ETH_P_PAE || ieee80211_is_nullfunc(fc))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw)
|
||||
static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw,
|
||||
struct rtlwifi_tx_info *tx_info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
|
||||
@ -1604,29 +1637,33 @@ static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw)
|
||||
|
||||
tx_report->last_sent_sn = sn;
|
||||
tx_report->last_sent_time = jiffies;
|
||||
|
||||
tx_info->sn = sn;
|
||||
tx_info->send_time = tx_report->last_sent_time;
|
||||
RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
|
||||
"Send TX-Report sn=0x%X\n", sn);
|
||||
|
||||
return sn;
|
||||
}
|
||||
|
||||
void rtl_get_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
|
||||
struct ieee80211_hw *hw)
|
||||
void rtl_set_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
|
||||
struct ieee80211_hw *hw, struct rtlwifi_tx_info *tx_info)
|
||||
{
|
||||
if (ptcb_desc->use_spe_rpt) {
|
||||
u16 sn = rtl_get_tx_report_sn(hw);
|
||||
u16 sn = rtl_get_tx_report_sn(hw, tx_info);
|
||||
|
||||
SET_TX_DESC_SPE_RPT(pdesc, 1);
|
||||
SET_TX_DESC_SW_DEFINE(pdesc, sn);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl_get_tx_report);
|
||||
EXPORT_SYMBOL_GPL(rtl_set_tx_report);
|
||||
|
||||
void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
|
||||
struct rtlwifi_tx_info *tx_info;
|
||||
struct sk_buff_head *queue = &tx_report->queue;
|
||||
struct sk_buff *skb;
|
||||
u16 sn;
|
||||
u8 st, retry;
|
||||
|
||||
@ -1642,6 +1679,14 @@ void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len)
|
||||
|
||||
tx_report->last_recv_sn = sn;
|
||||
|
||||
skb_queue_walk(queue, skb) {
|
||||
tx_info = rtl_tx_skb_cb_info(skb);
|
||||
if (tx_info->sn == sn) {
|
||||
skb_unlink(skb, queue);
|
||||
rtl_tx_status(hw, skb, st == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
|
||||
"Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n",
|
||||
st, sn, retry);
|
||||
@ -1909,6 +1954,25 @@ static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,
|
||||
bool chk_timeout)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
|
||||
struct sk_buff_head *queue = &tx_report->queue;
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct rtlwifi_tx_info *tx_info;
|
||||
|
||||
skb_queue_walk_safe(queue, skb, tmp) {
|
||||
tx_info = rtl_tx_skb_cb_info(skb);
|
||||
if (chk_timeout &&
|
||||
time_after(tx_info->send_time + HZ, jiffies))
|
||||
continue;
|
||||
skb_unlink(skb, queue);
|
||||
rtl_tx_status(hw, skb, false);
|
||||
}
|
||||
}
|
||||
|
||||
void rtl_scan_list_expire(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@ -2173,6 +2237,9 @@ void rtl_watchdog_wq_callback(void *data)
|
||||
|
||||
/* <6> scan list */
|
||||
rtl_scan_list_expire(hw);
|
||||
|
||||
/* <7> check ack queue */
|
||||
rtl_free_entries_from_ack_queue(hw, true);
|
||||
}
|
||||
|
||||
void rtl_watch_dog_timer_callback(struct timer_list *t)
|
||||
@ -2195,81 +2262,122 @@ void rtl_fwevt_wq_callback(void *data)
|
||||
rtlpriv->cfg->ops->c2h_command_handle(hw);
|
||||
}
|
||||
|
||||
void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val)
|
||||
static void rtl_c2h_content_parsing(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb);
|
||||
|
||||
static bool rtl_c2h_fast_cmd(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
u8 cmd_id = GET_C2H_CMD_ID(skb->data);
|
||||
|
||||
switch (cmd_id) {
|
||||
case C2H_BT_MP:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
unsigned long flags;
|
||||
struct rtl_c2hcmd *c2hcmd;
|
||||
|
||||
c2hcmd = kmalloc(sizeof(*c2hcmd),
|
||||
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
|
||||
if (!c2hcmd)
|
||||
goto label_err;
|
||||
|
||||
c2hcmd->val = kmalloc(len,
|
||||
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
|
||||
if (!c2hcmd->val)
|
||||
goto label_err2;
|
||||
|
||||
/* fill data */
|
||||
c2hcmd->tag = tag;
|
||||
c2hcmd->len = len;
|
||||
memcpy(c2hcmd->val, val, len);
|
||||
if (rtl_c2h_fast_cmd(hw, skb)) {
|
||||
rtl_c2h_content_parsing(hw, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* enqueue */
|
||||
spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);
|
||||
|
||||
list_add_tail(&c2hcmd->list, &rtlpriv->c2hcmd_list);
|
||||
__skb_queue_tail(&rtlpriv->c2hcmd_queue, skb);
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);
|
||||
|
||||
/* wake up wq */
|
||||
queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0);
|
||||
|
||||
return;
|
||||
|
||||
label_err2:
|
||||
kfree(c2hcmd);
|
||||
|
||||
label_err:
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
|
||||
"C2H cmd enqueue fail.\n");
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_c2hcmd_enqueue);
|
||||
|
||||
static void rtl_c2h_content_parsing(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal_ops *hal_ops = rtlpriv->cfg->ops;
|
||||
const struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
|
||||
u8 cmd_id, cmd_seq, cmd_len;
|
||||
u8 *cmd_buf = NULL;
|
||||
|
||||
cmd_id = GET_C2H_CMD_ID(skb->data);
|
||||
cmd_seq = GET_C2H_SEQ(skb->data);
|
||||
cmd_len = skb->len - C2H_DATA_OFFSET;
|
||||
cmd_buf = GET_C2H_DATA_PTR(skb->data);
|
||||
|
||||
switch (cmd_id) {
|
||||
case C2H_DBG:
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n");
|
||||
break;
|
||||
case C2H_TXBF:
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
"[C2H], C2H_TXBF!!\n");
|
||||
break;
|
||||
case C2H_TX_REPORT:
|
||||
rtl_tx_report_handler(hw, cmd_buf, cmd_len);
|
||||
break;
|
||||
case C2H_RA_RPT:
|
||||
if (hal_ops->c2h_ra_report_handler)
|
||||
hal_ops->c2h_ra_report_handler(hw, cmd_buf, cmd_len);
|
||||
break;
|
||||
case C2H_BT_INFO:
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
"[C2H], C2H_BT_INFO!!\n");
|
||||
if (rtlpriv->cfg->ops->get_btc_status())
|
||||
btc_ops->btc_btinfo_notify(rtlpriv, cmd_buf, cmd_len);
|
||||
break;
|
||||
case C2H_BT_MP:
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
"[C2H], C2H_BT_MP!!\n");
|
||||
if (rtlpriv->cfg->ops->get_btc_status())
|
||||
btc_ops->btc_btmpinfo_notify(rtlpriv, cmd_buf, cmd_len);
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
"[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct sk_buff *skb;
|
||||
unsigned long flags;
|
||||
struct rtl_c2hcmd *c2hcmd;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 200; i++) {
|
||||
/* dequeue a task */
|
||||
spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);
|
||||
|
||||
c2hcmd = list_first_entry_or_null(&rtlpriv->c2hcmd_list,
|
||||
struct rtl_c2hcmd, list);
|
||||
|
||||
if (c2hcmd)
|
||||
list_del(&c2hcmd->list);
|
||||
skb = __skb_dequeue(&rtlpriv->c2hcmd_queue);
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);
|
||||
|
||||
/* do it */
|
||||
if (!c2hcmd)
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
if (rtlpriv->cfg->ops->c2h_content_parsing && exec)
|
||||
rtlpriv->cfg->ops->c2h_content_parsing(hw,
|
||||
c2hcmd->tag, c2hcmd->len, c2hcmd->val);
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n",
|
||||
*((u8 *)skb->cb));
|
||||
RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"C2H data: ", skb->data, skb->len);
|
||||
|
||||
if (exec)
|
||||
rtl_c2h_content_parsing(hw, skb);
|
||||
|
||||
/* free */
|
||||
kfree(c2hcmd->val);
|
||||
|
||||
kfree(c2hcmd);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,9 +130,10 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
|
||||
bool is_enc);
|
||||
|
||||
void rtl_tx_ackqueue(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
void rtl_get_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
|
||||
struct ieee80211_hw *hw);
|
||||
void rtl_set_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,
|
||||
struct ieee80211_hw *hw, struct rtlwifi_tx_info *info);
|
||||
void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf,
|
||||
u8 c2h_cmd_len);
|
||||
bool rtl_check_tx_report_acked(struct ieee80211_hw *hw);
|
||||
@ -160,7 +161,7 @@ void rtl_watchdog_wq_callback(void *data);
|
||||
void rtl_fwevt_wq_callback(void *data);
|
||||
void rtl_c2hcmd_wq_callback(void *data);
|
||||
void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec);
|
||||
void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val);
|
||||
void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
u8 rtl_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index,
|
||||
enum wireless_mode wirelessmode);
|
||||
|
@ -2876,25 +2876,10 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
|
||||
btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
|
||||
|
||||
/* sw mechanism */
|
||||
if (BTC_WIFI_BW_HT40 == wifi_bw) {
|
||||
if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
|
||||
(wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
|
||||
btc8723b2ant_sw_mechanism(btcoexist, true, true,
|
||||
false, false);
|
||||
} else {
|
||||
btc8723b2ant_sw_mechanism(btcoexist, true, true,
|
||||
false, false);
|
||||
}
|
||||
} else {
|
||||
if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
|
||||
(wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
|
||||
btc8723b2ant_sw_mechanism(btcoexist, false, true,
|
||||
false, false);
|
||||
} else {
|
||||
btc8723b2ant_sw_mechanism(btcoexist, false, true,
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
if (wifi_bw == BTC_WIFI_BW_HT40)
|
||||
btc8723b2ant_sw_mechanism(btcoexist, true, true, false, false);
|
||||
else
|
||||
btc8723b2ant_sw_mechanism(btcoexist, false, true, false, false);
|
||||
}
|
||||
|
||||
/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
|
||||
|
@ -619,12 +619,15 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
|
||||
rtlpriv->link_info.tidtx_inperiod[tid]++;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
/*info->status.rates[0].count = 1; */
|
||||
|
||||
ieee80211_tx_status_irqsafe(hw, skb);
|
||||
if (likely(!ieee80211_is_nullfunc(fc))) {
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
/*info->status.rates[0].count = 1; */
|
||||
ieee80211_tx_status_irqsafe(hw, skb);
|
||||
} else {
|
||||
rtl_tx_ackqueue(hw, skb);
|
||||
}
|
||||
|
||||
if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
|
||||
@ -827,9 +830,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
goto new_trx_end;
|
||||
}
|
||||
/* handle command packet here */
|
||||
if (rtlpriv->cfg->ops->rx_command_packet &&
|
||||
rtlpriv->cfg->ops->rx_command_packet(hw, &stats, skb)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
if (stats.packet_report_type == C2H_PACKET) {
|
||||
rtl_c2hcmd_enqueue(hw, skb);
|
||||
goto new_trx_end;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user