1
0
Fork 0

wireless-drivers-next patches for 4.14

rsi driver is getting a lot of new features lately, but as usual
 active development happening on iwlwifi as well as other drivers.
 
 I pulled wireless-drivers to fix multiple conflicts in iwlwifi and to
 make it easier further development.
 
 Major changes:
 
 ath10k
 
 * initial UBS bus support (no full support yet)
 
 * add tdls support for 10.4 firmware
 
 ath9k
 
 * add Dell Wireless 1802
 
 wil6210
 
 * support FW RSSI reporting
 
 rsi
 
 * support legacy power save, U-APSD, rf-kill and AP mode
 
 * RTS threshold configuration
 
 brcmfmac
 
 * support CYW4373 SDIO/USB chipset
 
 iwlwifi
 
 * some more code moved to a new directory
 
 * add new PCI ID for 7265D
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJZo9ubAAoJEG4XJFUm622bgTMIAIoYA4hNR17lkrsfuHztwo/p
 LM1biXej9dbRT5VNEVP4mlUVrKKakRt46YpW+UMdAI3KSNhqiNTM418126LUPpqn
 FIa5SKwoAB1S8g9dIBEpyfZVU9EnuyQ2XoW9ochBikrtQN71fW17G3EqRthiTbqH
 pWBA8RgKpLyjFs2Iupz8IJ8J5jK7qnIBo+wD5Px31U2rEiaE2/kCQPcVoM9aaNgD
 zJHFyVQgT2X76mD14B1R0tPyjEWDEmaWLW92jII+6Oxr6vnBguuyY1MKB1aejjmy
 UiKqf/znKrCYS8JepV+ayRqRThFYnNbO5UOCDnuQqCLkxcUAjvCkovamG+x9QBE=
 =IR0O
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-for-davem-2017-08-28' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for 4.14

rsi driver is getting a lot of new features lately, but as usual
active development happening on iwlwifi as well as other drivers.

I pulled wireless-drivers to fix multiple conflicts in iwlwifi and to
make it easier further development.

Major changes:

ath10k

* initial UBS bus support (no full support yet)

* add tdls support for 10.4 firmware

ath9k

* add Dell Wireless 1802

wil6210

* support FW RSSI reporting

rsi

* support legacy power save, U-APSD, rf-kill and AP mode

* RTS threshold configuration

brcmfmac

* support CYW4373 SDIO/USB chipset

iwlwifi

* some more code moved to a new directory

* add new PCI ID for 7265D
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
hifive-unleashed-5.1
David S. Miller 2017-08-29 11:04:43 -07:00
commit 7619de85d0
127 changed files with 4312 additions and 1274 deletions

View File

@ -3,11 +3,8 @@ config BCMA_POSSIBLE
depends on HAS_IOMEM && HAS_DMA
default y
menu "Broadcom specific AMBA"
depends on BCMA_POSSIBLE
config BCMA
tristate "BCMA support"
menuconfig BCMA
tristate "Broadcom specific AMBA"
depends on BCMA_POSSIBLE
help
Bus driver for Broadcom specific Advanced Microcontroller Bus
@ -117,5 +114,3 @@ config BCMA_DEBUG
This turns on additional debugging messages.
If unsure, say N
endmenu

View File

@ -1749,7 +1749,7 @@ static void ar5523_disconnect(struct usb_interface *intf)
{ USB_DEVICE((vendor), (device) + 1), \
.driver_info = AR5523_FLAG_ABG|AR5523_FLAG_PRE_FIRMWARE }
static struct usb_device_id ar5523_id_table[] = {
static const struct usb_device_id ar5523_id_table[] = {
AR5523_DEVICE_UG(0x168c, 0x0001), /* Atheros / AR5523 */
AR5523_DEVICE_UG(0x0cf3, 0x0001), /* Atheros2 / AR5523_1 */
AR5523_DEVICE_UG(0x0cf3, 0x0003), /* Atheros2 / AR5523_2 */

View File

@ -29,6 +29,13 @@ config ATH10K_SDIO
This module adds experimental support for SDIO/MMC bus. Currently
work in progress and will not fully work.
config ATH10K_USB
tristate "Atheros ath10k USB support (EXPERIMENTAL)"
depends on ATH10K && USB
---help---
This module adds experimental support for USB bus. Currently
work in progress and will not fully work.
config ATH10K_DEBUG
bool "Atheros ath10k debugging"
depends on ATH10K

View File

@ -30,5 +30,8 @@ ath10k_pci-$(CONFIG_ATH10K_AHB) += ahb.o
obj-$(CONFIG_ATH10K_SDIO) += ath10k_sdio.o
ath10k_sdio-y += sdio.o
obj-$(CONFIG_ATH10K_USB) += ath10k_usb.o
ath10k_usb-y += usb.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)

View File

@ -197,35 +197,40 @@ static int ath10k_ahb_rst_ctrl_init(struct ath10k *ar)
dev = &ar_ahb->pdev->dev;
ar_ahb->core_cold_rst = devm_reset_control_get(dev, "wifi_core_cold");
ar_ahb->core_cold_rst = devm_reset_control_get_exclusive(dev,
"wifi_core_cold");
if (IS_ERR(ar_ahb->core_cold_rst)) {
ath10k_err(ar, "failed to get core cold rst ctrl: %ld\n",
PTR_ERR(ar_ahb->core_cold_rst));
return PTR_ERR(ar_ahb->core_cold_rst);
}
ar_ahb->radio_cold_rst = devm_reset_control_get(dev, "wifi_radio_cold");
ar_ahb->radio_cold_rst = devm_reset_control_get_exclusive(dev,
"wifi_radio_cold");
if (IS_ERR(ar_ahb->radio_cold_rst)) {
ath10k_err(ar, "failed to get radio cold rst ctrl: %ld\n",
PTR_ERR(ar_ahb->radio_cold_rst));
return PTR_ERR(ar_ahb->radio_cold_rst);
}
ar_ahb->radio_warm_rst = devm_reset_control_get(dev, "wifi_radio_warm");
ar_ahb->radio_warm_rst = devm_reset_control_get_exclusive(dev,
"wifi_radio_warm");
if (IS_ERR(ar_ahb->radio_warm_rst)) {
ath10k_err(ar, "failed to get radio warm rst ctrl: %ld\n",
PTR_ERR(ar_ahb->radio_warm_rst));
return PTR_ERR(ar_ahb->radio_warm_rst);
}
ar_ahb->radio_srif_rst = devm_reset_control_get(dev, "wifi_radio_srif");
ar_ahb->radio_srif_rst = devm_reset_control_get_exclusive(dev,
"wifi_radio_srif");
if (IS_ERR(ar_ahb->radio_srif_rst)) {
ath10k_err(ar, "failed to get radio srif rst ctrl: %ld\n",
PTR_ERR(ar_ahb->radio_srif_rst));
return PTR_ERR(ar_ahb->radio_srif_rst);
}
ar_ahb->cpu_init_rst = devm_reset_control_get(dev, "wifi_cpu_init");
ar_ahb->cpu_init_rst = devm_reset_control_get_exclusive(dev,
"wifi_cpu_init");
if (IS_ERR(ar_ahb->cpu_init_rst)) {
ath10k_err(ar, "failed to get cpu init rst ctrl: %ld\n",
PTR_ERR(ar_ahb->cpu_init_rst));

View File

@ -1454,6 +1454,7 @@ static void ath10k_core_get_fw_name(struct ath10k *ar, char *fw_name,
{
switch (ar->hif.bus) {
case ATH10K_BUS_SDIO:
case ATH10K_BUS_USB:
scnprintf(fw_name, fw_name_len, "%s-%s-%d.bin",
ATH10K_FW_FILE_BASE, ath10k_bus_str(ar->hif.bus),
fw_api);
@ -1885,6 +1886,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->fw_stats_req_mask = WMI_10_4_STAT_PEER |
WMI_10_4_STAT_PEER_EXTD;
ar->max_spatial_stream = ar->hw_params.max_spatial_stream;
ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS;
if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
fw_file->fw_features))
@ -2123,6 +2125,14 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ar->running_fw->fw_file.fw_features))
val |= WMI_10_4_COEX_GPIO_SUPPORT;
if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
ar->wmi.svc_map))
val |= WMI_10_4_TDLS_EXPLICIT_MODE_ONLY;
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,
ar->wmi.svc_map))
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
status = ath10k_mac_ext_resource_config(ar, val);
if (status) {
ath10k_err(ar,

View File

@ -92,6 +92,7 @@ enum ath10k_bus {
ATH10K_BUS_PCI,
ATH10K_BUS_AHB,
ATH10K_BUS_SDIO,
ATH10K_BUS_USB,
};
static inline const char *ath10k_bus_str(enum ath10k_bus bus)
@ -103,6 +104,8 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
return "ahb";
case ATH10K_BUS_SDIO:
return "sdio";
case ATH10K_BUS_USB:
return "usb";
}
return "unknown";
@ -993,6 +996,8 @@ struct ath10k {
u32 reg_ack_cts_timeout_orig;
} fw_coverage;
u32 ampdu_reference;
void *ce_priv;
/* must be last */

View File

@ -40,6 +40,8 @@ enum ath10k_debug_mask {
ATH10K_DBG_AHB = 0x00008000,
ATH10K_DBG_SDIO = 0x00010000,
ATH10K_DBG_SDIO_DUMP = 0x00020000,
ATH10K_DBG_USB = 0x00040000,
ATH10K_DBG_USB_BULK = 0x00080000,
ATH10K_DBG_ANY = 0xffffffff,
};

View File

@ -890,16 +890,26 @@ static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
status->nss = 0;
status->encoding = RX_ENC_LEGACY;
status->bw = RATE_INFO_BW_20;
status->flag &= ~RX_FLAG_MACTIME_END;
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
status->flag &= ~(RX_FLAG_AMPDU_IS_LAST);
status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
status->ampdu_reference = ar->ampdu_reference;
ath10k_htt_rx_h_signal(ar, status, rxd);
ath10k_htt_rx_h_channel(ar, status, rxd, vdev_id);
ath10k_htt_rx_h_rates(ar, status, rxd);
}
if (is_last_ppdu)
if (is_last_ppdu) {
ath10k_htt_rx_h_mactime(ar, status, rxd);
/* set ampdu last segment flag */
status->flag |= RX_FLAG_AMPDU_IS_LAST;
ar->ampdu_reference++;
}
}
static const char * const tid_to_ac[] = {

View File

@ -720,6 +720,11 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
#define TARGET_10_4_IPHDR_PAD_CONFIG 1
#define TARGET_10_4_QWRAP_CONFIG 0
/* TDLS config */
#define TARGET_10_4_NUM_TDLS_VDEVS 1
#define TARGET_10_4_NUM_TDLS_BUFFER_STA 1
#define TARGET_10_4_NUM_TDLS_SLEEP_STA 1
/* Maximum number of Copy Engine's supported */
#define CE_COUNT_MAX 12

View File

@ -8197,8 +8197,11 @@ int ath10k_mac_register(struct ath10k *ar)
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
}
if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
}
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;

View File

@ -683,7 +683,7 @@ static int ath10k_sdio_mbox_rxmsg_pending_handler(struct ath10k *ar,
lookaheads[0] = msg_lookahead;
timeout = jiffies + SDIO_MBOX_PROCESSING_TIMEOUT_HZ;
while (time_before(jiffies, timeout)) {
do {
/* Try to allocate as many HTC RX packets indicated by
* n_lookaheads.
*/
@ -719,7 +719,7 @@ static int ath10k_sdio_mbox_rxmsg_pending_handler(struct ath10k *ar,
* performance in high throughput situations.
*/
*done = false;
}
} while (time_before(jiffies, timeout));
if (ret && (ret != -ECANCELED))
ath10k_warn(ar, "failed to get pending recv messages: %d\n",
@ -1336,11 +1336,11 @@ static void ath10k_sdio_irq_handler(struct sdio_func *func)
sdio_release_host(ar_sdio->func);
timeout = jiffies + ATH10K_SDIO_HIF_COMMUNICATION_TIMEOUT_HZ;
while (time_before(jiffies, timeout) && !done) {
do {
ret = ath10k_sdio_mbox_proc_pending_irqs(ar, &done);
if (ret)
break;
}
} while (time_before(jiffies, timeout) && !done);
sdio_claim_host(ar_sdio->func);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
*
* 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.
*/
#ifndef _USB_H_
#define _USB_H_
/* constants */
#define TX_URB_COUNT 32
#define RX_URB_COUNT 32
#define ATH10K_USB_RX_BUFFER_SIZE 4096
#define ATH10K_USB_PIPE_INVALID ATH10K_USB_PIPE_MAX
/* USB endpoint definitions */
#define ATH10K_USB_EP_ADDR_APP_CTRL_IN 0x81
#define ATH10K_USB_EP_ADDR_APP_DATA_IN 0x82
#define ATH10K_USB_EP_ADDR_APP_DATA2_IN 0x83
#define ATH10K_USB_EP_ADDR_APP_INT_IN 0x84
#define ATH10K_USB_EP_ADDR_APP_CTRL_OUT 0x01
#define ATH10K_USB_EP_ADDR_APP_DATA_LP_OUT 0x02
#define ATH10K_USB_EP_ADDR_APP_DATA_MP_OUT 0x03
#define ATH10K_USB_EP_ADDR_APP_DATA_HP_OUT 0x04
/* diagnostic command defnitions */
#define ATH10K_USB_CONTROL_REQ_SEND_BMI_CMD 1
#define ATH10K_USB_CONTROL_REQ_RECV_BMI_RESP 2
#define ATH10K_USB_CONTROL_REQ_DIAG_CMD 3
#define ATH10K_USB_CONTROL_REQ_DIAG_RESP 4
#define ATH10K_USB_CTRL_DIAG_CC_READ 0
#define ATH10K_USB_CTRL_DIAG_CC_WRITE 1
#define ATH10K_USB_IS_BULK_EP(attr) (((attr) & 3) == 0x02)
#define ATH10K_USB_IS_INT_EP(attr) (((attr) & 3) == 0x03)
#define ATH10K_USB_IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
#define ATH10K_USB_IS_DIR_IN(addr) ((addr) & 0x80)
struct ath10k_usb_ctrl_diag_cmd_write {
__le32 cmd;
__le32 address;
__le32 value;
__le32 padding;
} __packed;
struct ath10k_usb_ctrl_diag_cmd_read {
__le32 cmd;
__le32 address;
} __packed;
struct ath10k_usb_ctrl_diag_resp_read {
u8 value[4];
} __packed;
/* tx/rx pipes for usb */
enum ath10k_usb_pipe_id {
ATH10K_USB_PIPE_TX_CTRL = 0,
ATH10K_USB_PIPE_TX_DATA_LP,
ATH10K_USB_PIPE_TX_DATA_MP,
ATH10K_USB_PIPE_TX_DATA_HP,
ATH10K_USB_PIPE_RX_CTRL,
ATH10K_USB_PIPE_RX_DATA,
ATH10K_USB_PIPE_RX_DATA2,
ATH10K_USB_PIPE_RX_INT,
ATH10K_USB_PIPE_MAX
};
struct ath10k_usb_pipe {
struct list_head urb_list_head;
struct usb_anchor urb_submitted;
u32 urb_alloc;
u32 urb_cnt;
u32 urb_cnt_thresh;
unsigned int usb_pipe_handle;
u32 flags;
u8 ep_address;
u8 logical_pipe_num;
struct ath10k_usb *ar_usb;
u16 max_packet_size;
struct work_struct io_complete_work;
struct sk_buff_head io_comp_queue;
struct usb_endpoint_descriptor *ep_desc;
};
#define ATH10K_USB_PIPE_FLAG_TX BIT(0)
/* usb device object */
struct ath10k_usb {
/* protects pipe->urb_list_head and pipe->urb_cnt */
spinlock_t cs_lock;
struct usb_device *udev;
struct usb_interface *interface;
struct ath10k_usb_pipe pipes[ATH10K_USB_PIPE_MAX];
u8 *diag_cmd_buffer;
u8 *diag_resp_buffer;
struct ath10k *ar;
};
/* usb urb object */
struct ath10k_urb_context {
struct list_head link;
struct ath10k_usb_pipe *pipe;
struct sk_buff *skb;
struct ath10k *ar;
};
static inline struct ath10k_usb *ath10k_usb_priv(struct ath10k *ar)
{
return (struct ath10k_usb *)ar->drv_priv;
}
#endif

View File

@ -651,8 +651,6 @@ static struct wmi_cmd_map wmi_10_4_cmd_map = {
.gpio_output_cmdid = WMI_10_4_GPIO_OUTPUT_CMDID,
.pdev_get_temperature_cmdid = WMI_10_4_PDEV_GET_TEMPERATURE_CMDID,
.vdev_set_wmm_params_cmdid = WMI_CMD_UNSUPPORTED,
.tdls_set_state_cmdid = WMI_CMD_UNSUPPORTED,
.tdls_peer_update_cmdid = WMI_CMD_UNSUPPORTED,
.adaptive_qcs_cmdid = WMI_CMD_UNSUPPORTED,
.scan_update_request_cmdid = WMI_10_4_SCAN_UPDATE_REQUEST_CMDID,
.vdev_standby_response_cmdid = WMI_10_4_VDEV_STANDBY_RESPONSE_CMDID,
@ -711,6 +709,33 @@ static struct wmi_cmd_map wmi_10_4_cmd_map = {
.pdev_bss_chan_info_request_cmdid =
WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
.ext_resource_cfg_cmdid = WMI_10_4_EXT_RESOURCE_CFG_CMDID,
.vdev_set_ie_cmdid = WMI_10_4_VDEV_SET_IE_CMDID,
.set_lteu_config_cmdid = WMI_10_4_SET_LTEU_CONFIG_CMDID,
.atf_ssid_grouping_request_cmdid =
WMI_10_4_ATF_SSID_GROUPING_REQUEST_CMDID,
.peer_atf_ext_request_cmdid = WMI_10_4_PEER_ATF_EXT_REQUEST_CMDID,
.set_periodic_channel_stats_cfg_cmdid =
WMI_10_4_SET_PERIODIC_CHANNEL_STATS_CONFIG,
.peer_bwf_request_cmdid = WMI_10_4_PEER_BWF_REQUEST_CMDID,
.btcoex_cfg_cmdid = WMI_10_4_BTCOEX_CFG_CMDID,
.peer_tx_mu_txmit_count_cmdid = WMI_10_4_PEER_TX_MU_TXMIT_COUNT_CMDID,
.peer_tx_mu_txmit_rstcnt_cmdid = WMI_10_4_PEER_TX_MU_TXMIT_RSTCNT_CMDID,
.peer_gid_userpos_list_cmdid = WMI_10_4_PEER_GID_USERPOS_LIST_CMDID,
.pdev_check_cal_version_cmdid = WMI_10_4_PDEV_CHECK_CAL_VERSION_CMDID,
.coex_version_cfg_cmid = WMI_10_4_COEX_VERSION_CFG_CMID,
.pdev_get_rx_filter_cmdid = WMI_10_4_PDEV_GET_RX_FILTER_CMDID,
.pdev_extended_nss_cfg_cmdid = WMI_10_4_PDEV_EXTENDED_NSS_CFG_CMDID,
.vdev_set_scan_nac_rssi_cmdid = WMI_10_4_VDEV_SET_SCAN_NAC_RSSI_CMDID,
.prog_gpio_band_select_cmdid = WMI_10_4_PROG_GPIO_BAND_SELECT_CMDID,
.config_smart_logging_cmdid = WMI_10_4_CONFIG_SMART_LOGGING_CMDID,
.debug_fatal_condition_cmdid = WMI_10_4_DEBUG_FATAL_CONDITION_CMDID,
.get_tsf_timer_cmdid = WMI_10_4_GET_TSF_TIMER_CMDID,
.pdev_get_tpc_table_cmdid = WMI_10_4_PDEV_GET_TPC_TABLE_CMDID,
.vdev_sifs_trigger_time_cmdid = WMI_10_4_VDEV_SIFS_TRIGGER_TIME_CMDID,
.pdev_wds_entry_list_cmdid = WMI_10_4_PDEV_WDS_ENTRY_LIST_CMDID,
.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,
};
/* MAIN WMI VDEV param map */
@ -6473,6 +6498,7 @@ ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
cmd = (struct wmi_peer_create_cmd *)skb->data;
cmd->vdev_id = __cpu_to_le32(vdev_id);
ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
cmd->peer_type = __cpu_to_le32(peer_type);
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi peer create vdev_id %d peer_addr %pM\n",
@ -7803,14 +7829,28 @@ ath10k_wmi_10_4_ext_resource_config(struct ath10k *ar,
{
struct wmi_ext_resource_config_10_4_cmd *cmd;
struct sk_buff *skb;
u32 num_tdls_sleep_sta = 0;
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
if (!skb)
return ERR_PTR(-ENOMEM);
if (test_bit(WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, ar->wmi.svc_map))
num_tdls_sleep_sta = TARGET_10_4_NUM_TDLS_SLEEP_STA;
cmd = (struct wmi_ext_resource_config_10_4_cmd *)skb->data;
cmd->host_platform_config = __cpu_to_le32(type);
cmd->fw_feature_bitmap = __cpu_to_le32(fw_feature_bitmap);
cmd->wlan_gpio_priority = __cpu_to_le32(-1);
cmd->coex_version = __cpu_to_le32(WMI_NO_COEX_VERSION_SUPPORT);
cmd->coex_gpio_pin1 = __cpu_to_le32(-1);
cmd->coex_gpio_pin2 = __cpu_to_le32(-1);
cmd->coex_gpio_pin3 = __cpu_to_le32(-1);
cmd->num_tdls_vdevs = __cpu_to_le32(TARGET_10_4_NUM_TDLS_VDEVS);
cmd->num_tdls_conn_table_entries = __cpu_to_le32(20);
cmd->max_tdls_concurrent_sleep_sta = __cpu_to_le32(num_tdls_sleep_sta);
cmd->max_tdls_concurrent_buffer_sta =
__cpu_to_le32(TARGET_10_4_NUM_TDLS_BUFFER_STA);
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi ext resource config host type %d firmware feature bitmap %08x\n",
@ -7818,6 +7858,124 @@ ath10k_wmi_10_4_ext_resource_config(struct ath10k *ar,
return skb;
}
static struct sk_buff *
ath10k_wmi_10_4_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
enum wmi_tdls_state state)
{
struct wmi_10_4_tdls_set_state_cmd *cmd;
struct sk_buff *skb;
u32 options = 0;
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
if (!skb)
return ERR_PTR(-ENOMEM);
if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map))
state = WMI_TDLS_ENABLE_PASSIVE;
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
options |= WMI_TDLS_BUFFER_STA_EN;
cmd = (struct wmi_10_4_tdls_set_state_cmd *)skb->data;
cmd->vdev_id = __cpu_to_le32(vdev_id);
cmd->state = __cpu_to_le32(state);
cmd->notification_interval_ms = __cpu_to_le32(5000);
cmd->tx_discovery_threshold = __cpu_to_le32(100);
cmd->tx_teardown_threshold = __cpu_to_le32(5);
cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
cmd->rssi_delta = __cpu_to_le32(-20);
cmd->tdls_options = __cpu_to_le32(options);
cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
cmd->teardown_notification_ms = __cpu_to_le32(10);
cmd->tdls_peer_kickout_threshold = __cpu_to_le32(96);
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi update fw tdls state %d for vdev %i\n",
state, vdev_id);
return skb;
}
static u32 ath10k_wmi_prepare_peer_qos(u8 uapsd_queues, u8 sp)
{
u32 peer_qos = 0;
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
peer_qos |= WMI_TDLS_PEER_QOS_AC_VO;
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
peer_qos |= WMI_TDLS_PEER_QOS_AC_VI;
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
peer_qos |= WMI_TDLS_PEER_QOS_AC_BK;
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
peer_qos |= WMI_TDLS_PEER_QOS_AC_BE;
peer_qos |= SM(sp, WMI_TDLS_PEER_SP);
return peer_qos;
}
static struct sk_buff *
ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
const struct wmi_tdls_peer_update_cmd_arg *arg,
const struct wmi_tdls_peer_capab_arg *cap,
const struct wmi_channel_arg *chan_arg)
{
struct wmi_10_4_tdls_peer_update_cmd *cmd;
struct wmi_tdls_peer_capabilities *peer_cap;
struct wmi_channel *chan;
struct sk_buff *skb;
u32 peer_qos;
int len, chan_len;
int i;
/* tdls peer update cmd has place holder for one channel*/
chan_len = cap->peer_chan_len ? (cap->peer_chan_len - 1) : 0;
len = sizeof(*cmd) + chan_len * sizeof(*chan);
skb = ath10k_wmi_alloc_skb(ar, len);
if (!skb)
return ERR_PTR(-ENOMEM);
memset(skb->data, 0, sizeof(*cmd));
cmd = (struct wmi_10_4_tdls_peer_update_cmd *)skb->data;
cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
cmd->peer_state = __cpu_to_le32(arg->peer_state);
peer_qos = ath10k_wmi_prepare_peer_qos(cap->peer_uapsd_queues,
cap->peer_max_sp);
peer_cap = &cmd->peer_capab;
peer_cap->peer_qos = __cpu_to_le32(peer_qos);
peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
peer_cap->peer_operclass[i] = cap->peer_operclass[i];
peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
for (i = 0; i < cap->peer_chan_len; i++) {
chan = (struct wmi_channel *)&peer_cap->peer_chan_list[i];
ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
}
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi tdls peer update vdev %i state %d n_chans %u\n",
arg->vdev_id, arg->peer_state, cap->peer_chan_len);
return skb;
}
static struct sk_buff *
ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
{
@ -8197,6 +8355,8 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
.ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
.gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state,
.gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
/* shared with 10.2 */
.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,

View File

@ -184,6 +184,17 @@ enum wmi_service {
WMI_SERVICE_TX_MODE_PUSH_ONLY,
WMI_SERVICE_TX_MODE_PUSH_PULL,
WMI_SERVICE_TX_MODE_DYNAMIC,
WMI_SERVICE_VDEV_RX_FILTER,
WMI_SERVICE_BTCOEX,
WMI_SERVICE_CHECK_CAL_VERSION,
WMI_SERVICE_DBGLOG_WARN2,
WMI_SERVICE_BTCOEX_DUTY_CYCLE,
WMI_SERVICE_4_WIRE_COEX_SUPPORT,
WMI_SERVICE_EXTENDED_NSS_SUPPORT,
WMI_SERVICE_PROG_GPIO_BAND_SELECT,
WMI_SERVICE_SMART_LOGGING_SUPPORT,
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
/* keep last */
WMI_SERVICE_MAX,
@ -310,6 +321,21 @@ enum wmi_10_4_service {
WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
WMI_10_4_SERVICE_VDEV_RX_FILTER,
WMI_10_4_SERVICE_BTCOEX,
WMI_10_4_SERVICE_CHECK_CAL_VERSION,
WMI_10_4_SERVICE_DBGLOG_WARN2,
WMI_10_4_SERVICE_BTCOEX_DUTY_CYCLE,
WMI_10_4_SERVICE_4_WIRE_COEX_SUPPORT,
WMI_10_4_SERVICE_EXTENDED_NSS_SUPPORT,
WMI_10_4_SERVICE_PROG_GPIO_BAND_SELECT,
WMI_10_4_SERVICE_SMART_LOGGING_SUPPORT,
WMI_10_4_SERVICE_TDLS,
WMI_10_4_SERVICE_TDLS_OFFCHAN,
WMI_10_4_SERVICE_TDLS_UAPSD_BUFFER_STA,
WMI_10_4_SERVICE_TDLS_UAPSD_SLEEP_STA,
WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
};
static inline char *wmi_service_name(int service_id)
@ -408,6 +434,16 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
SVCSTR(WMI_SERVICE_VDEV_RX_FILTER);
SVCSTR(WMI_SERVICE_CHECK_CAL_VERSION);
SVCSTR(WMI_SERVICE_DBGLOG_WARN2);
SVCSTR(WMI_SERVICE_BTCOEX_DUTY_CYCLE);
SVCSTR(WMI_SERVICE_4_WIRE_COEX_SUPPORT);
SVCSTR(WMI_SERVICE_EXTENDED_NSS_SUPPORT);
SVCSTR(WMI_SERVICE_PROG_GPIO_BAND_SELECT);
SVCSTR(WMI_SERVICE_SMART_LOGGING_SUPPORT);
SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
default:
return NULL;
}
@ -420,9 +456,20 @@ static inline char *wmi_service_name(int service_id)
__le32_to_cpu((wmi_svc_bmap)[(svc_id) / (sizeof(u32))]) & \
BIT((svc_id) % (sizeof(u32))))
/* This extension is required to accommodate new services, current limit
* for wmi_services is 64 as target is using only 4-bits of each 32-bit
* wmi_service word. Extending this to make use of remaining unused bits
* for new services.
*/
#define WMI_EXT_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
((svc_id) >= (len) && \
__le32_to_cpu((wmi_svc_bmap)[((svc_id) - (len)) / 28]) & \
BIT(((((svc_id) - (len)) % 28) & 0x1f) + 4))
#define SVCMAP(x, y, len) \
do { \
if (WMI_SERVICE_IS_ENABLED((in), (x), (len))) \
if ((WMI_SERVICE_IS_ENABLED((in), (x), (len))) || \
(WMI_EXT_SERVICE_IS_ENABLED((in), (x), (len)))) \
__set_bit(y, out); \
} while (0)
@ -663,6 +710,36 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
WMI_SERVICE_TX_MODE_PUSH_PULL, len);
SVCMAP(WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
WMI_SERVICE_TX_MODE_DYNAMIC, len);
SVCMAP(WMI_10_4_SERVICE_VDEV_RX_FILTER,
WMI_SERVICE_VDEV_RX_FILTER, len);
SVCMAP(WMI_10_4_SERVICE_BTCOEX,
WMI_SERVICE_BTCOEX, len);
SVCMAP(WMI_10_4_SERVICE_CHECK_CAL_VERSION,
WMI_SERVICE_CHECK_CAL_VERSION, len);
SVCMAP(WMI_10_4_SERVICE_DBGLOG_WARN2,
WMI_SERVICE_DBGLOG_WARN2, len);
SVCMAP(WMI_10_4_SERVICE_BTCOEX_DUTY_CYCLE,
WMI_SERVICE_BTCOEX_DUTY_CYCLE, len);
SVCMAP(WMI_10_4_SERVICE_4_WIRE_COEX_SUPPORT,
WMI_SERVICE_4_WIRE_COEX_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_EXTENDED_NSS_SUPPORT,
WMI_SERVICE_EXTENDED_NSS_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_PROG_GPIO_BAND_SELECT,
WMI_SERVICE_PROG_GPIO_BAND_SELECT, len);
SVCMAP(WMI_10_4_SERVICE_SMART_LOGGING_SUPPORT,
WMI_SERVICE_SMART_LOGGING_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_TDLS,
WMI_SERVICE_TDLS, len);
SVCMAP(WMI_10_4_SERVICE_TDLS_OFFCHAN,
WMI_SERVICE_TDLS_OFFCHAN, len);
SVCMAP(WMI_10_4_SERVICE_TDLS_UAPSD_BUFFER_STA,
WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, len);
SVCMAP(WMI_10_4_SERVICE_TDLS_UAPSD_SLEEP_STA,
WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, len);
SVCMAP(WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, len);
SVCMAP(WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
}
#undef SVCMAP
@ -837,6 +914,29 @@ struct wmi_cmd_map {
u32 pdev_bss_chan_info_request_cmdid;
u32 pdev_enable_adaptive_cca_cmdid;
u32 ext_resource_cfg_cmdid;
u32 vdev_set_ie_cmdid;
u32 set_lteu_config_cmdid;
u32 atf_ssid_grouping_request_cmdid;
u32 peer_atf_ext_request_cmdid;
u32 set_periodic_channel_stats_cfg_cmdid;
u32 peer_bwf_request_cmdid;
u32 btcoex_cfg_cmdid;
u32 peer_tx_mu_txmit_count_cmdid;
u32 peer_tx_mu_txmit_rstcnt_cmdid;
u32 peer_gid_userpos_list_cmdid;
u32 pdev_check_cal_version_cmdid;
u32 coex_version_cfg_cmid;
u32 pdev_get_rx_filter_cmdid;
u32 pdev_extended_nss_cfg_cmdid;
u32 vdev_set_scan_nac_rssi_cmdid;
u32 prog_gpio_band_select_cmdid;
u32 config_smart_logging_cmdid;
u32 debug_fatal_condition_cmdid;
u32 get_tsf_timer_cmdid;
u32 pdev_get_tpc_table_cmdid;
u32 vdev_sifs_trigger_time_cmdid;
u32 pdev_wds_entry_list_cmdid;
u32 tdls_set_offchan_mode_cmdid;
};
/*
@ -1647,6 +1747,29 @@ enum wmi_10_4_cmd_id {
WMI_10_4_EXT_RESOURCE_CFG_CMDID,
WMI_10_4_VDEV_SET_IE_CMDID,
WMI_10_4_SET_LTEU_CONFIG_CMDID,
WMI_10_4_ATF_SSID_GROUPING_REQUEST_CMDID,
WMI_10_4_PEER_ATF_EXT_REQUEST_CMDID,
WMI_10_4_SET_PERIODIC_CHANNEL_STATS_CONFIG,
WMI_10_4_PEER_BWF_REQUEST_CMDID,
WMI_10_4_BTCOEX_CFG_CMDID,
WMI_10_4_PEER_TX_MU_TXMIT_COUNT_CMDID,
WMI_10_4_PEER_TX_MU_TXMIT_RSTCNT_CMDID,
WMI_10_4_PEER_GID_USERPOS_LIST_CMDID,
WMI_10_4_PDEV_CHECK_CAL_VERSION_CMDID,
WMI_10_4_COEX_VERSION_CFG_CMID,
WMI_10_4_PDEV_GET_RX_FILTER_CMDID,
WMI_10_4_PDEV_EXTENDED_NSS_CFG_CMDID,
WMI_10_4_VDEV_SET_SCAN_NAC_RSSI_CMDID,
WMI_10_4_PROG_GPIO_BAND_SELECT_CMDID,
WMI_10_4_CONFIG_SMART_LOGGING_CMDID,
WMI_10_4_DEBUG_FATAL_CONDITION_CMDID,
WMI_10_4_GET_TSF_TIMER_CMDID,
WMI_10_4_PDEV_GET_TPC_TABLE_CMDID,
WMI_10_4_VDEV_SIFS_TRIGGER_TIME_CMDID,
WMI_10_4_PDEV_WDS_ENTRY_LIST_CMDID,
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_UTF_CMDID = WMI_10_4_END_CMDID - 1,
};
@ -1710,6 +1833,18 @@ enum wmi_10_4_event_id {
WMI_10_4_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID,
WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID,
WMI_10_4_MU_REPORT_EVENTID,
WMI_10_4_TX_DATA_TRAFFIC_CTRL_EVENTID,
WMI_10_4_PEER_TX_MU_TXMIT_COUNT_EVENTID,
WMI_10_4_PEER_GID_USERPOS_LIST_EVENTID,
WMI_10_4_PDEV_CHECK_CAL_VERSION_EVENTID,
WMI_10_4_ATF_PEER_STATS_EVENTID,
WMI_10_4_PDEV_GET_RX_FILTER_EVENTID,
WMI_10_4_NAC_RSSI_EVENTID,
WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID,
WMI_10_4_GET_TSF_TIMER_RESP_EVENTID,
WMI_10_4_PDEV_TPC_TABLE_EVENTID,
WMI_10_4_PDEV_WDS_ENTRY_LIST_EVENTID,
WMI_10_4_TDLS_PEER_EVENTID,
WMI_10_4_PDEV_UTF_EVENTID = WMI_10_4_END_EVENTID - 1,
};
@ -2718,6 +2853,18 @@ struct wmi_resource_config_10_4 {
__le32 qwrap_config;
} __packed;
enum wmi_coex_version {
WMI_NO_COEX_VERSION_SUPPORT = 0,
/* 3 wire coex support*/
WMI_COEX_VERSION_1 = 1,
/* 2.5 wire coex support*/
WMI_COEX_VERSION_2 = 2,
/* 2.5 wire coex with duty cycle support */
WMI_COEX_VERSION_3 = 3,
/* 4 wire coex support*/
WMI_COEX_VERSION_4 = 4,
};
/**
* enum wmi_10_4_feature_mask - WMI 10.4 feature enable/disable flags
* @WMI_10_4_LTEU_SUPPORT: LTEU config
@ -2726,6 +2873,14 @@ struct wmi_resource_config_10_4 {
* @WMI_10_4_AUX_RADIO_CHAN_LOAD_INTF: AUX Radio Enhancement for chan load scan
* @WMI_10_4_BSS_CHANNEL_INFO_64: BSS channel info stats
* @WMI_10_4_PEER_STATS: Per station stats
* @WMI_10_4_VDEV_STATS: Per vdev stats
* @WMI_10_4_TDLS: Implicit TDLS support in firmware enable/disable
* @WMI_10_4_TDLS_OFFCHAN: TDLS offchannel support enable/disable
* @WMI_10_4_TDLS_UAPSD_BUFFER_STA: TDLS buffer sta support enable/disable
* @WMI_10_4_TDLS_UAPSD_SLEEP_STA: TDLS sleep sta support enable/disable
* @WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE: TDLS connection tracker in host
* enable/disable
* @WMI_10_4_TDLS_EXPLICIT_MODE_ONLY:Explicit TDLS mode enable/disable
*/
enum wmi_10_4_feature_mask {
WMI_10_4_LTEU_SUPPORT = BIT(0),
@ -2734,6 +2889,14 @@ enum wmi_10_4_feature_mask {
WMI_10_4_AUX_RADIO_CHAN_LOAD_INTF = BIT(3),
WMI_10_4_BSS_CHANNEL_INFO_64 = BIT(4),
WMI_10_4_PEER_STATS = BIT(5),
WMI_10_4_VDEV_STATS = BIT(6),
WMI_10_4_TDLS = BIT(7),
WMI_10_4_TDLS_OFFCHAN = BIT(8),
WMI_10_4_TDLS_UAPSD_BUFFER_STA = BIT(9),
WMI_10_4_TDLS_UAPSD_SLEEP_STA = BIT(10),
WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE = BIT(11),
WMI_10_4_TDLS_EXPLICIT_MODE_ONLY = BIT(12),
};
struct wmi_ext_resource_config_10_4_cmd {
@ -2741,6 +2904,22 @@ struct wmi_ext_resource_config_10_4_cmd {
__le32 host_platform_config;
/* see enum wmi_10_4_feature_mask */
__le32 fw_feature_bitmap;
/* WLAN priority GPIO number */
__le32 wlan_gpio_priority;
/* see enum wmi_coex_version */
__le32 coex_version;
/* COEX GPIO config */
__le32 coex_gpio_pin1;
__le32 coex_gpio_pin2;
__le32 coex_gpio_pin3;
/* number of vdevs allowed to perform tdls */
__le32 num_tdls_vdevs;
/* number of peers to track per TDLS vdev */
__le32 num_tdls_conn_table_entries;
/* number of tdls sleep sta supported */
__le32 max_tdls_concurrent_sleep_sta;
/* number of tdls buffer sta supported */
__le32 max_tdls_concurrent_buffer_sta;
};
/* strucutre describing host memory chunk. */
@ -5698,6 +5877,7 @@ struct wmi_tbtt_offset_event {
struct wmi_peer_create_cmd {
__le32 vdev_id;
struct wmi_mac_addr peer_macaddr;
__le32 peer_type;
} __packed;
enum wmi_peer_type {
@ -6556,6 +6736,22 @@ struct wmi_tdls_peer_update_cmd_arg {
#define WMI_TDLS_MAX_SUPP_OPER_CLASSES 32
#define WMI_TDLS_PEER_SP_MASK 0x60
#define WMI_TDLS_PEER_SP_LSB 5
enum wmi_tdls_options {
WMI_TDLS_OFFCHAN_EN = BIT(0),
WMI_TDLS_BUFFER_STA_EN = BIT(1),
WMI_TDLS_SLEEP_STA_EN = BIT(2),
};
enum {
WMI_TDLS_PEER_QOS_AC_VO = BIT(0),
WMI_TDLS_PEER_QOS_AC_VI = BIT(1),
WMI_TDLS_PEER_QOS_AC_BK = BIT(2),
WMI_TDLS_PEER_QOS_AC_BE = BIT(3),
};
struct wmi_tdls_peer_capab_arg {
u8 peer_uapsd_queues;
u8 peer_max_sp;
@ -6571,6 +6767,79 @@ struct wmi_tdls_peer_capab_arg {
u32 pref_offchan_bw;
};
struct wmi_10_4_tdls_set_state_cmd {
__le32 vdev_id;
__le32 state;
__le32 notification_interval_ms;
__le32 tx_discovery_threshold;
__le32 tx_teardown_threshold;
__le32 rssi_teardown_threshold;
__le32 rssi_delta;
__le32 tdls_options;
__le32 tdls_peer_traffic_ind_window;
__le32 tdls_peer_traffic_response_timeout_ms;
__le32 tdls_puapsd_mask;
__le32 tdls_puapsd_inactivity_time_ms;
__le32 tdls_puapsd_rx_frame_threshold;
__le32 teardown_notification_ms;
__le32 tdls_peer_kickout_threshold;
} __packed;
struct wmi_tdls_peer_capabilities {
__le32 peer_qos;
__le32 buff_sta_support;
__le32 off_chan_support;
__le32 peer_curr_operclass;
__le32 self_curr_operclass;
__le32 peer_chan_len;
__le32 peer_operclass_len;
u8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES];
__le32 is_peer_responder;
__le32 pref_offchan_num;
__le32 pref_offchan_bw;
struct wmi_channel peer_chan_list[1];
} __packed;
struct wmi_10_4_tdls_peer_update_cmd {
__le32 vdev_id;
struct wmi_mac_addr peer_macaddr;
__le32 peer_state;
__le32 reserved[4];
struct wmi_tdls_peer_capabilities peer_capab;
} __packed;
enum wmi_tdls_peer_reason {
WMI_TDLS_TEARDOWN_REASON_TX,
WMI_TDLS_TEARDOWN_REASON_RSSI,
WMI_TDLS_TEARDOWN_REASON_SCAN,
WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE,
WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT,
WMI_TDLS_TEARDOWN_REASON_BAD_PTR,
WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE,
WMI_TDLS_ENTER_BUF_STA,
WMI_TDLS_EXIT_BUF_STA,
WMI_TDLS_ENTER_BT_BUSY_MODE,
WMI_TDLS_EXIT_BT_BUSY_MODE,
WMI_TDLS_SCAN_STARTED_EVENT,
WMI_TDLS_SCAN_COMPLETED_EVENT,
};
enum wmi_tdls_peer_notification {
WMI_TDLS_SHOULD_DISCOVER,
WMI_TDLS_SHOULD_TEARDOWN,
WMI_TDLS_PEER_DISCONNECTED,
WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION,
};
struct wmi_tdls_peer_event {
struct wmi_mac_addr peer_macaddr;
/* see enum wmi_tdls_peer_notification*/
__le32 peer_status;
/* see enum wmi_tdls_peer_reason */
__le32 peer_reason;
__le32 vdev_id;
} __packed;
enum wmi_txbf_conf {
WMI_TXBF_CONF_UNSUPPORTED,
WMI_TXBF_CONF_BEFORE_ASSOC,

View File

@ -1452,7 +1452,7 @@ int ath9k_init_debug(struct ath_hw *ah)
#endif
#ifdef CONFIG_ATH9K_DYNACK
debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
debugfs_create_file("ack_to", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_ackto);
#endif
debugfs_create_file("tpc", S_IRUSR | S_IWUSR,

View File

@ -388,6 +388,11 @@ static const struct pci_device_id ath_pci_id_table[] = {
PCI_VENDOR_ID_DELL,
0x020B),
.driver_data = ATH9K_PCI_WOW },
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
0x0034,
PCI_VENDOR_ID_DELL,
0x0300),
.driver_data = ATH9K_PCI_WOW },
/* Killer Wireless (2x2) */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,

View File

@ -64,7 +64,7 @@ MODULE_ALIAS("arusb_lnx");
* http://wireless.kernel.org/en/users/Drivers/ar9170/devices ),
* whenever you add a new device.
*/
static struct usb_device_id carl9170_usb_ids[] = {
static const struct usb_device_id carl9170_usb_ids[] = {
/* Atheros 9170 */
{ USB_DEVICE(0x0cf3, 0x9170) },
/* Atheros TG121N */

View File

@ -289,6 +289,11 @@ static int wcn36xx_dxe_fill_skb(struct device *dev, struct wcn36xx_dxe_ctl *ctl)
skb_tail_pointer(skb),
WCN36XX_PKT_SIZE,
DMA_FROM_DEVICE);
if (dma_mapping_error(dev, dxe->dst_addr_l)) {
dev_err(dev, "unable to map skb\n");
kfree_skb(skb);
return -ENOMEM;
}
ctl->skb = skb;
return 0;

View File

@ -130,7 +130,7 @@ MODULE_FIRMWARE("atmel_at76c505amx-rfmd.bin");
#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
static struct usb_device_id dev_table[] = {
static const struct usb_device_id dev_table[] = {
/*
* at76c503-i3861
*/

View File

@ -1105,6 +1105,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);

View File

@ -3940,6 +3940,7 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
{
s32 err;
s32 wpa_val;
/* set auth */
err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
@ -3954,7 +3955,11 @@ static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
return err;
}
/* set upper-layer auth */
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
if (brcmf_is_ibssmode(ifp->vif))
wpa_val = WPA_AUTH_NONE;
else
wpa_val = WPA_AUTH_DISABLED;
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
if (err < 0) {
brcmf_err("wpa_auth error %d\n", err);
return err;
@ -5693,10 +5698,13 @@ brcmf_notify_roaming_status(struct brcmf_if *ifp,
u32 status = e->status;
if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state)) {
brcmf_bss_roaming_done(cfg, ifp->ndev, e);
else
} else {
brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
brcmf_net_setcarrier(ifp, true);
}
}
return 0;
@ -6456,6 +6464,8 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
if (p2p) {
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
combo[c].num_different_channels = 2;
else
combo[c].num_different_channels = 1;
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE);
@ -6465,10 +6475,10 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
} else {
combo[c].num_different_channels = 1;
c0_limits[i].max = 1;
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
}
combo[c].num_different_channels = 1;
combo[c].max_interfaces = i;
combo[c].n_limits = i;
combo[c].limits = c0_limits;

View File

@ -690,6 +690,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
case BRCM_CC_4365_CHIP_ID:
case BRCM_CC_4366_CHIP_ID:
return 0x200000;
case CY_CC_4373_CHIP_ID:
return 0x160000;
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;

View File

@ -618,6 +618,7 @@ BRCMF_FW_NVRAM_DEF(43430A1, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt");
BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt");
BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt");
BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt");
BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt");
static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
@ -636,7 +637,8 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356)
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
};
static void pkt_align(struct sk_buff *p, int len, int align)

View File

@ -50,6 +50,7 @@ BRCMF_FW_DEF(43143, "brcmfmac43143.bin");
BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin");
BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin");
BRCMF_FW_DEF(43569, "brcmfmac43569.bin");
BRCMF_FW_DEF(4373, "brcmfmac4373.bin");
static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
@ -58,7 +59,8 @@ static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43238_CHIP_ID, 0x00000008, 43236B),
BRCMF_FW_ENTRY(BRCM_CC_43242_CHIP_ID, 0xFFFFFFFF, 43242A),
BRCMF_FW_ENTRY(BRCM_CC_43566_CHIP_ID, 0xFFFFFFFF, 43569),
BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43569)
BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43569),
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
};
#define TRX_MAGIC 0x30524448 /* "HDR0" */
@ -1463,15 +1465,20 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
#define LINKSYS_USB_DEVICE(dev_id) \
{ USB_DEVICE(BRCM_USB_VENDOR_ID_LINKSYS, dev_id) }
static struct usb_device_id brcmf_usb_devid_table[] = {
#define CYPRESS_USB_DEVICE(dev_id) \
{ USB_DEVICE(CY_USB_VENDOR_ID_CYPRESS, dev_id) }
static const struct usb_device_id brcmf_usb_devid_table[] = {
BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
LINKSYS_USB_DEVICE(BRCM_USB_43235_LINKSYS_DEVICE_ID),
CYPRESS_USB_DEVICE(CY_USB_4373_DEVICE_ID),
{ USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) },
/* special entry for device with firmware loaded and running */
BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
CYPRESS_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
{ /* end: all zeroes */ }
};

View File

@ -23,6 +23,7 @@
#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
#define BRCM_USB_VENDOR_ID_LG 0x043e
#define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1
#define CY_USB_VENDOR_ID_CYPRESS 0x04b4
#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
/* Chipcommon Core Chip IDs */
@ -57,6 +58,7 @@
#define BRCM_CC_4365_CHIP_ID 0x4365
#define BRCM_CC_4366_CHIP_ID 0x4366
#define BRCM_CC_4371_CHIP_ID 0x4371
#define CY_CC_4373_CHIP_ID 0x4373
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
@ -66,6 +68,7 @@
#define BRCM_USB_43242_LG_DEVICE_ID 0x3101
#define BRCM_USB_43569_DEVICE_ID 0xbd27
#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
#define CY_USB_4373_DEVICE_ID 0xbd29
/* PCIE Device IDs */
#define BRCM_PCIE_4350_DEVICE_ID 0x43a3

View File

@ -340,7 +340,7 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
struct ipw2100_fw *fw);
static void ipw2100_wx_event_work(struct work_struct *work);
static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
static struct iw_handler_def ipw2100_wx_handler_def;
static const struct iw_handler_def ipw2100_wx_handler_def;
static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
{
@ -8273,7 +8273,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
return (struct iw_statistics *)NULL;
}
static struct iw_handler_def ipw2100_wx_handler_def = {
static const struct iw_handler_def ipw2100_wx_handler_def = {
.standard = ipw2100_wx_handlers,
.num_standard = ARRAY_SIZE(ipw2100_wx_handlers),
.num_private = ARRAY_SIZE(ipw2100_private_handler),

View File

@ -3209,7 +3209,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
struct fw_chunk *chunk;
int total_nr = 0;
int i;
struct pci_pool *pool;
struct dma_pool *pool;
void **virts;
dma_addr_t *phys;
@ -3226,9 +3226,10 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
kfree(virts);
return -ENOMEM;
}
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
pool = dma_pool_create("ipw2200", &priv->pci_dev->dev, CB_MAX_LENGTH, 0,
0);
if (!pool) {
IPW_ERROR("pci_pool_create failed\n");
IPW_ERROR("dma_pool_create failed\n");
kfree(phys);
kfree(virts);
return -ENOMEM;
@ -3253,7 +3254,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;
for (i = 0; i < nr; i++) {
virts[total_nr] = pci_pool_alloc(pool, GFP_KERNEL,
virts[total_nr] = dma_pool_alloc(pool, GFP_KERNEL,
&phys[total_nr]);
if (!virts[total_nr]) {
ret = -ENOMEM;
@ -3297,9 +3298,9 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
}
out:
for (i = 0; i < total_nr; i++)
pci_pool_free(pool, virts[i], phys[i]);
dma_pool_free(pool, virts[i], phys[i]);
pci_pool_destroy(pool);
dma_pool_destroy(pool);
kfree(phys);
kfree(virts);
@ -10008,7 +10009,7 @@ static iw_handler ipw_priv_handler[] = {
#endif
};
static struct iw_handler_def ipw_wx_handler_def = {
static const struct iw_handler_def ipw_wx_handler_def = {
.standard = ipw_wx_handlers,
.num_standard = ARRAY_SIZE(ipw_wx_handlers),
.num_private = ARRAY_SIZE(ipw_priv_handler),

View File

@ -12,7 +12,7 @@ iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/a000.o
iwlwifi-objs += iwl-trans.o
iwlwifi-objs += fw/notif-wait.o
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
iwlwifi-objs += $(iwlwifi-m)

View File

@ -75,11 +75,20 @@
#define IWL_A000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-"
#define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
#define IWL_A000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
#define IWL_A000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-"
#define IWL_A000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
#define IWL_A000_HR_MODULE_FIRMWARE(api) \
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_JF_MODULE_FIRMWARE(api) \
IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_JF_B0_FW_PRE "-" __stringify(api) ".ucode"
#define IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_HR_A0_FW_PRE "-" __stringify(api) ".ucode"
#define NVM_HW_SECTION_NUM_FAMILY_A000 10
@ -168,5 +177,38 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
IWL_DEVICE_A000,
.ht_params = &iwl_a000_ht_params,
.nvm_ver = IWL_A000_NVM_VERSION,
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_JF_B0_FW_PRE,
IWL_DEVICE_A000,
.ht_params = &iwl_a000_ht_params,
.nvm_ver = IWL_A000_NVM_VERSION,
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_HR_A0_FW_PRE,
IWL_DEVICE_A000,
.ht_params = &iwl_a000_ht_params,
.nvm_ver = IWL_A000_NVM_VERSION,
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
};
MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));

View File

@ -311,11 +311,6 @@ enum {
/**
* rate_n_flags Tx antenna masks
* 4965 has 2 transmitters
* 5100 has 1 transmitter B
* 5150 has 1 transmitter A
* 5300 has 3 transmitters
* 5350 has 3 transmitters
* bit14:16
*/
#define RATE_MCS_ANT_POS 14
@ -1230,7 +1225,6 @@ struct iwl_rx_mpdu_res_start {
*/
/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
*/
@ -1540,7 +1534,7 @@ struct iwl_link_qual_general_params {
/* Best single antenna to use for single stream (legacy, SISO). */
u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */
/* Best antennas to use for MIMO (unused for 4965, assumes both). */
/* Best antennas to use for MIMO */
u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */
/*

View File

@ -76,7 +76,6 @@ enum iwl_bt_coex_lut_type {
BT_COEX_INVALID_LUT = 0xff,
}; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
#define BT_COEX_CORUN_LUT_SIZE (32)
#define BT_REDUCED_TX_POWER_BIT BIT(7)
enum iwl_bt_coex_mode {
@ -106,18 +105,6 @@ struct iwl_bt_coex_cmd {
__le32 enabled_modules;
} __packed; /* BT_COEX_CMD_API_S_VER_6 */
/**
* struct iwl_bt_coex_corun_lut_update - bt coex update the corun lut
* @corun_lut20: co-running 20 MHz LUT configuration
* @corun_lut40: co-running 40 MHz LUT configuration
*
* The structure is used for the BT_COEX_UPDATE_CORUN_LUT command.
*/
struct iwl_bt_coex_corun_lut_update_cmd {
__le32 corun_lut20[BT_COEX_CORUN_LUT_SIZE];
__le32 corun_lut40[BT_COEX_CORUN_LUT_SIZE];
} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
/**
* struct iwl_bt_coex_reduced_txp_update_cmd
* @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
@ -191,6 +178,7 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, ACL_STATE, 3, 1),
BT_MBOX(3, MSTR_STATE, 4, 1),
BT_MBOX(3, OBX_STATE, 5, 1),
BT_MBOX(3, A2DP_SRC, 6, 1),
BT_MBOX(3, OPEN_CON_2, 8, 2),
BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
@ -200,10 +188,21 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, UPDATE_REQUEST, 21, 1),
};
enum iwl_bt_mxbox_dw4 {
BT_MBOX(4, ATS_BT_INTERVAL, 0, 7),
BT_MBOX(4, ATS_BT_ACTIVE_MAX_TH, 7, 7),
};
#define BT_MBOX_MSG(_notif, _num, _field) \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
#define BT_MBOX_PRINT(_num, _field, _end) \
pos += scnprintf(buf + pos, bufsz - pos, \
"\t%s: %d%s", \
#_field, \
BT_MBOX_MSG(notif, _num, _field), \
true ? "\n" : ", ");
enum iwl_bt_activity_grading {
BT_OFF = 0,
BT_ON_NO_CONNECTION = 1,
@ -220,11 +219,30 @@ enum iwl_bt_ci_compliance {
BT_CI_COMPLIANCE_BOTH = 3,
}; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */
#define IWL_COEX_IS_TTC_ON(_ttc_rrc_status, _phy_id) \
(_ttc_rrc_status & BIT(_phy_id))
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
* @mbox_msg: message from BT to WiFi
* @msg_idx: the index of the message
* @bt_ci_compliance: enum %iwl_bt_ci_compliance
* @primary_ch_lut: LUT used for primary channel &enum iwl_bt_coex_lut_type
* @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type
* @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading
* @ttc_status: is TTC enabled - one bit per PHY
* @rrc_status: is RRC enabled - one bit per PHY
* @reserved: reserved
*/
struct iwl_bt_coex_profile_notif {
__le32 mbox_msg[8];
__le32 msg_idx;
__le32 bt_ci_compliance;
#define IWL_COEX_IS_RRC_ON(_ttc_rrc_status, _phy_id) \
((_ttc_rrc_status >> 4) & BIT(_phy_id))
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
u8 ttc_status;
u8 rrc_status;
__le16 reserved;
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_5 */
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
@ -234,10 +252,11 @@ enum iwl_bt_ci_compliance {
* @primary_ch_lut: LUT used for primary channel &enum iwl_bt_coex_lut_type
* @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type
* @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading
* @ttc_rrc_status: is TTC or RRC enabled - one bit per PHY
* @ttc_status: is TTC enabled - one bit per PHY
* @rrc_status: is RRC enabled - one bit per PHY
* @reserved: reserved
*/
struct iwl_bt_coex_profile_notif {
struct iwl_bt_coex_profile_notif_v4 {
__le32 mbox_msg[4];
__le32 msg_idx;
__le32 bt_ci_compliance;
@ -245,8 +264,9 @@ struct iwl_bt_coex_profile_notif {
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
u8 ttc_rrc_status;
u8 reserved[3];
u8 ttc_status;
u8 rrc_status;
__le16 reserved;
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_4 */
#endif /* __iwl_fw_api_coex_h__ */

View File

@ -135,12 +135,6 @@ enum iwl_legacy_cmds {
*/
DBG_CFG = 0x9,
/**
* @ANTENNA_COUPLING_NOTIFICATION:
* Antenna coupling data, &struct iwl_mvm_antenna_coupling_notif
*/
ANTENNA_COUPLING_NOTIFICATION = 0xa,
/**
* @SCAN_ITERATION_COMPLETE_UMAC:
* Firmware indicates a scan iteration completed, using
@ -287,6 +281,11 @@ enum iwl_legacy_cmds {
*/
NON_QOS_TX_COUNTER_CMD = 0x2d,
/**
* @LEDS_CMD: command is &struct iwl_led_cmd
*/
LEDS_CMD = 0x48,
/**
* @LQ_CMD: using &struct iwl_lq_cmd
*/
@ -518,12 +517,6 @@ enum iwl_legacy_cmds {
*/
BT_CONFIG = 0x9b,
/**
* @BT_COEX_UPDATE_CORUN_LUT:
* &struct iwl_bt_coex_corun_lut_update_cmd
*/
BT_COEX_UPDATE_CORUN_LUT = 0x5b,
/**
* @BT_COEX_UPDATE_REDUCED_TXP:
* &struct iwl_bt_coex_reduced_txp_update_cmd

View File

@ -181,12 +181,4 @@ struct iwl_dc2dc_config_resp {
__le32 dc2dc_freq_tune1;
} __packed; /* DC2DC_CONFIG_RESP_API_S_VER_1 */
/**
* struct iwl_mvm_antenna_coupling_notif - antenna coupling notification
* @isolation: antenna isolation value
*/
struct iwl_mvm_antenna_coupling_notif {
__le32 isolation;
} __packed;
#endif /* __iwl_fw_api_config_h__ */

View File

@ -0,0 +1,71 @@
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2017 Intel Deutschland GmbH
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __iwl_fw_api_led_h__
#define __iwl_fw_api_led_h__
/**
* struct iwl_led_cmd - LED switching command
*
* @status: LED status (on/off)
*/
struct iwl_led_cmd {
__le32 status;
} __packed; /* LEDS_CMD_API_S_VER_2 */
#endif /* __iwl_fw_api_led_h__ */

View File

@ -409,7 +409,8 @@ enum iwl_tx_status {
* @AGG_TX_STATE_BT_PRIO:
* @AGG_TX_STATE_FEW_BYTES:
* @AGG_TX_STATE_ABORT:
* @AGG_TX_STATE_LAST_SENT_TTL:
* @AGG_TX_STATE_TX_ON_AIR_DROP: TX_ON_AIR signal drop without underrun or
* BT detection
* @AGG_TX_STATE_LAST_SENT_TRY_CNT:
* @AGG_TX_STATE_LAST_SENT_BT_KILL:
* @AGG_TX_STATE_SCD_QUERY:
@ -421,7 +422,7 @@ enum iwl_tx_status {
* occur if tx failed for this frame when it was a member of a previous
* aggregation block). If rate scaling is used, retry count indicates the
* rate table entry used for all frames in the new agg.
*@ AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
* @AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
* this frame
*
* TODO: complete documentation
@ -433,7 +434,7 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_BT_PRIO = 0x002,
AGG_TX_STATE_FEW_BYTES = 0x004,
AGG_TX_STATE_ABORT = 0x008,
AGG_TX_STATE_LAST_SENT_TTL = 0x010,
AGG_TX_STATE_TX_ON_AIR_DROP = 0x010,
AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020,
AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040,
AGG_TX_STATE_SCD_QUERY = 0x080,
@ -445,10 +446,6 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS,
};
#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL| \
AGG_TX_STATE_LAST_SENT_TRY_CNT| \
AGG_TX_STATE_LAST_SENT_BT_KILL)
/*
* The mask below describes a status where we are absolutely sure that the MPDU
* wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've
@ -786,13 +783,20 @@ struct iwl_mac_beacon_cmd_v7 {
struct ieee80211_hdr frame[0];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
enum iwl_mac_beacon_flags {
IWL_MAC_BEACON_CCK = BIT(8),
IWL_MAC_BEACON_ANT_A = BIT(9),
IWL_MAC_BEACON_ANT_B = BIT(10),
IWL_MAC_BEACON_ANT_C = BIT(11),
};
/**
* struct iwl_mac_beacon_cmd - beacon template command with offloaded CSA
* @byte_cnt: byte count of the beacon frame
* @flags: for future use
* @byte_cnt: byte count of the beacon frame.
* @flags: least significant byte for rate code. The most significant byte
* is &enum iwl_mac_beacon_flags.
* @reserved: reserved
* @template_id: currently equal to the mac context id of the coresponding
* mac.
* @template_id: currently equal to the mac context id of the coresponding mac.
* @tim_idx: the offset of the tim IE in the beacon
* @tim_size: the length of the tim IE
* @ecsa_offset: offset to the ECSA IE if present
@ -809,7 +813,7 @@ struct iwl_mac_beacon_cmd {
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[0];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_8 */
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_9 */
struct iwl_beacon_notif {
struct iwl_mvm_tx_resp beacon_notify_hdr;

View File

@ -545,11 +545,13 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
struct iwl_fw_error_dump_data *dump_data;
struct iwl_fw_error_dump_info *dump_info;
struct iwl_fw_error_dump_mem *dump_mem;
struct iwl_fw_error_dump_smem_cfg *dump_smem_cfg;
struct iwl_fw_error_dump_trigger_desc *dump_trig;
struct iwl_fw_dump_ptrs *fw_error_dump;
struct scatterlist *sg_dump_data;
u32 sram_len, sram_ofs;
const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = fwrt->fw->dbg_mem_tlv;
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0;
u32 smem_len = fwrt->fw->n_dbg_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
u32 sram2_len = fwrt->fw->n_dbg_mem_tlv ?
@ -585,8 +587,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
/* reading RXF/TXF sizes */
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
fifo_data_len = 0;
/* Count RXF2 size */
@ -675,7 +675,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
}
file_len = sizeof(*dump_file) +
sizeof(*dump_data) * 2 +
sizeof(*dump_data) * 3 +
sizeof(*dump_smem_cfg) +
fifo_data_len +
prph_len +
radio_len +
@ -706,8 +707,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
/* If we only want a monitor dump, reset the file length */
if (monitor_dump_only) {
file_len = sizeof(*dump_file) + sizeof(*dump_data) +
sizeof(*dump_info);
file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 +
sizeof(*dump_info) + sizeof(*dump_smem_cfg);
}
if (fwrt->dump.desc)
@ -744,6 +745,33 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
sizeof(dump_info->bus_human_readable));
dump_data = iwl_fw_error_next_data(dump_data);
/* Dump shared memory configuration */
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_CFG);
dump_data->len = cpu_to_le32(sizeof(*dump_smem_cfg));
dump_smem_cfg = (void *)dump_data->data;
dump_smem_cfg->num_lmacs = cpu_to_le32(mem_cfg->num_lmacs);
dump_smem_cfg->num_txfifo_entries =
cpu_to_le32(mem_cfg->num_txfifo_entries);
for (i = 0; i < MAX_NUM_LMAC; i++) {
int j;
for (j = 0; j < TX_FIFO_MAX_NUM; j++)
dump_smem_cfg->lmac[i].txfifo_size[j] =
cpu_to_le32(mem_cfg->lmac[i].txfifo_size[j]);
dump_smem_cfg->lmac[i].rxfifo1_size =
cpu_to_le32(mem_cfg->lmac[i].rxfifo1_size);
}
dump_smem_cfg->rxfifo2_size = cpu_to_le32(mem_cfg->rxfifo2_size);
dump_smem_cfg->internal_txfifo_addr =
cpu_to_le32(mem_cfg->internal_txfifo_addr);
for (i = 0; i < TX_FIFO_INTERNAL_MAX_NUM; i++) {
dump_smem_cfg->internal_txfifo_size[i] =
cpu_to_le32(mem_cfg->internal_txfifo_size[i]);
}
dump_data = iwl_fw_error_next_data(dump_data);
/* We only dump the FIFOs if the FW is in error state */
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
iwl_fw_dump_fifos(fwrt, &dump_data);

View File

@ -7,6 +7,7 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
*
* 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
@ -33,6 +34,7 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -92,6 +94,9 @@
* @IWL_FW_ERROR_DUMP_EXTERNAL: used only by external code utilities, and
* for that reason is not in use in any other place in the Linux Wi-Fi
* stack.
* @IWL_FW_ERROR_DUMP_MEM_CFG: the addresses and sizes of fifos in the smem,
* which we get from the fw after ALIVE. The content is structured as
* &struct iwl_fw_error_dump_smem_cfg.
*/
enum iwl_fw_error_dump_type {
/* 0 is deprecated */
@ -110,6 +115,7 @@ enum iwl_fw_error_dump_type {
IWL_FW_ERROR_DUMP_RADIO_REG = 13,
IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14,
IWL_FW_ERROR_DUMP_EXTERNAL = 15, /* Do not move */
IWL_FW_ERROR_DUMP_MEM_CFG = 16,
IWL_FW_ERROR_DUMP_MAX,
};
@ -208,6 +214,30 @@ struct iwl_fw_error_dump_fw_mon {
u8 data[];
} __packed;
#define MAX_NUM_LMAC 2
#define TX_FIFO_INTERNAL_MAX_NUM 6
#define TX_FIFO_MAX_NUM 15
/**
* struct iwl_fw_error_dump_smem_cfg - Dump SMEM configuration
* This must follow &struct iwl_fwrt_shared_mem_cfg.
* @num_lmacs: number of lmacs
* @num_txfifo_entries: number of tx fifos
* @lmac: sizes of lmacs txfifos and rxfifo1
* @rxfifo2_size: size of rxfifo2
* @internal_txfifo_addr: address of internal tx fifo
* @internal_txfifo_size: size of internal tx fifo
*/
struct iwl_fw_error_dump_smem_cfg {
__le32 num_lmacs;
__le32 num_txfifo_entries;
struct {
__le32 txfifo_size[TX_FIFO_MAX_NUM];
__le32 rxfifo1_size;
} lmac[MAX_NUM_LMAC];
__le32 rxfifo2_size;
__le32 internal_txfifo_addr;
__le32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
} __packed;
/**
* struct iwl_fw_error_dump_prph - periphery registers data
* @prph_start: address of the first register in this chunk

View File

@ -246,6 +246,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement.
* @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2
* @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
* @IWL_UCODE_TLV_API_ATS_COEX_EXTERNAL: the coex notification is enlared to
* include information about ACL time sharing.
*
* @NUM_IWL_UCODE_TLV_API: number of bits used
*/
@ -260,7 +262,9 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_STA_TYPE = (__force iwl_ucode_tlv_api_t)30,
IWL_UCODE_TLV_API_NAN2_VER2 = (__force iwl_ucode_tlv_api_t)31,
/* API Set 1 */
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34,
IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35,
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL = (__force iwl_ucode_tlv_api_t)37,
NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__

View File

@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
*
* 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
@ -32,6 +32,7 @@
* BSD LICENSE
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -161,6 +162,15 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
}
IWL_EXPORT_SYMBOL(iwl_init_notification_wait);
void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry)
{
spin_lock_bh(&notif_wait->notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
}
IWL_EXPORT_SYMBOL(iwl_remove_notification);
int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry,
unsigned long timeout)
@ -171,9 +181,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
wait_entry->triggered || wait_entry->aborted,
timeout);
spin_lock_bh(&notif_wait->notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
iwl_remove_notification(notif_wait, wait_entry);
if (wait_entry->aborted)
return -EIO;
@ -184,12 +192,3 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
return 0;
}
IWL_EXPORT_SYMBOL(iwl_wait_notification);
void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
struct iwl_notification_wait *wait_entry)
{
spin_lock_bh(&notif_wait->notif_wait_lock);
list_del(&wait_entry->list);
spin_unlock_bh(&notif_wait->notif_wait_lock);
}
IWL_EXPORT_SYMBOL(iwl_remove_notification);

View File

@ -0,0 +1,162 @@
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "iwl-drv.h"
#include "runtime.h"
#include "fw/api/nvm-reg.h"
#include "fw/api/commands.h"
#include "iwl-nvm-parse.h"
struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt)
{
struct iwl_nvm_get_info cmd = {};
struct iwl_nvm_get_info_rsp *rsp;
struct iwl_trans *trans = fwrt->trans;
struct iwl_nvm_data *nvm;
struct iwl_host_cmd hcmd = {
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
.data = { &cmd, },
.len = { sizeof(cmd) },
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP, NVM_GET_INFO)
};
int ret;
bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret)
return ERR_PTR(ret);
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
"Invalid payload len in NVM response from FW %d",
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
ret = -EINVAL;
goto out;
}
rsp = (void *)hcmd.resp_pkt->data;
if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
IWL_INFO(fwrt, "OTP is empty\n");
nvm = kzalloc(sizeof(*nvm) +
sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
GFP_KERNEL);
if (!nvm) {
ret = -ENOMEM;
goto out;
}
iwl_set_hw_address_from_csr(trans, nvm);
/* TODO: if platform NVM has MAC address - override it here */
if (!is_valid_ether_addr(nvm->hw_addr)) {
IWL_ERR(fwrt, "no valid mac address was found\n");
ret = -EINVAL;
goto err_free;
}
IWL_INFO(trans, "base HW address: %pM\n", nvm->hw_addr);
/* Initialize general data */
nvm->nvm_version = le16_to_cpu(rsp->general.nvm_version);
/* Initialize MAC sku data */
nvm->sku_cap_11ac_enable =
le32_to_cpu(rsp->mac_sku.enable_11ac);
nvm->sku_cap_11n_enable =
le32_to_cpu(rsp->mac_sku.enable_11n);
nvm->sku_cap_band_24GHz_enable =
le32_to_cpu(rsp->mac_sku.enable_24g);
nvm->sku_cap_band_52GHz_enable =
le32_to_cpu(rsp->mac_sku.enable_5g);
nvm->sku_cap_mimo_disabled =
le32_to_cpu(rsp->mac_sku.mimo_disable);
/* Initialize PHY sku data */
nvm->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
nvm->valid_rx_ant = (u8)le32_to_cpu(rsp->phy_sku.rx_chains);
/* Initialize regulatory data */
nvm->lar_enabled =
le32_to_cpu(rsp->regulatory.lar_enabled) && lar_fw_supported;
iwl_init_sbands(trans->dev, trans->cfg, nvm,
rsp->regulatory.channel_profile,
nvm->valid_tx_ant & fwrt->fw->valid_tx_ant,
nvm->valid_rx_ant & fwrt->fw->valid_rx_ant,
nvm->lar_enabled, false);
iwl_free_resp(&hcmd);
return nvm;
err_free:
kfree(nvm);
out:
iwl_free_resp(&hcmd);
return ERR_PTR(ret);
}
IWL_EXPORT_SYMBOL(iwl_fw_get_nvm);

View File

@ -63,6 +63,7 @@
#include "img.h"
#include "fw/api/debug.h"
#include "fw/api/paging.h"
#include "iwl-eeprom-parse.h"
struct iwl_fw_runtime_ops {
int (*dump_start)(void *ctx);
@ -152,5 +153,6 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
void iwl_fwrt_handle_notification(struct iwl_fw_runtime *fwrt,
struct iwl_rx_cmd_buffer *rxb);
struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt);
#endif /* __iwl_fw_runtime_h__ */

View File

@ -113,6 +113,9 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) !=
sizeof(mem_cfg->internal_txfifo_size));
fwrt->smem_cfg.internal_txfifo_addr =
le32_to_cpu(mem_cfg->internal_txfifo_addr);
for (i = 0;
i < ARRAY_SIZE(fwrt->smem_cfg.internal_txfifo_size);
i++)

View File

@ -463,6 +463,9 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr;
extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb;
extern const struct iwl_cfg iwla000_2ac_cfg_jf;
extern const struct iwl_cfg iwla000_2ax_cfg_hr;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0;
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0;
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */

View File

@ -169,7 +169,7 @@
/*
* CSR Hardware Revision Workaround Register. Indicates hardware rev;
* "step" determines CCK backoff for txpower calculation. Used for 4965 only.
* "step" determines CCK backoff for txpower calculation.
* See also CSR_HW_REV register.
* Bit fields:
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
@ -354,11 +354,16 @@ enum {
#define CSR_HW_REV_TYPE_135 (0x0000120)
#define CSR_HW_REV_TYPE_7265D (0x0000210)
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
/* RF_ID value */
#define CSR_HW_RF_ID_TYPE_JF (0x00105000)
#define CSR_HW_RF_ID_TYPE_JF (0x00105100)
#define CSR_HW_RF_ID_TYPE_HR (0x0010A000)
#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109000)
#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00)
/* HW_RF CHIP ID */
#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF)
/* EEPROM REG */
#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)

View File

@ -479,8 +479,8 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
return 0;
}
static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
struct iwl_ucode_capabilities *capa)
static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
struct iwl_ucode_capabilities *capa)
{
const struct iwl_ucode_api *ucode_api = (void *)data;
u32 api_index = le32_to_cpu(ucode_api->api_index);
@ -488,23 +488,20 @@ static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
int i;
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
IWL_ERR(drv,
"api flags index %d larger than supported by driver\n",
api_index);
/* don't return an error so we can load FW that has more bits */
return 0;
IWL_WARN(drv,
"api flags index %d larger than supported by driver\n",
api_index);
return;
}
for (i = 0; i < 32; i++) {
if (api_flags & BIT(i))
__set_bit(i + 32 * api_index, capa->_api);
}
return 0;
}
static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
struct iwl_ucode_capabilities *capa)
static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
struct iwl_ucode_capabilities *capa)
{
const struct iwl_ucode_capa *ucode_capa = (void *)data;
u32 api_index = le32_to_cpu(ucode_capa->api_index);
@ -512,19 +509,16 @@ static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
int i;
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
IWL_ERR(drv,
"capa flags index %d larger than supported by driver\n",
api_index);
/* don't return an error so we can load FW that has more bits */
return 0;
IWL_WARN(drv,
"capa flags index %d larger than supported by driver\n",
api_index);
return;
}
for (i = 0; i < 32; i++) {
if (api_flags & BIT(i))
__set_bit(i + 32 * api_index, capa->_capa);
}
return 0;
}
static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
@ -766,14 +760,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
case IWL_UCODE_TLV_API_CHANGES_SET:
if (tlv_len != sizeof(struct iwl_ucode_api))
goto invalid_tlv_len;
if (iwl_set_ucode_api_flags(drv, tlv_data, capa))
goto tlv_error;
iwl_set_ucode_api_flags(drv, tlv_data, capa);
break;
case IWL_UCODE_TLV_ENABLED_CAPABILITIES:
if (tlv_len != sizeof(struct iwl_ucode_capa))
goto invalid_tlv_len;
if (iwl_set_ucode_capabilities(drv, tlv_data, capa))
goto tlv_error;
iwl_set_ucode_capabilities(drv, tlv_data, capa);
break;
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
if (tlv_len != sizeof(u32))

View File

@ -241,20 +241,12 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
void iwl_force_nmi(struct iwl_trans *trans)
{
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
DEVICE_SET_NMI_VAL_DRV);
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
DEVICE_SET_NMI_VAL_HW);
} else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) {
else
iwl_write_prph(trans, UREG_NIC_SET_NMI_DRIVER,
DEVICE_SET_NMI_8000_VAL);
} else {
iwl_write_prph(trans, DEVICE_SET_NMI_8000_REG,
DEVICE_SET_NMI_8000_VAL);
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
DEVICE_SET_NMI_VAL_DRV);
}
UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK);
}
IWL_EXPORT_SYMBOL(iwl_force_nmi);

View File

@ -79,6 +79,7 @@
/* NVM offsets (in words) definitions */
enum wkp_nvm_offsets {
/* NVM HW-Section offset (in words) definitions */
SUBSYSTEM_ID = 0x0A,
HW_ADDR = 0x15,
/* NVM SW-Section offset (in words) definitions */
@ -183,22 +184,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
* @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
* on same channel on 2.4 or same UNII band on 5.2
* @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
* @NVM_CHANNEL_UNIFORM: uniform spreading required
* @NVM_CHANNEL_20MHZ: 20 MHz channel okay
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay
* @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
*/
enum iwl_nvm_channel_flags {
NVM_CHANNEL_VALID = BIT(0),
NVM_CHANNEL_IBSS = BIT(1),
NVM_CHANNEL_ACTIVE = BIT(3),
NVM_CHANNEL_RADAR = BIT(4),
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
NVM_CHANNEL_WIDE = BIT(8),
NVM_CHANNEL_40MHZ = BIT(9),
NVM_CHANNEL_80MHZ = BIT(10),
NVM_CHANNEL_160MHZ = BIT(11),
NVM_CHANNEL_VALID = BIT(0),
NVM_CHANNEL_IBSS = BIT(1),
NVM_CHANNEL_ACTIVE = BIT(3),
NVM_CHANNEL_RADAR = BIT(4),
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
NVM_CHANNEL_UNIFORM = BIT(7),
NVM_CHANNEL_20MHZ = BIT(8),
NVM_CHANNEL_40MHZ = BIT(9),
NVM_CHANNEL_80MHZ = BIT(10),
NVM_CHANNEL_160MHZ = BIT(11),
NVM_CHANNEL_DC_HIGH = BIT(12),
};
#define CHECK_AND_PRINT_I(x) \
@ -254,13 +259,12 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 * const nvm_ch_flags,
bool lar_supported)
bool lar_supported, bool no_wide_in_5ghz)
{
int ch_idx;
int n_channels = 0;
struct ieee80211_channel *channel;
u16 ch_flags;
bool is_5ghz;
int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan;
@ -275,12 +279,20 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
}
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
bool is_5ghz = (ch_idx >= num_2ghz_channels);
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
if (ch_idx >= num_2ghz_channels &&
!data->sku_cap_band_52GHz_enable)
if (is_5ghz && !data->sku_cap_band_52GHz_enable)
continue;
/* workaround to disable wide channels in 5GHz */
if (no_wide_in_5ghz && is_5ghz) {
ch_flags &= ~(NVM_CHANNEL_40MHZ |
NVM_CHANNEL_80MHZ |
NVM_CHANNEL_160MHZ);
}
if (ch_flags & NVM_CHANNEL_160MHZ)
data->vht160_supported = true;
@ -303,8 +315,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
n_channels++;
channel->hw_value = nvm_chan[ch_idx];
channel->band = (ch_idx < num_2ghz_channels) ?
NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
channel->band = is_5ghz ?
NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
channel->center_freq =
ieee80211_channel_to_frequency(
channel->hw_value, channel->band);
@ -316,7 +328,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
* is not used in mvm, and is used for backwards compatibility
*/
channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
is_5ghz = channel->band == NL80211_BAND_5GHZ;
/* don't put limitations in case we're using LAR */
if (!lar_supported)
@ -327,7 +338,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
channel->flags = 0;
IWL_DEBUG_EEPROM(dev,
"Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
"Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
channel->hw_value,
is_5ghz ? "5.2" : "2.4",
ch_flags,
@ -337,10 +348,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(WIDE),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(DC_HIGH),
channel->max_power,
((ch_flags & NVM_CHANNEL_IBSS) &&
!(ch_flags & NVM_CHANNEL_RADAR))
@ -432,14 +445,15 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
u8 tx_chains, u8 rx_chains, bool lar_supported)
u8 tx_chains, u8 rx_chains, bool lar_supported,
bool no_wide_in_5ghz)
{
int n_channels;
int n_used = 0;
struct ieee80211_supported_band *sband;
n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
lar_supported);
lar_supported, no_wide_in_5ghz);
sband = &data->bands[NL80211_BAND_2GHZ];
sband->band = NL80211_BAND_2GHZ;
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@ -568,7 +582,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 *mac_override,
const __le16 *nvm_hw)
const __be16 *nvm_hw)
{
const u8 *hw_addr;
@ -615,7 +629,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
static int iwl_set_hw_address(struct iwl_trans *trans,
const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_hw,
struct iwl_nvm_data *data, const __be16 *nvm_hw,
const __le16 *mac_override)
{
if (cfg->mac_addr_from_csr) {
@ -645,9 +659,41 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
return 0;
}
static bool
iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
const __be16 *nvm_hw)
{
/*
* Workaround a bug in Indonesia SKUs where the regulatory in
* some 7000-family OTPs erroneously allow wide channels in
* 5GHz. To check for Indonesia, we take the SKU value from
* bits 1-4 in the subsystem ID and check if it is either 5 or
* 9. In those cases, we need to force-disable wide channels
* in 5GHz otherwise the FW will throw a sysassert when we try
* to use them.
*/
if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/*
* Unlike the other sections in the NVM, the hw
* section uses big-endian.
*/
u16 subsystem_id = be16_to_cpup(nvm_hw + SUBSYSTEM_ID);
u8 sku = (subsystem_id & 0x1e) >> 1;
if (sku == 5 || sku == 9) {
IWL_DEBUG_EEPROM(dev,
"disabling wide channels in 5GHz (0x%0x %d)\n",
subsystem_id, sku);
return true;
}
}
return false;
}
struct iwl_nvm_data *
iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw,
const __be16 *nvm_hw, const __le16 *nvm_sw,
const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
@ -655,6 +701,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
struct device *dev = trans->dev;
struct iwl_nvm_data *data;
bool lar_enabled;
bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
u32 sku, radio_cfg;
u16 lar_config;
const __le16 *ch_section;
@ -725,7 +772,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
}
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
lar_fw_supported && lar_enabled);
lar_fw_supported && lar_enabled, no_wide_in_5ghz);
data->calib_version = 255;
return data;
@ -868,18 +915,21 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
prev_reg_rule_flags = reg_rule_flags;
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x) reg_flags 0x%x: %s\n",
"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x) reg_flags 0x%x: %s\n",
center_freq,
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
CHECK_AND_PRINT_I(VALID),
CHECK_AND_PRINT_I(IBSS),
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(WIDE),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(DC_HIGH),
ch_flags, reg_rule_flags,
((ch_flags & NVM_CHANNEL_ACTIVE) &&
!(ch_flags & NVM_CHANNEL_RADAR))

View File

@ -77,7 +77,7 @@
*/
struct iwl_nvm_data *
iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw,
const __be16 *nvm_hw, const __le16 *nvm_sw,
const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported);
@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
*/
void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
u8 tx_chains, u8 rx_chains, bool lar_supported);
u8 tx_chains, u8 rx_chains, bool lar_supported,
bool no_wide_in_5ghz);
/**
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW

View File

@ -109,13 +109,12 @@
/* Device system time */
#define DEVICE_SYSTEM_TIME_REG 0xA0206C
/* Device NMI register */
/* Device NMI register and value for 8000 family and lower hw's */
#define DEVICE_SET_NMI_REG 0x00a01c30
#define DEVICE_SET_NMI_VAL_HW BIT(0)
#define DEVICE_SET_NMI_VAL_DRV BIT(7)
#define DEVICE_SET_NMI_8000_REG 0x00a01c24
#define DEVICE_SET_NMI_8000_VAL 0x1000000
/* Device NMI register and value for 9000 family and above hw's */
#define UREG_NIC_SET_NMI_DRIVER 0x00a05c10
#define UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK 0xff000000
/* Shared registers (0x0..0x3ff, via target indirect or periphery */
#define SHR_BASE 0x00a10000
@ -404,6 +403,12 @@ enum aux_misc_master1_en {
#define SB_CPU_2_STATUS 0xA01E34
#define UMAG_SB_CPU_1_STATUS 0xA038C0
#define UMAG_SB_CPU_2_STATUS 0xA038C4
#define UMAG_GEN_HW_STATUS 0xA038C8
/* For UMAG_GEN_HW_STATUS reg check */
enum {
UMAG_GEN_HW_IS_FPGA = BIT(1),
};
/* FW chicken bits */
#define LMPM_CHICK 0xA01FF8

View File

@ -7,6 +7,7 @@
*
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH
*
* 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
@ -33,6 +34,7 @@
*
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -148,215 +150,6 @@ static const __le64 iwl_ci_mask[][3] = {
},
};
struct corunning_block_luts {
u8 range;
__le32 lut20[BT_COEX_CORUN_LUT_SIZE];
};
/*
* Ranges for the antenna coupling calibration / co-running block LUT:
* LUT0: [ 0, 12[
* LUT1: [12, 20[
* LUT2: [20, 21[
* LUT3: [21, 23[
* LUT4: [23, 27[
* LUT5: [27, 30[
* LUT6: [30, 32[
* LUT7: [32, 33[
* LUT8: [33, - [
*/
static const struct corunning_block_luts antenna_coupling_ranges[] = {
{
.range = 0,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 12,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 20,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 21,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 23,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 27,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 30,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 32,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
{
.range = 33,
.lut20 = {
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
},
},
};
static enum iwl_bt_coex_lut_type
iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
{
@ -437,9 +230,6 @@ int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm)
bt_cmd.enabled_modules |=
cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
if (iwl_mvm_bt_is_plcr_supported(mvm))
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
if (iwl_mvm_is_mplut_supported(mvm))
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_MPLUT_ENABLED);
@ -560,8 +350,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
smps_mode = IEEE80211_SMPS_AUTOMATIC;
if (mvmvif->phy_ctxt &&
IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
mvmvif->phy_ctxt->id))
(mvm->last_bt_notif.rrc_status & BIT(mvmvif->phy_ctxt->id)))
smps_mode = IEEE80211_SMPS_AUTOMATIC;
IWL_DEBUG_COEX(data->mvm,
@ -725,17 +514,36 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
le32_to_cpu(notif->primary_ch_lut));
IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
le32_to_cpu(notif->secondary_ch_lut));
IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
le32_to_cpu(notif->bt_activity_grading));
if (!iwl_mvm_has_new_ats_coex_api(mvm)) {
struct iwl_bt_coex_profile_notif_v4 *v4 = (void *)pkt->data;
mvm->last_bt_notif.mbox_msg[0] = v4->mbox_msg[0];
mvm->last_bt_notif.mbox_msg[1] = v4->mbox_msg[1];
mvm->last_bt_notif.mbox_msg[2] = v4->mbox_msg[2];
mvm->last_bt_notif.mbox_msg[3] = v4->mbox_msg[3];
mvm->last_bt_notif.msg_idx = v4->msg_idx;
mvm->last_bt_notif.bt_ci_compliance = v4->bt_ci_compliance;
mvm->last_bt_notif.primary_ch_lut = v4->primary_ch_lut;
mvm->last_bt_notif.secondary_ch_lut = v4->secondary_ch_lut;
mvm->last_bt_notif.bt_activity_grading =
v4->bt_activity_grading;
mvm->last_bt_notif.ttc_status = v4->ttc_status;
mvm->last_bt_notif.rrc_status = v4->rrc_status;
} else {
/* save this notification for future use: rssi fluctuations */
memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
}
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n",
mvm->last_bt_notif.bt_ci_compliance);
IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
le32_to_cpu(mvm->last_bt_notif.primary_ch_lut));
IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut));
IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
le32_to_cpu(mvm->last_bt_notif.bt_activity_grading));
/* remember this notification for future use: rssi fluctuations */
memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
iwl_mvm_bt_coex_notif_handle(mvm);
}
@ -792,7 +600,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
enum iwl_bt_coex_lut_type lut_type;
if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
return LINK_QUAL_AGG_TIME_LIMIT_DEF;
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
@ -816,7 +624,7 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
enum iwl_bt_coex_lut_type lut_type;
if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
return true;
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
@ -909,59 +717,3 @@ void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
{
iwl_mvm_bt_coex_notif_handle(mvm);
}
void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_mvm_antenna_coupling_notif *notif = (void *)pkt->data;
u32 ant_isolation = le32_to_cpu(notif->isolation);
struct iwl_bt_coex_corun_lut_update_cmd cmd = {};
u8 __maybe_unused lower_bound, upper_bound;
u8 lut;
if (!iwl_mvm_bt_is_plcr_supported(mvm))
return;
lockdep_assert_held(&mvm->mutex);
/* Ignore updates if we are in force mode */
if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
return;
if (ant_isolation == mvm->last_ant_isol)
return;
for (lut = 0; lut < ARRAY_SIZE(antenna_coupling_ranges) - 1; lut++)
if (ant_isolation < antenna_coupling_ranges[lut + 1].range)
break;
lower_bound = antenna_coupling_ranges[lut].range;
if (lut < ARRAY_SIZE(antenna_coupling_ranges) - 1)
upper_bound = antenna_coupling_ranges[lut + 1].range;
else
upper_bound = antenna_coupling_ranges[lut].range;
IWL_DEBUG_COEX(mvm, "Antenna isolation=%d in range [%d,%d[, lut=%d\n",
ant_isolation, lower_bound, upper_bound, lut);
mvm->last_ant_isol = ant_isolation;
if (mvm->last_corun_lut == lut)
return;
mvm->last_corun_lut = lut;
/* For the moment, use the same LUT for 20GHz and 40GHz */
memcpy(&cmd.corun_lut20, antenna_coupling_ranges[lut].lut20,
sizeof(cmd.corun_lut20));
memcpy(&cmd.corun_lut40, antenna_coupling_ranges[lut].lut20,
sizeof(cmd.corun_lut40));
if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_CORUN_LUT, 0,
sizeof(cmd), &cmd))
IWL_ERR(mvm,
"failed to send BT_COEX_UPDATE_CORUN_LUT command\n");
}

View File

@ -95,7 +95,6 @@
#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 0
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_BT_COEX_RRC 1
#define IWL_MVM_BT_COEX_TTC 1
@ -137,6 +136,7 @@
#define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */
#define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */
#define IWL_MVM_RS_AGG_DISABLE_START 3
#define IWL_MVM_RS_AGG_START_THRESHOLD 10 /* num frames per second */
#define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */
#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */
#define IWL_MVM_RS_TPC_TX_POWER_STEP 3

View File

@ -82,6 +82,9 @@ static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
char buf[16];
int pos, budget;
if (!iwl_mvm_is_ctdp_supported(mvm))
return -EOPNOTSUPP;
if (!iwl_mvm_firmware_running(mvm) ||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
return -EIO;
@ -103,6 +106,9 @@ static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
{
int ret;
if (!iwl_mvm_is_ctdp_supported(mvm))
return -EOPNOTSUPP;
if (!iwl_mvm_firmware_running(mvm) ||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
return -EIO;
@ -114,6 +120,18 @@ static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
return ret ?: count;
}
static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
{
if (!iwl_mvm_firmware_running(mvm) ||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
return -EIO;
iwl_mvm_enter_ctkill(mvm);
return count;
}
static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
{
@ -451,20 +469,9 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
return ret ?: count;
}
#define BT_MBOX_MSG(_notif, _num, _field) \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
#define BT_MBOX_PRINT(_num, _field, _end) \
pos += scnprintf(buf + pos, bufsz - pos, \
"\t%s: %d%s", \
#_field, \
BT_MBOX_MSG(notif, _num, _field), \
true ? "\n" : ", ");
static
int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
int iwl_mvm_coex_dump_mbox(struct iwl_mvm *mvm,
struct iwl_bt_coex_profile_notif *notif, char *buf,
int pos, int bufsz)
{
pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
@ -508,6 +515,7 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
BT_MBOX_PRINT(3, SCO_STATE, false);
BT_MBOX_PRINT(3, SNIFF_STATE, false);
BT_MBOX_PRINT(3, A2DP_STATE, false);
BT_MBOX_PRINT(3, A2DP_SRC, false);
BT_MBOX_PRINT(3, ACL_STATE, false);
BT_MBOX_PRINT(3, MSTR_STATE, false);
BT_MBOX_PRINT(3, OBX_STATE, false);
@ -517,7 +525,12 @@ int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
BT_MBOX_PRINT(3, INBAND_P, false);
BT_MBOX_PRINT(3, MSG_TYPE_2, false);
BT_MBOX_PRINT(3, SSN_2, false);
BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
BT_MBOX_PRINT(3, UPDATE_REQUEST, !iwl_mvm_has_new_ats_coex_api(mvm));
if (iwl_mvm_has_new_ats_coex_api(mvm)) {
BT_MBOX_PRINT(4, ATS_BT_INTERVAL, false);
BT_MBOX_PRINT(4, ATS_BT_ACTIVE_MAX_TH, true);
}
return pos;
}
@ -536,7 +549,7 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
mutex_lock(&mvm->mutex);
pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz);
pos += iwl_mvm_coex_dump_mbox(mvm, notif, buf, pos, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n",
notif->bt_ci_compliance);
@ -547,20 +560,15 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
pos += scnprintf(buf + pos,
bufsz - pos, "bt_activity_grading = %d\n",
le32_to_cpu(notif->bt_activity_grading));
pos += scnprintf(buf + pos, bufsz - pos,
"antenna isolation = %d CORUN LUT index = %d\n",
mvm->last_ant_isol, mvm->last_corun_lut);
pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n",
(notif->ttc_rrc_status >> 4) & 0xF);
notif->rrc_status & 0xF);
pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n",
notif->ttc_rrc_status & 0xF);
notif->ttc_status & 0xF);
pos += scnprintf(buf + pos, bufsz - pos, "sync_sco = %d\n",
IWL_MVM_BT_COEX_SYNC2SCO);
pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n",
IWL_MVM_BT_COEX_MPLUT);
pos += scnprintf(buf + pos, bufsz - pos, "corunning = %d\n",
IWL_MVM_BT_COEX_CORUNNING);
mutex_unlock(&mvm->mutex);
@ -1641,6 +1649,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
/* Device wide debugfs entries */
MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
@ -1828,6 +1837,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);

View File

@ -83,6 +83,7 @@
#include "fw/api/commands.h"
#include "fw/api/d3.h"
#include "fw/api/filter.h"
#include "fw/api/led.h"
#include "fw/api/mac.h"
#include "fw/api/nvm-reg.h"
#include "fw/api/phy-ctxt.h"

View File

@ -388,7 +388,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
}
if (IWL_MVM_PARSE_NVM && read_nvm) {
ret = iwl_nvm_init(mvm, true);
ret = iwl_nvm_init(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto error;
@ -412,8 +412,10 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
/* Read the NVM only at driver load time, no need to do this twice */
if (!IWL_MVM_PARSE_NVM && read_nvm) {
ret = iwl_mvm_nvm_get_from_fw(mvm);
if (ret) {
mvm->nvm_data = iwl_fw_get_nvm(&mvm->fwrt);
if (IS_ERR(mvm->nvm_data)) {
ret = PTR_ERR(mvm->nvm_data);
mvm->nvm_data = NULL;
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
return ret;
}
@ -473,22 +475,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT);
if (ret) {
IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret);
goto error;
goto remove_notif;
}
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
ret = iwl_mvm_send_bt_init_conf(mvm);
if (ret)
goto error;
goto remove_notif;
}
/* Read the NVM only at driver load time, no need to do this twice */
if (read_nvm) {
/* Read nvm */
ret = iwl_nvm_init(mvm, true);
ret = iwl_nvm_init(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto error;
goto remove_notif;
}
}
@ -496,8 +497,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if (mvm->nvm_file_name)
iwl_mvm_load_nvm_to_nic(mvm);
ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
WARN_ON(ret);
WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
/*
* abort after reading the nvm in case RF Kill is on, we will complete
@ -506,9 +506,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm,
"jump over all phy activities due to RF kill\n");
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
ret = 1;
goto out;
goto remove_notif;
}
mvm->calibrating = true;
@ -516,17 +514,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
if (ret)
goto error;
goto remove_notif;
/*
* Send phy configurations command to init uCode
* to start the 16.0 uCode init image internal calibrations.
*/
ret = iwl_send_phy_cfg_cmd(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret);
goto error;
goto remove_notif;
}
/*
@ -534,15 +528,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
* just wait for the calibration complete notification.
*/
ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
MVM_UCODE_CALIB_TIMEOUT);
MVM_UCODE_CALIB_TIMEOUT);
if (!ret)
goto out;
if (ret && iwl_mvm_is_radio_hw_killed(mvm)) {
if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
ret = 1;
ret = 0;
} else {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret);
}
goto out;
error:
remove_notif:
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out:
mvm->calibrating = false;
@ -997,6 +997,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
{
return 0;
}
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a,
int prof_b)
{
return -ENOENT;
}
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
return -ENOENT;
}
#endif /* CONFIG_ACPI */
static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
@ -1043,9 +1054,6 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
if (ret) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
/* this can't happen */
if (WARN_ON(ret > 0))
ret = -ERFKILL;
return ret;
}
@ -1173,7 +1181,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
}
/* TODO: read the budget from BIOS / Platform NVM */
if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) {
/*
* In case there is no budget from BIOS / Platform NVM the default
* budget should be 2000mW (cooling state 0).
*/
if (iwl_mvm_is_ctdp_supported(mvm)) {
ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
mvm->cooling_dev.cur_state);
if (ret)
@ -1219,6 +1232,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret)
goto error;
iwl_mvm_leds_sync(mvm);
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
return 0;
error:

View File

@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
*
* 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
@ -31,6 +32,7 @@
* BSD LICENSE
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,26 +68,45 @@
#include "iwl-csr.h"
#include "mvm.h"
/* Set led register on */
static void iwl_mvm_led_enable(struct iwl_mvm *mvm)
static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
{
iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
struct iwl_led_cmd led_cmd = {
.status = cpu_to_le32(on),
};
struct iwl_host_cmd cmd = {
.id = WIDE_ID(LONG_GROUP, LEDS_CMD),
.len = { sizeof(led_cmd), },
.data = { &led_cmd, },
.flags = CMD_ASYNC,
};
int err;
if (!iwl_mvm_firmware_running(mvm))
return;
err = iwl_mvm_send_cmd(mvm, &cmd);
if (err)
IWL_WARN(mvm, "LED command failed: %d\n", err);
}
/* Set led register off */
static void iwl_mvm_led_disable(struct iwl_mvm *mvm)
static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
{
iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_OFF);
if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
iwl_mvm_send_led_fw_cmd(mvm, on);
return;
}
iwl_write32(mvm->trans, CSR_LED_REG,
on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);
}
static void iwl_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
if (brightness > 0)
iwl_mvm_led_enable(mvm);
else
iwl_mvm_led_disable(mvm);
iwl_mvm_led_set(mvm, brightness > 0);
}
int iwl_mvm_leds_init(struct iwl_mvm *mvm)
@ -127,10 +148,24 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
return 0;
}
void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
{
if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
return;
/*
* if we control through the register, we're doing it
* even when the firmware isn't up, so no need to sync
*/
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000)
return;
iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
}
void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
{
if (iwlwifi_mod_params.led_mode == IWL_LED_DISABLE ||
!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
return;
led_classdev_unregister(&mvm->led);

View File

@ -923,6 +923,19 @@ static u32 iwl_mvm_find_ie_offset(u8 *beacon, u8 eid, u32 frame_size)
return ie - beacon;
}
static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
struct ieee80211_vif *vif)
{
u8 rate;
if (info->band == NL80211_BAND_5GHZ || vif->p2p)
rate = IWL_FIRST_OFDM_RATE;
else
rate = IWL_FIRST_CCK_RATE;
return rate;
}
static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct sk_buff *beacon,
@ -930,7 +943,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_tx_info *info;
u32 rate, tx_flags;
u8 rate;
u32 tx_flags;
info = IEEE80211_SKB_CB(beacon);
@ -955,14 +969,12 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
RATE_MCS_ANT_POS);
if (info->band == NL80211_BAND_5GHZ || vif->p2p) {
rate = IWL_FIRST_OFDM_RATE;
} else {
rate = IWL_FIRST_CCK_RATE;
tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
}
rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
if (rate == IWL_FIRST_CCK_RATE)
tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
}
static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
@ -1033,19 +1045,27 @@ static int iwl_mvm_mac_ctxt_send_beacon_v7(struct iwl_mvm *mvm,
sizeof(beacon_cmd));
}
static int iwl_mvm_mac_ctxt_send_beacon_v8(struct iwl_mvm *mvm,
static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct sk_buff *beacon)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(beacon);
struct iwl_mac_beacon_cmd beacon_cmd = {};
u8 rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
u16 flags;
flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
if (rate == IWL_FIRST_CCK_RATE)
flags |= IWL_MAC_BEACON_CCK;
beacon_cmd.flags = cpu_to_le16(flags);
beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
if (vif->type == NL80211_IFTYPE_AP)
iwl_mvm_mac_ctxt_set_tim(mvm,
&beacon_cmd.tim_idx,
iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
&beacon_cmd.tim_size,
beacon->data, beacon->len);
@ -1073,10 +1093,11 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD))
return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon);
if (!iwl_mvm_has_new_tx_api(mvm))
return iwl_mvm_mac_ctxt_send_beacon_v7(mvm, vif, beacon);
if (fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
return iwl_mvm_mac_ctxt_send_beacon_v9(mvm, vif, beacon);
return iwl_mvm_mac_ctxt_send_beacon_v8(mvm, vif, beacon);
return iwl_mvm_mac_ctxt_send_beacon_v7(mvm, vif, beacon);
}
/* The beacon template for the AP/GO/IBSS has changed and needs update */

View File

@ -2023,8 +2023,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
* We received a beacon from the associated AP so
* remove the session protection.
*/
iwl_mvm_remove_time_event(mvm, mvmvif,
&mvmvif->time_event_data);
iwl_mvm_stop_session_protection(mvm, vif);
iwl_mvm_sf_update(mvm, vif, false);
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
@ -3886,11 +3885,16 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
/* Schedule the time event to a bit before beacon 1,
* to make sure we're in the new channel when the
* GO/AP arrives.
* GO/AP arrives. In case count <= 1 immediately schedule the
* TE (this might result with some packet loss or connection
* loss).
*/
apply_time = chsw->device_timestamp +
((vif->bss_conf.beacon_int * (chsw->count - 1) -
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
if (chsw->count <= 1)
apply_time = 0;
else
apply_time = chsw->device_timestamp +
((vif->bss_conf.beacon_int * (chsw->count - 1) -
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
if (chsw->block_tx)
iwl_mvm_csa_client_absent(mvm, vif);

View File

@ -924,8 +924,6 @@ struct iwl_mvm {
struct iwl_bt_coex_profile_notif last_bt_notif;
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
u32 last_ant_isol;
u8 last_corun_lut;
u8 bt_tx_prio;
enum iwl_bt_force_ant_mode bt_force_ant_mode;
@ -1175,13 +1173,6 @@ static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC);
}
static inline bool iwl_mvm_bt_is_plcr_supported(struct iwl_mvm *mvm)
{
return fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BT_COEX_PLCR) &&
IWL_MVM_BT_COEX_CORUNNING;
}
static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm)
{
return fw_has_capa(&mvm->fw->ucode_capa,
@ -1251,6 +1242,12 @@ static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
IWL_UCODE_TLV_API_NEW_RX_STATS);
}
static inline bool iwl_mvm_has_new_ats_coex_api(struct iwl_mvm *mvm)
{
return fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL);
}
static inline struct agg_tx_status *
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
{
@ -1376,8 +1373,7 @@ int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear);
void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
/* NVM */
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm);
int iwl_nvm_init(struct iwl_mvm *mvm);
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm);
@ -1566,6 +1562,7 @@ void iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
#ifdef CONFIG_IWLWIFI_LEDS
int iwl_mvm_leds_init(struct iwl_mvm *mvm);
void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
void iwl_mvm_leds_sync(struct iwl_mvm *mvm);
#else
static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
{
@ -1574,6 +1571,9 @@ static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
static inline void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
{
}
static inline void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
{
}
#endif
/* D3 (WoWLAN, NetDetect) */
@ -1751,6 +1751,7 @@ void iwl_mvm_thermal_exit(struct iwl_mvm *mvm);
void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp);
void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm);
int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);
int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget);
@ -1824,21 +1825,7 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
u32 duration, u32 timeout);
bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
#ifdef CONFIG_ACPI
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
#else
static inline
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
{
return -ENOENT;
}
static inline
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
return -ENOENT;
}
#endif /* CONFIG_ACPI */
#endif /* __IWL_MVM_H__ */

View File

@ -292,7 +292,8 @@ static struct iwl_nvm_data *
iwl_parse_nvm_sections(struct iwl_mvm *mvm)
{
struct iwl_nvm_section *sections = mvm->nvm_sections;
const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku;
const __be16 *hw;
const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
bool lar_enabled;
/* Checking for required sections */
@ -326,10 +327,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
}
}
if (WARN_ON(!mvm->cfg))
return NULL;
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
@ -546,98 +544,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
return ret;
}
int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
{
struct iwl_nvm_get_info cmd = {};
struct iwl_nvm_get_info_rsp *rsp;
struct iwl_trans *trans = mvm->trans;
struct iwl_host_cmd hcmd = {
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
.data = { &cmd, },
.len = { sizeof(cmd) },
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP, NVM_GET_INFO)
};
int ret;
bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
lockdep_assert_held(&mvm->mutex);
ret = iwl_mvm_send_cmd(mvm, &hcmd);
if (ret)
return ret;
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
"Invalid payload len in NVM response from FW %d",
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
ret = -EINVAL;
goto out;
}
rsp = (void *)hcmd.resp_pkt->data;
if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
IWL_INFO(mvm, "OTP is empty\n");
mvm->nvm_data = kzalloc(sizeof(*mvm->nvm_data) +
sizeof(struct ieee80211_channel) *
IWL_NUM_CHANNELS, GFP_KERNEL);
if (!mvm->nvm_data) {
ret = -ENOMEM;
goto out;
}
iwl_set_hw_address_from_csr(trans, mvm->nvm_data);
/* TODO: if platform NVM has MAC address - override it here */
if (!is_valid_ether_addr(mvm->nvm_data->hw_addr)) {
IWL_ERR(trans, "no valid mac address was found\n");
ret = -EINVAL;
goto err_free;
}
IWL_INFO(trans, "base HW address: %pM\n", mvm->nvm_data->hw_addr);
/* Initialize general data */
mvm->nvm_data->nvm_version = le16_to_cpu(rsp->general.nvm_version);
/* Initialize MAC sku data */
mvm->nvm_data->sku_cap_11ac_enable =
le32_to_cpu(rsp->mac_sku.enable_11ac);
mvm->nvm_data->sku_cap_11n_enable =
le32_to_cpu(rsp->mac_sku.enable_11n);
mvm->nvm_data->sku_cap_band_24GHz_enable =
le32_to_cpu(rsp->mac_sku.enable_24g);
mvm->nvm_data->sku_cap_band_52GHz_enable =
le32_to_cpu(rsp->mac_sku.enable_5g);
mvm->nvm_data->sku_cap_mimo_disabled =
le32_to_cpu(rsp->mac_sku.mimo_disable);
/* Initialize PHY sku data */
mvm->nvm_data->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
mvm->nvm_data->valid_rx_ant = (u8)le32_to_cpu(rsp->phy_sku.rx_chains);
/* Initialize regulatory data */
mvm->nvm_data->lar_enabled =
le32_to_cpu(rsp->regulatory.lar_enabled) && lar_fw_supported;
iwl_init_sbands(trans->dev, trans->cfg, mvm->nvm_data,
rsp->regulatory.channel_profile,
mvm->nvm_data->valid_tx_ant & mvm->fw->valid_tx_ant,
mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant,
rsp->regulatory.lar_enabled && lar_fw_supported);
iwl_free_resp(&hcmd);
return 0;
err_free:
kfree(mvm->nvm_data);
out:
iwl_free_resp(&hcmd);
return ret;
}
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
int iwl_nvm_init(struct iwl_mvm *mvm)
{
int ret, section;
u32 size_read = 0;
@ -648,63 +555,61 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
return -EINVAL;
/* load NVM values from nic */
if (read_nvm_from_nic) {
/* Read From FW NVM */
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
/* Read From FW NVM */
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
GFP_KERNEL);
if (!nvm_buffer)
return -ENOMEM;
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
/* we override the constness for initial read */
ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
size_read);
if (ret < 0)
continue;
size_read += ret;
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
if (!temp) {
ret = -ENOMEM;
break;
}
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
GFP_KERNEL);
if (!nvm_buffer)
return -ENOMEM;
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
/* we override the constness for initial read */
ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
size_read);
if (ret < 0)
continue;
size_read += ret;
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
if (!temp) {
ret = -ENOMEM;
break;
}
iwl_mvm_nvm_fixups(mvm, section, temp, ret);
iwl_mvm_nvm_fixups(mvm, section, temp, ret);
mvm->nvm_sections[section].data = temp;
mvm->nvm_sections[section].length = ret;
mvm->nvm_sections[section].data = temp;
mvm->nvm_sections[section].length = ret;
#ifdef CONFIG_IWLWIFI_DEBUGFS
switch (section) {
case NVM_SECTION_TYPE_SW:
mvm->nvm_sw_blob.data = temp;
mvm->nvm_sw_blob.size = ret;
switch (section) {
case NVM_SECTION_TYPE_SW:
mvm->nvm_sw_blob.data = temp;
mvm->nvm_sw_blob.size = ret;
break;
case NVM_SECTION_TYPE_CALIBRATION:
mvm->nvm_calib_blob.data = temp;
mvm->nvm_calib_blob.size = ret;
break;
case NVM_SECTION_TYPE_PRODUCTION:
mvm->nvm_prod_blob.data = temp;
mvm->nvm_prod_blob.size = ret;
break;
case NVM_SECTION_TYPE_PHY_SKU:
mvm->nvm_phy_sku_blob.data = temp;
mvm->nvm_phy_sku_blob.size = ret;
break;
default:
if (section == mvm->cfg->nvm_hw_section_num) {
mvm->nvm_hw_blob.data = temp;
mvm->nvm_hw_blob.size = ret;
break;
case NVM_SECTION_TYPE_CALIBRATION:
mvm->nvm_calib_blob.data = temp;
mvm->nvm_calib_blob.size = ret;
break;
case NVM_SECTION_TYPE_PRODUCTION:
mvm->nvm_prod_blob.data = temp;
mvm->nvm_prod_blob.size = ret;
break;
case NVM_SECTION_TYPE_PHY_SKU:
mvm->nvm_phy_sku_blob.data = temp;
mvm->nvm_phy_sku_blob.size = ret;
break;
default:
if (section == mvm->cfg->nvm_hw_section_num) {
mvm->nvm_hw_blob.data = temp;
mvm->nvm_hw_blob.size = ret;
break;
}
}
#endif
}
if (!size_read)
IWL_ERR(mvm, "OTP is blank\n");
kfree(nvm_buffer);
#endif
}
if (!size_read)
IWL_ERR(mvm, "OTP is blank\n");
kfree(nvm_buffer);
/* Only if PNVM selected in the mod param - load external NVM */
if (mvm->nvm_file_name) {

View File

@ -256,8 +256,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
iwl_mvm_rx_ant_coupling_notif, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
iwl_mvm_window_status_notif, RX_HANDLER_SYNC),
@ -325,7 +323,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(INIT_COMPLETE_NOTIF),
HCMD_NAME(PHY_CONTEXT_CMD),
HCMD_NAME(DBG_CFG),
HCMD_NAME(ANTENNA_COUPLING_NOTIFICATION),
HCMD_NAME(SCAN_CFG_CMD),
HCMD_NAME(SCAN_REQ_UMAC),
HCMD_NAME(SCAN_ABORT_UMAC),
@ -350,13 +347,13 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(BINDING_CONTEXT_CMD),
HCMD_NAME(TIME_QUOTA_CMD),
HCMD_NAME(NON_QOS_TX_COUNTER_CMD),
HCMD_NAME(LEDS_CMD),
HCMD_NAME(LQ_CMD),
HCMD_NAME(FW_PAGING_BLOCK_CMD),
HCMD_NAME(SCAN_OFFLOAD_REQUEST_CMD),
HCMD_NAME(SCAN_OFFLOAD_ABORT_CMD),
HCMD_NAME(HOT_SPOT_CMD),
HCMD_NAME(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
HCMD_NAME(BT_COEX_UPDATE_CORUN_LUT),
HCMD_NAME(BT_COEX_UPDATE_REDUCED_TXP),
HCMD_NAME(BT_COEX_CI),
HCMD_NAME(PHY_CONFIGURATION_CMD),
@ -387,6 +384,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
HCMD_NAME(REPLY_RX_PHY_CMD),
HCMD_NAME(REPLY_RX_MPDU_CMD),
HCMD_NAME(FRAME_RELEASE),
HCMD_NAME(BA_NOTIF),
HCMD_NAME(MCC_UPDATE_CMD),
HCMD_NAME(MCC_CHUB_UPDATE_CMD),
@ -754,7 +752,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
iwl_mvm_stop_device(mvm);
iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
mutex_unlock(&mvm->mutex);
/* returns 0 if successful, 1 if success but in rfkill */
if (err < 0) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
goto out_free;

View File

@ -622,7 +622,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
/* start BA session until the peer sends del BA */
ret = ieee80211_start_tx_ba_session(sta, tid, 0);
if (ret == -EAGAIN) {
/*
* driver and mac80211 is out of sync
@ -636,15 +638,31 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
return ret;
}
static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid,
struct iwl_lq_sta *lq_data,
static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
u8 tid, struct iwl_lq_sta *lq_sta,
struct ieee80211_sta *sta)
{
if (tid < IWL_MAX_TID_COUNT)
rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
else
struct iwl_mvm_tid_data *tid_data;
/*
* In AP mode, tid can be equal to IWL_MAX_TID_COUNT
* when the frame is not QoS
*/
if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) {
IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",
tid, IWL_MAX_TID_COUNT);
return;
} else if (tid == IWL_MAX_TID_COUNT) {
return;
}
tid_data = &mvmsta->tid_data[tid];
if ((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)) {
IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta);
}
}
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
@ -753,8 +771,38 @@ static int rs_collect_tpc_data(struct iwl_mvm *mvm,
window);
}
static void rs_update_tid_tpt_stats(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvmsta,
u8 tid, int successes)
{
struct iwl_mvm_tid_data *tid_data;
if (tid >= IWL_MAX_TID_COUNT)
return;
tid_data = &mvmsta->tid_data[tid];
/*
* Measure if there're enough successful transmits per second.
* These statistics are used only to decide if we can start a
* BA session, so it should be updated only when A-MPDU is
* off.
*/
if (tid_data->state != IWL_AGG_OFF)
return;
if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) ||
(tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
tid_data->tx_count_last = tid_data->tx_count;
tid_data->tx_count = 0;
tid_data->tpt_meas_start = jiffies;
} else {
tid_data->tx_count += successes;
}
}
static int rs_collect_tlc_data(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_sta,
struct iwl_mvm_sta *mvmsta, u8 tid,
struct iwl_scale_tbl_info *tbl,
int scale_index, int attempts, int successes)
{
@ -764,12 +812,14 @@ static int rs_collect_tlc_data(struct iwl_mvm *mvm,
return -EINVAL;
if (tbl->column != RS_COLUMN_INVALID) {
struct lq_sta_pers *pers = &lq_sta->pers;
struct lq_sta_pers *pers = &mvmsta->lq_sta.pers;
pers->tx_stats[tbl->column][scale_index].total += attempts;
pers->tx_stats[tbl->column][scale_index].success += successes;
}
rs_update_tid_tpt_stats(mvm, mvmsta, tid, successes);
/* Select window for current tx bit rate */
window = &(tbl->win[scale_index]);
return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
@ -1211,12 +1261,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (time_after(jiffies,
(unsigned long)(lq_sta->last_tx +
(IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
int t;
IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
for (t = 0; t < IWL_MAX_TID_COUNT; t++)
ieee80211_stop_tx_ba_session(sta, t);
iwl_mvm_rs_rate_init(mvm, sta, info->band, false);
return;
}
@ -1312,7 +1357,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (info->status.ampdu_ack_len == 0)
info->status.ampdu_len = 1;
rs_collect_tlc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl, tx_resp_rate.index,
info->status.ampdu_len,
info->status.ampdu_ack_len);
@ -1351,7 +1396,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
tx_resp_rate.index, 1,
i < retries ? 0 : legacy_success,
reduced_txp);
rs_collect_tlc_data(mvm, lq_sta, tmp_tbl,
rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
tx_resp_rate.index, 1,
i < retries ? 0 : legacy_success);
}
@ -1673,14 +1718,14 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct iwl_scale_tbl_info *tbl,
enum rs_action scale_action)
{
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
scale_action == RS_ACTION_DOWNSCALE)
sta_priv->tlc_amsdu = false;
mvmsta->tlc_amsdu = false;
else
sta_priv->tlc_amsdu = true;
mvmsta->tlc_amsdu = true;
}
/*
@ -2228,11 +2273,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
u16 high_low;
s32 sr;
u8 prev_agg = lq_sta->is_agg;
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_tid_data *tid_data;
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct rs_rate *rate;
lq_sta->is_agg = !!sta_priv->agg_tids;
lq_sta->is_agg = !!mvmsta->agg_tids;
/*
* Select rate-scale / modulation-mode table to work with in
@ -2480,44 +2524,12 @@ lq_update:
}
}
if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
/* If the "active" (non-search) mode was legacy,
* and we've tried switching antennas,
* but we haven't been able to try HT modes (not available),
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(&tbl1->rate)) {
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
if (!ndp)
rs_tl_turn_on_agg(mvm, mvmsta, tid, lq_sta, sta);
if (tid != IWL_MAX_TID_COUNT) {
tid_data = &sta_priv->tid_data[tid];
if (tid_data->state != IWL_AGG_OFF) {
IWL_DEBUG_RATE(mvm,
"Stop aggregation on tid %d\n",
tid);
ieee80211_stop_tx_ba_session(sta, tid);
}
}
rs_set_stay_in_table(mvm, 1, lq_sta);
} else {
/* If we're in an HT mode, and all 3 mode switch actions
* have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != IWL_MAX_TID_COUNT)) {
tid_data = &sta_priv->tid_data[tid];
if (tid_data->state == IWL_AGG_OFF && !ndp) {
IWL_DEBUG_RATE(mvm,
"try to aggregate tid %d\n",
tid);
rs_tl_turn_on_agg(mvm, tid,
lq_sta, sta);
}
}
rs_set_stay_in_table(mvm, 0, lq_sta);
}
if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
rs_set_stay_in_table(mvm, is_legacy(&tbl1->rate), lq_sta);
}
}
@ -2900,10 +2912,10 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
gfp_t gfp)
{
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
@ -2917,7 +2929,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
lq_sta->pers.last_rssi = S8_MIN;
return &sta_priv->lq_sta;
return &mvmsta->lq_sta;
}
static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
@ -3109,8 +3121,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_hw *hw = mvm->hw;
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
struct ieee80211_supported_band *sband;
unsigned long supp; /* must be unsigned long for for_each_set_bit */
@ -3119,8 +3131,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
sband = hw->wiphy->bands[band];
lq_sta->lq.sta_id = sta_priv->sta_id;
sta_priv->tlc_amsdu = false;
lq_sta->lq.sta_id = mvmsta->sta_id;
mvmsta->tlc_amsdu = false;
for (j = 0; j < LQ_SIZE; j++)
rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
@ -3130,7 +3142,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
IWL_DEBUG_RATE(mvm,
"LQ: *** rate scale station global init for station %d ***\n",
sta_priv->sta_id);
mvmsta->sta_id);
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately

View File

@ -1278,6 +1278,50 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
}
}
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr,
u16 mac_id, u16 color)
{
struct iwl_mvm_add_sta_cmd cmd;
int ret;
u32 status;
lockdep_assert_held(&mvm->mutex);
memset(&cmd, 0, sizeof(cmd));
cmd.sta_id = sta->sta_id;
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
color));
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
cmd.station_type = sta->type;
if (!iwl_mvm_has_new_tx_api(mvm))
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
cmd.tid_disable_tx = cpu_to_le16(0xffff);
if (addr)
memcpy(cmd.addr, addr, ETH_ALEN);
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
iwl_mvm_add_sta_cmd_size(mvm),
&cmd, &status);
if (ret)
return ret;
switch (status & IWL_ADD_STA_STATUS_MASK) {
case ADD_STA_SUCCESS:
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
return 0;
default:
ret = -EIO;
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
status);
break;
}
return ret;
}
int iwl_mvm_add_sta(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
@ -1286,6 +1330,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_rxq_dup_data *dup_data;
int i, ret, sta_id;
bool sta_update = false;
unsigned int sta_flags = 0;
lockdep_assert_held(&mvm->mutex);
@ -1302,7 +1348,23 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
/* if this is a HW restart re-alloc existing queues */
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
struct iwl_mvm_int_sta tmp_sta = {
.sta_id = sta_id,
.type = mvm_sta->sta_type,
};
/*
* First add an empty station since allocating
* a queue requires a valid station
*/
ret = iwl_mvm_add_int_sta_common(mvm, &tmp_sta, sta->addr,
mvmvif->id, mvmvif->color);
if (ret)
goto err;
iwl_mvm_realloc_queues_after_restart(mvm, mvm_sta);
sta_update = true;
sta_flags = iwl_mvm_has_new_tx_api(mvm) ? 0 : STA_MODIFY_QUEUES;
goto update_fw;
}
@ -1369,7 +1431,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
}
update_fw:
ret = iwl_mvm_sta_send_to_fw(mvm, sta, false, 0);
ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
if (ret)
goto err;
@ -1638,50 +1700,6 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
sta->sta_id = IWL_MVM_INVALID_STA;
}
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr,
u16 mac_id, u16 color)
{
struct iwl_mvm_add_sta_cmd cmd;
int ret;
u32 status;
lockdep_assert_held(&mvm->mutex);
memset(&cmd, 0, sizeof(cmd));
cmd.sta_id = sta->sta_id;
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
color));
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
cmd.station_type = sta->type;
if (!iwl_mvm_has_new_tx_api(mvm))
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
cmd.tid_disable_tx = cpu_to_le16(0xffff);
if (addr)
memcpy(cmd.addr, addr, ETH_ALEN);
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
iwl_mvm_add_sta_cmd_size(mvm),
&cmd, &status);
if (ret)
return ret;
switch (status & IWL_ADD_STA_STATUS_MASK) {
case ADD_STA_SUCCESS:
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
return 0;
default:
ret = -EIO;
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
status);
break;
}
return ret;
}
static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
{
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?

View File

@ -316,6 +316,10 @@ enum iwl_mvm_agg_state {
* @is_tid_active: has this TID sent traffic in the last
* %IWL_MVM_DQA_QUEUE_TIMEOUT time period. If %txq_id is invalid, this
* field should be ignored.
* @tpt_meas_start: time of the throughput measurements start, is reset every HZ
* @tx_count_last: number of frames transmitted during the last second
* @tx_count: counts the number of frames transmitted since the last reset of
* tpt_meas_start
*/
struct iwl_mvm_tid_data {
struct sk_buff_head deferred_tx_frames;
@ -330,6 +334,9 @@ struct iwl_mvm_tid_data {
u16 ssn;
u16 tx_time;
bool is_tid_active;
unsigned long tpt_meas_start;
u32 tx_count_last;
u32 tx_count;
};
struct iwl_mvm_key_pn {

View File

@ -7,6 +7,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH
*
* 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
@ -33,6 +34,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -726,8 +728,21 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
u32 id;
lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock);
id = te_data->id;
spin_unlock_bh(&mvm->time_event_lock);
if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
IWL_DEBUG_TE(mvm,
"don't remove TE with id=%u (not session protection)\n",
id);
return;
}
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
}
@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
if (te_data->running) {
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
return -EBUSY;
u32 id;
spin_lock_bh(&mvm->time_event_lock);
id = te_data->id;
spin_unlock_bh(&mvm->time_event_lock);
if (id == TE_CHANNEL_SWITCH_PERIOD) {
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
return -EBUSY;
}
/*
* Remove the session protection time event to allow the
* channel switch. If we got here, we just heard a beacon so
* the session protection is not needed anymore anyway.
*/
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
}
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);

View File

@ -71,7 +71,7 @@
#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
{
struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
u32 duration = tt->params.ct_kill_duration;
@ -813,7 +813,7 @@ unlock:
return ret;
}
static struct thermal_cooling_device_ops tcooling_ops = {
static const struct thermal_cooling_device_ops tcooling_ops = {
.get_max_state = iwl_mvm_tcool_get_max_state,
.get_cur_state = iwl_mvm_tcool_get_cur_state,
.set_cur_state = iwl_mvm_tcool_set_cur_state,

View File

@ -1337,6 +1337,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
while (!skb_queue_empty(&skbs)) {
struct sk_buff *skb = __skb_dequeue(&skbs);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
bool flushed = false;
skb_freed++;
@ -1350,6 +1351,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
case TX_STATUS_DIRECT_DONE:
info->flags |= IEEE80211_TX_STAT_ACK;
break;
case TX_STATUS_FAIL_FIFO_FLUSHED:
case TX_STATUS_FAIL_DRAIN_FLOW:
flushed = true;
break;
case TX_STATUS_FAIL_DEST_PS:
/* the FW should have stopped the queue and not
* return this status
@ -1372,7 +1377,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/* Single frame failure in an AMPDU queue => send BAR */
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
!(info->flags & IEEE80211_TX_STAT_ACK) &&
!(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
!(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed)
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
@ -1521,7 +1526,7 @@ static const char *iwl_get_agg_tx_status(u16 status)
AGG_TX_STATE_(BT_PRIO);
AGG_TX_STATE_(FEW_BYTES);
AGG_TX_STATE_(ABORT);
AGG_TX_STATE_(LAST_SENT_TTL);
AGG_TX_STATE_(TX_ON_AIR_DROP);
AGG_TX_STATE_(LAST_SENT_TRY_CNT);
AGG_TX_STATE_(LAST_SENT_BT_KILL);
AGG_TX_STATE_(SCD_QUERY);

View File

@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
ctxt_info->hcmd_cfg.cmd_queue_addr =
cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
ctxt_info->hcmd_cfg.cmd_queue_size =
TFD_QUEUE_CB_SIZE(TFD_QUEUE_SIZE_MAX);
TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);
/* allocate ucode sections in dram and set addresses */
ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info);

View File

@ -430,6 +430,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)},
/* 8000 Series */
{IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
@ -710,12 +711,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_trans->cfg = cfg_7265d;
}
if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb) {
if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_JF)
cfg = &iwla000_2ac_cfg_jf;
else if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR)
cfg = &iwla000_2ac_cfg_hr;
if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb &&
iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR);
if (rf_id_chp == jf_chp_id) {
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
cfg = &iwla000_2ax_cfg_qnj_jf_b0;
else
cfg = &iwla000_2ac_cfg_jf;
} else if (rf_id_chp == hr_chp_id) {
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
cfg = &iwla000_2ax_cfg_qnj_hr_a0;
else
cfg = &iwla000_2ac_cfg_hr;
}
iwl_trans->cfg = cfg;
}
#endif

View File

@ -661,10 +661,16 @@ static inline void iwl_pcie_sw_reset(struct iwl_trans *trans)
usleep_range(5000, 6000);
}
static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq *q, u32 index)
{
return index & (q->n_window - 1);
}
static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie,
struct iwl_txq *txq, int idx)
{
return txq->tfds + trans_pcie->tfd_size * idx;
return txq->tfds + trans_pcie->tfd_size * iwl_pcie_get_cmd_index(txq,
idx);
}
static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
@ -726,11 +732,6 @@ static inline bool iwl_queue_used(const struct iwl_txq *q, int i)
!(i < q->read_ptr && i >= q->write_ptr);
}
static inline u8 get_cmd_index(struct iwl_txq *q, u32 index)
{
return index & (q->n_window - 1);
}
static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@ -806,6 +807,8 @@ int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans,
struct iwl_dma_ptr *ptr, size_t size);
void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr);
void iwl_pcie_apply_destination(struct iwl_trans *trans);
void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
struct sk_buff *skb);
#ifdef CONFIG_INET
struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len);
#endif

View File

@ -1176,7 +1176,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
sequence = le16_to_cpu(pkt->hdr.sequence);
index = SEQ_TO_INDEX(sequence);
cmd_index = get_cmd_index(txq, index);
cmd_index = iwl_pcie_get_cmd_index(txq, index);
if (rxq->id == 0)
iwl_op_mode_rx(trans->op_mode, &rxq->napi,

View File

@ -1842,8 +1842,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
* These bits say the device is running, and should keep running for
* at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
* but they do not indicate that embedded SRAM is restored yet;
* 3945 and 4965 have volatile SRAM, and must save/restore contents
* to/from host DRAM when sleeping/waking for power-saving.
* HW with volatile SRAM must save/restore contents to/from
* host DRAM when sleeping/waking for power-saving.
* Each direction takes approximately 1/4 millisecond; with this
* overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
* series of register accesses are expected (e.g. reading Event Log),
@ -1851,8 +1851,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
*
* CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
* SRAM is okay/restored. We don't check that here because this call
* is just for hardware register access; but GP1 MAC_SLEEP check is a
* good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
* is just for hardware register access; but GP1 MAC_SLEEP
* check is a good idea before accessing the SRAM of HW with
* volatile SRAM (e.g. reading Event Log).
*
* 5000 series and later (including 1000 series) have non-volatile SRAM,
* and do not save/restore SRAM when power cycling.
@ -2834,7 +2835,7 @@ static struct iwl_trans_dump_data
spin_lock_bh(&cmdq->lock);
ptr = cmdq->write_ptr;
for (i = 0; i < cmdq->n_window; i++) {
u8 idx = get_cmd_index(cmdq, ptr);
u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr);
u32 caplen, cmdlen;
cmdlen = iwl_trans_pcie_get_cmdlen(trans, cmdq->tfds +
@ -3137,7 +3138,18 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
iwl_set_bit(trans, CSR_HOST_CHICKEN,
CSR_HOST_CHICKEN_PM_IDLE_SRC_DIS_SB_PME);
#if IS_ENABLED(CONFIG_IWLMVM)
trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
if (trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR) {
u32 hw_status;
hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
if (hw_status & UMAG_GEN_HW_IS_FPGA)
trans->cfg = &iwla000_2ax_cfg_qnj_hr_f0;
else
trans->cfg = &iwla000_2ac_cfg_hr;
}
#endif
iwl_pcie_set_interrupt_capa(pdev, trans);
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;

View File

@ -88,14 +88,14 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt,
int num_tbs)
{
struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr;
int write_ptr = txq->write_ptr;
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
u8 filled_tfd_size, num_fetch_chunks;
u16 len = byte_cnt;
__le16 bc_ent;
len = DIV_ROUND_UP(len, 4);
if (WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX))
if (WARN_ON(len > 0xFFF || idx >= txq->n_window))
return;
filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) +
@ -111,7 +111,7 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq *txq, u16 byte_cnt,
num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
scd_bc_tbl->tfd_offset[write_ptr] = bc_ent;
scd_bc_tbl->tfd_offset[idx] = bc_ent;
}
/*
@ -176,16 +176,12 @@ static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
/* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
* idx is bounded by n_window
*/
int rd_ptr = txq->read_ptr;
int idx = get_cmd_index(txq, rd_ptr);
int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
lockdep_assert_held(&txq->lock);
/* We have only q->n_window txq->entries, but we use
* TFD_QUEUE_SIZE_MAX tfds
*/
iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta,
iwl_pcie_get_tfd(trans_pcie, txq, rd_ptr));
iwl_pcie_get_tfd(trans_pcie, txq, idx));
/* free SKB */
if (txq->entries) {
@ -373,8 +369,9 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
struct iwl_tfh_tfd *tfd =
iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr);
iwl_pcie_get_tfd(trans_pcie, txq, idx);
dma_addr_t tb_phys;
bool amsdu;
int i, len, tb1_len, tb2_len, hdr_len;
@ -386,10 +383,10 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
(*ieee80211_get_qos_ctl(hdr) &
IEEE80211_QOS_CTL_A_MSDU_PRESENT);
tb_phys = iwl_pcie_get_first_tb_dma(txq, txq->write_ptr);
tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);
/* The first TB points to bi-directional DMA data */
if (!amsdu)
memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr,
memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr,
IWL_FIRST_TB_SIZE);
iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);
@ -431,7 +428,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
* building the A-MSDU might have changed this data, so memcpy
* it now
*/
memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr,
memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr,
IWL_FIRST_TB_SIZE);
return tfd;
}
@ -484,6 +481,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload;
struct iwl_cmd_meta *out_meta;
struct iwl_txq *txq = trans_pcie->txq[txq_id];
int idx;
void *tfd;
if (WARN_ONCE(!test_bit(txq_id, trans_pcie->queue_used),
@ -497,16 +495,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
spin_lock(&txq->lock);
idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
/* Set up driver data for this TFD */
txq->entries[txq->write_ptr].skb = skb;
txq->entries[txq->write_ptr].cmd = dev_cmd;
txq->entries[idx].skb = skb;
txq->entries[idx].cmd = dev_cmd;
dev_cmd->hdr.sequence =
cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
INDEX_TO_SEQ(txq->write_ptr)));
INDEX_TO_SEQ(idx)));
/* Set up first empty entry in queue's array of Tx/cmd buffers */
out_meta = &txq->entries[txq->write_ptr].meta;
out_meta = &txq->entries[idx].meta;
out_meta->flags = 0;
tfd = iwl_pcie_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta);
@ -562,7 +562,7 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
unsigned long flags;
void *dup_buf = NULL;
dma_addr_t phys_addr;
int idx, i, cmd_pos;
int i, cmd_pos, idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
u16 copy_size, cmd_size, tb0_size;
bool had_nocopy = false;
u8 group_id = iwl_cmd_groupid(cmd->id);
@ -651,7 +651,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf;
}
idx = get_cmd_index(txq, txq->write_ptr);
out_cmd = txq->entries[idx].cmd;
out_meta = &txq->entries[idx].meta;
@ -937,6 +936,15 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
txq_id, txq->read_ptr);
if (txq_id != trans_pcie->cmd_queue) {
int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
struct sk_buff *skb = txq->entries[idx].skb;
if (WARN_ON_ONCE(!skb))
continue;
iwl_pcie_free_tso_page(trans_pcie, skb);
}
iwl_pcie_gen2_free_tfd(trans, txq);
txq->read_ptr = iwl_queue_inc_wrap(txq->read_ptr);
@ -1033,6 +1041,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
.flags = CMD_WANT_SKB,
};
int ret, qid;
u32 wr_ptr;
txq = kzalloc(sizeof(*txq), GFP_KERNEL);
if (!txq)
@ -1060,7 +1069,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
cmd->tfdq_addr = cpu_to_le64(txq->dma_addr);
cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma);
cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(TFD_QUEUE_SIZE_MAX));
cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(TFD_TX_CMD_SLOTS));
ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret)
@ -1073,6 +1082,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
rsp = (void *)hcmd.resp_pkt->data;
qid = le16_to_cpu(rsp->queue_number);
wr_ptr = le16_to_cpu(rsp->write_pointer);
if (qid >= ARRAY_SIZE(trans_pcie->txq)) {
WARN_ONCE(1, "queue index %d unsupported", qid);
@ -1088,10 +1098,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
txq->id = qid;
trans_pcie->txq[qid] = txq;
wr_ptr &= (TFD_QUEUE_SIZE_MAX - 1);
/* Place first TFD at index corresponding to start sequence number */
txq->read_ptr = le16_to_cpu(rsp->write_pointer);
txq->write_ptr = le16_to_cpu(rsp->write_pointer);
txq->read_ptr = wr_ptr;
txq->write_ptr = wr_ptr;
iwl_write_direct32(trans, HBUS_TARG_WRPTR,
(txq->write_ptr) | (qid << 16));
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);

View File

@ -106,7 +106,7 @@ static int iwl_queue_init(struct iwl_txq *q, int slots_num)
q->n_window = slots_num;
/* slots_num must be power-of-two size, otherwise
* get_cmd_index is broken. */
* iwl_pcie_get_cmd_index is broken. */
if (WARN_ON(!is_power_of_2(slots_num)))
return -EINVAL;
@ -428,7 +428,7 @@ void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
* idx is bounded by n_window
*/
int rd_ptr = txq->read_ptr;
int idx = get_cmd_index(txq, rd_ptr);
int idx = iwl_pcie_get_cmd_index(txq, rd_ptr);
lockdep_assert_held(&txq->lock);
@ -577,8 +577,8 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
return 0;
}
static void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
struct sk_buff *skb)
void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
struct sk_buff *skb)
{
struct page **page_ptr;
@ -1100,7 +1100,8 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
for (;
txq->read_ptr != tfd_num;
txq->read_ptr = iwl_queue_inc_wrap(txq->read_ptr)) {
struct sk_buff *skb = txq->entries[txq->read_ptr].skb;
int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
struct sk_buff *skb = txq->entries[idx].skb;
if (WARN_ON_ONCE(!skb))
continue;
@ -1109,7 +1110,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
__skb_queue_tail(skbs, skb);
txq->entries[txq->read_ptr].skb = NULL;
txq->entries[idx].skb = NULL;
if (!trans->cfg->use_tfh)
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
@ -1559,7 +1560,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf;
}
idx = get_cmd_index(txq, txq->write_ptr);
idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
out_cmd = txq->entries[idx].cmd;
out_meta = &txq->entries[idx].meta;
@ -1751,7 +1752,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
spin_lock_bh(&txq->lock);
cmd_index = get_cmd_index(txq, index);
cmd_index = iwl_pcie_get_cmd_index(txq, index);
cmd = txq->entries[cmd_index].cmd;
meta = &txq->entries[cmd_index].meta;
group_id = cmd->hdr.group_id;

View File

@ -210,7 +210,7 @@ struct ezusb_packet {
} __packed;
/* Table of devices that work or may work with this driver */
static struct usb_device_id ezusb_table[] = {
static const struct usb_device_id ezusb_table[] = {
{USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_WL215_ID)},
{USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_HP_WL215_ID)},
{USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_W200_ID)},

View File

@ -41,7 +41,7 @@ MODULE_FIRMWARE("isl3887usb");
* whenever you add a new device.
*/
static struct usb_device_id p54u_table[] = {
static const struct usb_device_id p54u_table[] = {
/* Version 1 devices (pci chip + net2280) */
{USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
{USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */

View File

@ -52,7 +52,7 @@ static const struct lbs_fw_table fw_table[] = {
{ MODEL_8682, "libertas/usb8682.bin", NULL }
};
static struct usb_device_id if_usb_table[] = {
static const struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
{ USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
{ USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },

View File

@ -31,7 +31,7 @@ module_param_named(fw_name, lbtf_fw_name, charp, 0644);
MODULE_FIRMWARE("lbtf_usb.bin");
static struct usb_device_id if_usb_table[] = {
static const struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
{ USB_DEVICE(0x1286, 0x2001) },
{ USB_DEVICE(0x05a3, 0x8388) },

View File

@ -889,23 +889,15 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
switch (type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_STA);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
break;
case NL80211_IFTYPE_P2P_CLIENT:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
break;
case NL80211_IFTYPE_P2P_GO:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
break;
case NL80211_IFTYPE_AP:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_UAP);
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
break;
default:
@ -923,6 +915,8 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
adapter->rx_locked = false;
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
mwifiex_set_mac_address(priv, dev);
return 0;
}
@ -2012,6 +2006,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
priv->state_11h.is_11h_active = false;
}
mwifiex_config_uap_11d(priv, &params->beacon);
if (mwifiex_config_start_uap(priv, bss_cfg)) {
mwifiex_dbg(priv->adapter, ERROR,
"Failed to start AP\n");
@ -2963,6 +2959,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
}
mwifiex_init_priv_params(priv, dev);
mwifiex_set_mac_address(priv, dev);
priv->netdev = dev;
ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
@ -2990,7 +2988,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
dev_net_set(dev, wiphy_net(wiphy));
dev->ieee80211_ptr = &priv->wdev;
dev->ieee80211_ptr->iftype = priv->bss_mode;
memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
@ -3391,11 +3388,8 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
for (i = 0; i < adapter->priv_num; i++) {
priv = adapter->priv[i];
if (priv && priv->netdev) {
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev);
}
if (priv && priv->netdev)
netif_device_detach(priv->netdev);
}
for (i = 0; i < retry_num; i++) {
@ -3466,11 +3460,8 @@ static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
for (i = 0; i < adapter->priv_num; i++) {
priv = adapter->priv[i];
if (priv && priv->netdev) {
if (!netif_carrier_ok(priv->netdev))
netif_carrier_on(priv->netdev);
mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
}
if (priv && priv->netdev)
netif_device_attach(priv->netdev);
}
if (!wiphy->wowlan_config)

View File

@ -253,7 +253,7 @@ mwifiex_cmd_append_wps_ie(struct mwifiex_private *priv, u8 **buffer)
priv->wps_ie_len, *buffer);
/* Wrap the generic IE buffer with a pass through TLV type */
ie_header.type = cpu_to_le16(TLV_TYPE_MGMT_IE);
ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
ie_header.len = cpu_to_le16(priv->wps_ie_len);
memcpy(*buffer, &ie_header, sizeof(ie_header));
*buffer += sizeof(ie_header);

View File

@ -940,31 +940,44 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
/*
* CFG802.11 network device handler for setting MAC address.
*/
static int
mwifiex_set_mac_address(struct net_device *dev, void *addr)
int mwifiex_set_mac_address(struct mwifiex_private *priv,
struct net_device *dev)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct sockaddr *hw_addr = addr;
int ret;
u64 mac_addr;
memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
if (priv->bss_type != MWIFIEX_BSS_TYPE_P2P)
goto done;
mac_addr = ether_addr_to_u64(priv->curr_addr);
mac_addr |= BIT_ULL(MWIFIEX_MAC_LOCAL_ADMIN_BIT);
u64_to_ether_addr(mac_addr, priv->curr_addr);
/* Send request to firmware */
ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
HostCmd_ACT_GEN_SET, 0, NULL, true);
if (!ret)
memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
else
if (ret) {
mwifiex_dbg(priv->adapter, ERROR,
"set mac address failed: ret=%d\n", ret);
return ret;
}
done:
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
return 0;
}
return ret;
/* CFG802.11 network device handler for setting MAC address.
*/
static int
mwifiex_ndo_set_mac_address(struct net_device *dev, void *addr)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct sockaddr *hw_addr = addr;
memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
return mwifiex_set_mac_address(priv, dev);
}
/*
@ -1257,7 +1270,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
.ndo_open = mwifiex_open,
.ndo_stop = mwifiex_close,
.ndo_start_xmit = mwifiex_hard_start_xmit,
.ndo_set_mac_address = mwifiex_set_mac_address,
.ndo_set_mac_address = mwifiex_ndo_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = mwifiex_tx_timeout,
.ndo_get_stats = mwifiex_get_stats,
@ -1301,7 +1314,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
priv->gen_idx = MWIFIEX_AUTO_IDX_MASK;
priv->num_tx_timeout = 0;
ether_addr_copy(priv->curr_addr, priv->adapter->perm_addr);
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {

View File

@ -165,6 +165,8 @@ enum {
/* Address alignment */
#define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
#define MWIFIEX_MAC_LOCAL_ADMIN_BIT 41
/**
*enum mwifiex_debug_level - marvell wifi debug level
*/
@ -1562,6 +1564,9 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
struct mwifiex_sta_node *node);
void mwifiex_config_uap_11d(struct mwifiex_private *priv,
struct cfg80211_beacon_data *beacon_data);
void mwifiex_init_11h_params(struct mwifiex_private *priv);
int mwifiex_is_11h_active(struct mwifiex_private *priv);
int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag);
@ -1671,6 +1676,8 @@ void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
struct sk_buff *event_skb);
void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter);
int mwifiex_set_mac_address(struct mwifiex_private *priv,
struct net_device *dev);
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);

View File

@ -1947,7 +1947,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
}
adapter->active_scan_triggered = true;
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
if (priv->scan_request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
user_scan_cfg->ssid_list = priv->scan_request->ssids;
@ -2790,7 +2791,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
if (!scan_cfg)
return -ENOMEM;
ether_addr_copy(scan_cfg->random_mac, priv->random_mac);
scan_cfg->ssid_list = req_ssid;
scan_cfg->num_ssids = 1;

View File

@ -444,6 +444,28 @@ mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
return;
}
/* This function enable 11D if userspace set the country IE.
*/
void mwifiex_config_uap_11d(struct mwifiex_private *priv,
struct cfg80211_beacon_data *beacon_data)
{
enum state_11d_t state_11d;
const u8 *country_ie;
country_ie = cfg80211_find_ie(WLAN_EID_COUNTRY, beacon_data->tail,
beacon_data->tail_len);
if (country_ie) {
/* Send cmd to FW to enable 11D function */
state_11d = ENABLE_11D;
if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
HostCmd_ACT_GEN_SET, DOT11D_I,
&state_11d, true)) {
mwifiex_dbg(priv->adapter, ERROR,
"11D: failed to enable 11D\n");
}
}
}
/* This function parses BSS related parameters from structure
* and prepares TLVs. These TLVs are appended to command buffer.
*/
@ -848,8 +870,6 @@ void mwifiex_uap_set_channel(struct mwifiex_private *priv,
int mwifiex_config_start_uap(struct mwifiex_private *priv,
struct mwifiex_uap_bss_param *bss_cfg)
{
enum state_11d_t state_11d;
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
HostCmd_ACT_GEN_SET,
UAP_BSS_PARAMS_I, bss_cfg, true)) {
@ -858,16 +878,6 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
return -1;
}
/* Send cmd to FW to enable 11D function */
state_11d = ENABLE_11D;
if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
HostCmd_ACT_GEN_SET, DOT11D_I,
&state_11d, true)) {
mwifiex_dbg(priv->adapter, ERROR,
"11D: failed to enable 11D\n");
return -1;
}
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
HostCmd_ACT_GEN_SET, 0, NULL, true)) {
mwifiex_dbg(priv->adapter, ERROR,

View File

@ -24,7 +24,7 @@
static struct mwifiex_if_ops usb_ops;
static struct usb_device_id mwifiex_usb_table[] = {
static const struct usb_device_id mwifiex_usb_table[] = {
/* 8766 */
{USB_DEVICE(USB8XXX_VID, USB8766_PID_1)},
{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8766_PID_2,

View File

@ -457,6 +457,9 @@ static void mt7601u_free_tx(struct mt7601u_dev *dev)
{
int i;
if (!dev->tx_q)
return;
for (i = 0; i < __MT_EP_OUT_MAX; i++)
mt7601u_free_tx_queue(&dev->tx_q[i]);
}
@ -484,6 +487,8 @@ static int mt7601u_alloc_tx(struct mt7601u_dev *dev)
dev->tx_q = devm_kcalloc(dev->dev, __MT_EP_OUT_MAX,
sizeof(*dev->tx_q), GFP_KERNEL);
if (!dev->tx_q)
return -ENOMEM;
for (i = 0; i < __MT_EP_OUT_MAX; i++)
if (mt7601u_alloc_tx_queue(dev, &dev->tx_q[i]))

View File

@ -19,7 +19,7 @@
#include "usb.h"
#include "trace.h"
static struct usb_device_id mt7601u_device_table[] = {
static const struct usb_device_id mt7601u_device_table[] = {
{ USB_DEVICE(0x0b05, 0x17d3) },
{ USB_DEVICE(0x0e8d, 0x760a) },
{ USB_DEVICE(0x0e8d, 0x760b) },

View File

@ -130,7 +130,6 @@ static __always_inline void qtnf_bus_unlock(struct qtnf_bus *bus)
/* interface functions from common layer */
void qtnf_rx_frame(struct device *dev, struct sk_buff *rxp);
int qtnf_core_attach(struct qtnf_bus *bus);
void qtnf_core_detach(struct qtnf_bus *bus);
void qtnf_txflowblock(struct device *dev, bool state);

View File

@ -25,6 +25,7 @@
#include <linux/completion.h>
#include <linux/crc32.h>
#include <linux/spinlock.h>
#include <linux/circ_buf.h>
#include "qtn_hw_ids.h"
#include "pcie_bus_priv.h"
@ -36,7 +37,7 @@ static bool use_msi = true;
module_param(use_msi, bool, 0644);
MODULE_PARM_DESC(use_msi, "set 0 to use legacy interrupt");
static unsigned int tx_bd_size_param = 256;
static unsigned int tx_bd_size_param = 32;
module_param(tx_bd_size_param, uint, 0644);
MODULE_PARM_DESC(tx_bd_size_param, "Tx descriptors queue size");
@ -44,10 +45,6 @@ static unsigned int rx_bd_size_param = 256;
module_param(rx_bd_size_param, uint, 0644);
MODULE_PARM_DESC(rx_bd_size_param, "Rx descriptors queue size");
static unsigned int rx_bd_reserved_param = 16;
module_param(rx_bd_reserved_param, uint, 0644);
MODULE_PARM_DESC(rx_bd_reserved_param, "Reserved RX descriptors");
static u8 flashboot = 1;
module_param(flashboot, byte, 0644);
MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS");
@ -392,9 +389,8 @@ static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv)
pr_debug("TX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
priv->tx_bd_reclaim_start = 0;
priv->tx_bd_index = 0;
priv->tx_queue_len = 0;
priv->tx_bd_r_index = 0;
priv->tx_bd_w_index = 0;
/* rx bd */
@ -411,36 +407,25 @@ static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv)
writel(priv->rx_bd_num | (sizeof(struct qtnf_rx_bd)) << 16,
PCIE_HDP_TX_HOST_Q_SZ_CTRL(priv->pcie_reg_base));
priv->hw_txproc_wr_ptr = priv->rx_bd_num - rx_bd_reserved_param;
writel(priv->hw_txproc_wr_ptr,
PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base));
pr_debug("RX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr);
priv->rx_bd_index = 0;
return 0;
}
static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 rx_bd_index)
static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 index)
{
struct qtnf_rx_bd *rxbd;
struct sk_buff *skb;
dma_addr_t paddr;
skb = __dev_alloc_skb(SKB_BUF_SIZE + NET_IP_ALIGN,
GFP_ATOMIC);
skb = __netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE, GFP_ATOMIC);
if (!skb) {
priv->rx_skb[rx_bd_index] = NULL;
priv->rx_skb[index] = NULL;
return -ENOMEM;
}
priv->rx_skb[rx_bd_index] = skb;
skb_reserve(skb, NET_IP_ALIGN);
rxbd = &priv->rx_bd_vbase[rx_bd_index];
priv->rx_skb[index] = skb;
rxbd = &priv->rx_bd_vbase[index];
paddr = pci_map_single(priv->pdev, skb->data,
SKB_BUF_SIZE, PCI_DMA_FROMDEVICE);
@ -449,17 +434,22 @@ static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 rx_bd_index)
return -ENOMEM;
}
writel(QTN_HOST_LO32(paddr),
PCIE_HDP_HHBM_BUF_PTR(priv->pcie_reg_base));
writel(QTN_HOST_HI32(paddr),
PCIE_HDP_HHBM_BUF_PTR_H(priv->pcie_reg_base));
/* keep rx skb paddrs in rx buffer descriptors for cleanup purposes */
rxbd->addr = cpu_to_le32(QTN_HOST_LO32(paddr));
rxbd->addr_h = cpu_to_le32(QTN_HOST_HI32(paddr));
rxbd->info = 0x0;
priv->rx_bd_w_index = index;
/* sync up all descriptor updates */
wmb();
writel(QTN_HOST_HI32(paddr),
PCIE_HDP_HHBM_BUF_PTR_H(priv->pcie_reg_base));
writel(QTN_HOST_LO32(paddr),
PCIE_HDP_HHBM_BUF_PTR(priv->pcie_reg_base));
writel(index, PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base));
return 0;
}
@ -516,6 +506,8 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv)
priv->tx_bd_num = tx_bd_size_param;
priv->rx_bd_num = rx_bd_size_param;
priv->rx_bd_w_index = 0;
priv->rx_bd_r_index = 0;
ret = alloc_skb_array(priv);
if (ret) {
@ -538,67 +530,72 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv)
return ret;
}
static int qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv)
static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv)
{
struct qtnf_tx_bd *txbd;
struct sk_buff *skb;
unsigned long flags;
dma_addr_t paddr;
int last_sent;
int count;
u32 tx_done_index;
int count = 0;
int i;
last_sent = readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
% priv->tx_bd_num;
i = priv->tx_bd_reclaim_start;
count = 0;
spin_lock_irqsave(&priv->tx_reclaim_lock, flags);
while (i != last_sent) {
tx_done_index = readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
& (priv->tx_bd_num - 1);
i = priv->tx_bd_r_index;
while (CIRC_CNT(tx_done_index, i, priv->tx_bd_num)) {
skb = priv->tx_skb[i];
if (!skb)
break;
if (likely(skb)) {
txbd = &priv->tx_bd_vbase[i];
paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
le32_to_cpu(txbd->addr));
pci_unmap_single(priv->pdev, paddr, skb->len,
PCI_DMA_TODEVICE);
txbd = &priv->tx_bd_vbase[i];
paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h),
le32_to_cpu(txbd->addr));
pci_unmap_single(priv->pdev, paddr, skb->len, PCI_DMA_TODEVICE);
if (skb->dev) {
skb->dev->stats.tx_packets++;
skb->dev->stats.tx_bytes += skb->len;
if (skb->dev) {
skb->dev->stats.tx_packets++;
skb->dev->stats.tx_bytes += skb->len;
if (netif_queue_stopped(skb->dev))
netif_wake_queue(skb->dev);
}
if (netif_queue_stopped(skb->dev))
netif_wake_queue(skb->dev);
dev_kfree_skb_any(skb);
}
dev_kfree_skb_any(skb);
priv->tx_skb[i] = NULL;
priv->tx_queue_len--;
count++;
if (++i >= priv->tx_bd_num)
i = 0;
}
priv->tx_bd_reclaim_start = i;
priv->tx_reclaim_done += count;
priv->tx_reclaim_req++;
priv->tx_bd_r_index = i;
return count;
spin_unlock_irqrestore(&priv->tx_reclaim_lock, flags);
}
static bool qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv)
static int qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv)
{
if (priv->tx_queue_len >= priv->tx_bd_num - 1) {
if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
priv->tx_bd_num)) {
pr_err_ratelimited("reclaim full Tx queue\n");
qtnf_pcie_data_tx_reclaim(priv);
if (priv->tx_queue_len >= priv->tx_bd_num - 1) {
if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index,
priv->tx_bd_num)) {
priv->tx_full_count++;
return false;
return 0;
}
}
return true;
return 1;
}
static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
@ -606,24 +603,18 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
dma_addr_t txbd_paddr, skb_paddr;
struct qtnf_tx_bd *txbd;
unsigned long flags;
int len, i;
u32 info;
int ret = 0;
spin_lock_irqsave(&priv->tx_lock, flags);
priv->tx_done_count++;
if (!qtnf_tx_queue_ready(priv)) {
if (skb->dev)
netif_stop_queue(skb->dev);
spin_unlock_irqrestore(&priv->tx_lock, flags);
return NETDEV_TX_BUSY;
}
i = priv->tx_bd_index;
i = priv->tx_bd_w_index;
priv->tx_skb[i] = skb;
len = skb->len;
@ -655,8 +646,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
if (++i >= priv->tx_bd_num)
i = 0;
priv->tx_bd_index = i;
priv->tx_queue_len++;
priv->tx_bd_w_index = i;
tx_done:
if (ret && skb) {
@ -666,7 +656,8 @@ tx_done:
dev_kfree_skb_any(skb);
}
spin_unlock_irqrestore(&priv->tx_lock, flags);
qtnf_pcie_data_tx_reclaim(priv);
priv->tx_done_count++;
return NETDEV_TX_OK;
}
@ -693,14 +684,21 @@ static irqreturn_t qtnf_interrupt(int irq, void *data)
if (!(status & priv->pcie_irq_mask))
goto irq_done;
if (status & PCIE_HDP_INT_RX_BITS) {
if (status & PCIE_HDP_INT_RX_BITS)
priv->pcie_irq_rx_count++;
if (status & PCIE_HDP_INT_TX_BITS)
priv->pcie_irq_tx_count++;
if (status & PCIE_HDP_INT_HHBM_UF)
priv->pcie_irq_uf_count++;
if (status & PCIE_HDP_INT_RX_BITS) {
qtnf_dis_rxdone_irq(priv);
napi_schedule(&bus->mux_napi);
}
if (status & PCIE_HDP_INT_TX_BITS) {
priv->pcie_irq_tx_count++;
qtnf_dis_txdone_irq(priv);
tasklet_hi_schedule(&priv->reclaim_tq);
}
@ -715,16 +713,19 @@ irq_done:
return IRQ_HANDLED;
}
static inline void hw_txproc_wr_ptr_inc(struct qtnf_pcie_bus_priv *priv)
static int qtnf_rx_data_ready(struct qtnf_pcie_bus_priv *priv)
{
u32 index;
u16 index = priv->rx_bd_r_index;
struct qtnf_rx_bd *rxbd;
u32 descw;
index = priv->hw_txproc_wr_ptr;
rxbd = &priv->rx_bd_vbase[index];
descw = le32_to_cpu(rxbd->info);
if (++index >= priv->rx_bd_num)
index = 0;
if (descw & QTN_TXDONE_MASK)
return 1;
priv->hw_txproc_wr_ptr = index;
return 0;
}
static int qtnf_rx_poll(struct napi_struct *napi, int budget)
@ -736,64 +737,96 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget)
int processed = 0;
struct qtnf_rx_bd *rxbd;
dma_addr_t skb_paddr;
int consume;
u32 descw;
u16 index;
u32 psize;
u16 r_idx;
u16 w_idx;
int ret;
index = priv->rx_bd_index;
rxbd = &priv->rx_bd_vbase[index];
while (processed < budget) {
descw = le32_to_cpu(rxbd->info);
while ((descw & QTN_TXDONE_MASK) && (processed < budget)) {
skb = priv->rx_skb[index];
if (!qtnf_rx_data_ready(priv))
goto rx_out;
if (likely(skb)) {
skb_put(skb, QTN_GET_LEN(descw));
r_idx = priv->rx_bd_r_index;
rxbd = &priv->rx_bd_vbase[r_idx];
descw = le32_to_cpu(rxbd->info);
skb = priv->rx_skb[r_idx];
psize = QTN_GET_LEN(descw);
consume = 1;
if (!(descw & QTN_TXDONE_MASK)) {
pr_warn("skip invalid rxbd[%d]\n", r_idx);
consume = 0;
}
if (!skb) {
pr_warn("skip missing rx_skb[%d]\n", r_idx);
consume = 0;
}
if (skb && (skb_tailroom(skb) < psize)) {
pr_err("skip packet with invalid length: %u > %u\n",
psize, skb_tailroom(skb));
consume = 0;
}
if (skb) {
skb_paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h),
le32_to_cpu(rxbd->addr));
pci_unmap_single(priv->pdev, skb_paddr, SKB_BUF_SIZE,
PCI_DMA_FROMDEVICE);
}
if (consume) {
skb_put(skb, psize);
ndev = qtnf_classify_skb(bus, skb);
if (likely(ndev)) {
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, ndev);
netif_receive_skb(skb);
napi_gro_receive(napi, skb);
} else {
pr_debug("drop untagged skb\n");
bus->mux_dev.stats.rx_dropped++;
dev_kfree_skb_any(skb);
}
processed++;
} else {
pr_err("missing rx_skb[%d]\n", index);
if (skb) {
bus->mux_dev.stats.rx_dropped++;
dev_kfree_skb_any(skb);
}
}
/* attached rx buffer is passed upstream: map a new one */
ret = skb2rbd_attach(priv, index);
if (likely(!ret)) {
if (++index >= priv->rx_bd_num)
index = 0;
priv->rx_skb[r_idx] = NULL;
if (++r_idx >= priv->rx_bd_num)
r_idx = 0;
priv->rx_bd_index = index;
hw_txproc_wr_ptr_inc(priv);
priv->rx_bd_r_index = r_idx;
rxbd = &priv->rx_bd_vbase[index];
descw = le32_to_cpu(rxbd->info);
} else {
pr_err("failed to allocate new rx_skb[%d]\n", index);
break;
/* repalce processed buffer by a new one */
w_idx = priv->rx_bd_w_index;
while (CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
priv->rx_bd_num) > 0) {
if (++w_idx >= priv->rx_bd_num)
w_idx = 0;
ret = skb2rbd_attach(priv, w_idx);
if (ret) {
pr_err("failed to allocate new rx_skb[%d]\n",
w_idx);
break;
}
}
writel(priv->hw_txproc_wr_ptr,
PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base));
processed++;
}
rx_out:
if (processed < budget) {
napi_complete(napi);
qtnf_en_rxdone_irq(priv);
@ -1032,11 +1065,8 @@ static int qtnf_bringup_fw(struct qtnf_bus *bus)
static void qtnf_reclaim_tasklet_fn(unsigned long data)
{
struct qtnf_pcie_bus_priv *priv = (void *)data;
unsigned long flags;
spin_lock_irqsave(&priv->tx_lock, flags);
qtnf_pcie_data_tx_reclaim(priv);
spin_unlock_irqrestore(&priv->tx_lock, flags);
qtnf_en_txdone_irq(priv);
}
@ -1064,10 +1094,22 @@ static int qtnf_dbg_irq_stats(struct seq_file *s, void *data)
{
struct qtnf_bus *bus = dev_get_drvdata(s->private);
struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
u32 reg = readl(PCIE_HDP_INT_EN(priv->pcie_reg_base));
u32 status;
seq_printf(s, "pcie_irq_count(%u)\n", priv->pcie_irq_count);
seq_printf(s, "pcie_irq_tx_count(%u)\n", priv->pcie_irq_tx_count);
status = reg & PCIE_HDP_INT_TX_BITS;
seq_printf(s, "pcie_irq_tx_status(%s)\n",
(status == PCIE_HDP_INT_TX_BITS) ? "EN" : "DIS");
seq_printf(s, "pcie_irq_rx_count(%u)\n", priv->pcie_irq_rx_count);
status = reg & PCIE_HDP_INT_RX_BITS;
seq_printf(s, "pcie_irq_rx_status(%s)\n",
(status == PCIE_HDP_INT_RX_BITS) ? "EN" : "DIS");
seq_printf(s, "pcie_irq_uf_count(%u)\n", priv->pcie_irq_uf_count);
status = reg & PCIE_HDP_INT_HHBM_UF;
seq_printf(s, "pcie_irq_hhbm_uf_status(%s)\n",
(status == PCIE_HDP_INT_HHBM_UF) ? "EN" : "DIS");
return 0;
}
@ -1081,10 +1123,24 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data)
seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count);
seq_printf(s, "tx_reclaim_done(%u)\n", priv->tx_reclaim_done);
seq_printf(s, "tx_reclaim_req(%u)\n", priv->tx_reclaim_req);
seq_printf(s, "tx_bd_reclaim_start(%u)\n", priv->tx_bd_reclaim_start);
seq_printf(s, "tx_bd_index(%u)\n", priv->tx_bd_index);
seq_printf(s, "rx_bd_index(%u)\n", priv->rx_bd_index);
seq_printf(s, "tx_queue_len(%u)\n", priv->tx_queue_len);
seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index);
seq_printf(s, "tx_bd_p_index(%u)\n",
readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base))
& (priv->tx_bd_num - 1));
seq_printf(s, "tx_bd_w_index(%u)\n", priv->tx_bd_w_index);
seq_printf(s, "tx queue len(%u)\n",
CIRC_CNT(priv->tx_bd_w_index, priv->tx_bd_r_index,
priv->tx_bd_num));
seq_printf(s, "rx_bd_r_index(%u)\n", priv->rx_bd_r_index);
seq_printf(s, "rx_bd_p_index(%u)\n",
readl(PCIE_HDP_TX0DMA_CNT(priv->pcie_reg_base))
& (priv->rx_bd_num - 1));
seq_printf(s, "rx_bd_w_index(%u)\n", priv->rx_bd_w_index);
seq_printf(s, "rx alloc queue len(%u)\n",
CIRC_SPACE(priv->rx_bd_w_index, priv->rx_bd_r_index,
priv->rx_bd_num));
return 0;
}
@ -1131,7 +1187,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
init_completion(&bus->request_firmware_complete);
mutex_init(&bus->bus_lock);
spin_lock_init(&pcie_priv->irq_lock);
spin_lock_init(&pcie_priv->tx_lock);
spin_lock_init(&pcie_priv->tx_reclaim_lock);
/* init stats */
pcie_priv->tx_full_count = 0;
@ -1139,6 +1195,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pcie_priv->pcie_irq_count = 0;
pcie_priv->pcie_irq_rx_count = 0;
pcie_priv->pcie_irq_tx_count = 0;
pcie_priv->pcie_irq_uf_count = 0;
pcie_priv->tx_reclaim_done = 0;
pcie_priv->tx_reclaim_req = 0;

View File

@ -32,8 +32,8 @@ struct qtnf_pcie_bus_priv {
/* lock for irq configuration changes */
spinlock_t irq_lock;
/* lock for tx operations */
spinlock_t tx_lock;
/* lock for tx reclaim operations */
spinlock_t tx_reclaim_lock;
u8 msi_enabled;
int mps;
@ -66,13 +66,11 @@ struct qtnf_pcie_bus_priv {
void *bd_table_vaddr;
u32 bd_table_len;
u32 hw_txproc_wr_ptr;
u32 rx_bd_w_index;
u32 rx_bd_r_index;
u16 tx_bd_reclaim_start;
u16 tx_bd_index;
u32 tx_queue_len;
u16 rx_bd_index;
u32 tx_bd_w_index;
u32 tx_bd_r_index;
u32 pcie_irq_mask;
@ -80,6 +78,7 @@ struct qtnf_pcie_bus_priv {
u32 pcie_irq_count;
u32 pcie_irq_rx_count;
u32 pcie_irq_tx_count;
u32 pcie_irq_uf_count;
u32 tx_full_count;
u32 tx_done_count;
u32 tx_reclaim_done;

View File

@ -50,6 +50,7 @@
#define PCIE_HDP_INT_RX_BITS (0 \
| PCIE_HDP_INT_EP_TXDMA \
| PCIE_HDP_INT_EP_TXEMPTY \
| PCIE_HDP_INT_HHBM_UF \
)
#define PCIE_HDP_INT_TX_BITS (0 \

View File

@ -333,6 +333,7 @@
#define PCIE_HDP_INT_RX_LEN_ERR (BIT(2))
#define PCIE_HDP_INT_RX_HDR_LEN_ERR (BIT(3))
#define PCIE_HDP_INT_EP_TXDMA (BIT(12))
#define PCIE_HDP_INT_HHBM_UF (BIT(13))
#define PCIE_HDP_INT_EP_TXEMPTY (BIT(15))
#define PCIE_HDP_INT_IPC (BIT(29))

View File

@ -1911,7 +1911,7 @@ static const struct rt2x00_ops rt2500usb_ops = {
/*
* rt2500usb module information.
*/
static struct usb_device_id rt2500usb_device_table[] = {
static const struct usb_device_id rt2500usb_device_table[] = {
/* ASUS */
{ USB_DEVICE(0x0b05, 0x1706) },
{ USB_DEVICE(0x0b05, 0x1707) },

View File

@ -136,10 +136,19 @@ void rt2800mmio_fill_rxdone(struct queue_entry *entry,
*/
rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) {
rxdesc->flags |= RX_FLAG_DECRYPTED;
else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
} else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) {
/*
* In order to check the Michael Mic, the packet must have
* been decrypted. Mac80211 doesnt check the MMIC failure
* flag to initiate MMIC countermeasures if the decoded flag
* has not been set.
*/
rxdesc->flags |= RX_FLAG_DECRYPTED;
rxdesc->flags |= RX_FLAG_MMIC_ERROR;
}
}
if (rt2x00_get_field32(word, RXD_W3_MY_BSS))

View File

@ -697,11 +697,20 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
* stripped it from the frame. Signal this to mac80211.
*/
rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) {
rxdesc->flags |= RX_FLAG_DECRYPTED;
else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
} else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) {
/*
* In order to check the Michael Mic, the packet must have
* been decrypted. Mac80211 doesnt check the MMIC failure
* flag to initiate MMIC countermeasures if the decoded flag
* has not been set.
*/
rxdesc->flags |= RX_FLAG_DECRYPTED;
rxdesc->flags |= RX_FLAG_MMIC_ERROR;
}
}
if (rt2x00_get_field32(word, RXD_W0_MY_BSS))
@ -915,7 +924,7 @@ static const struct rt2x00_ops rt2800usb_ops = {
/*
* rt2800usb module information.
*/
static struct usb_device_id rt2800usb_device_table[] = {
static const struct usb_device_id rt2800usb_device_table[] = {
/* Abocom */
{ USB_DEVICE(0x07b8, 0x2870) },
{ USB_DEVICE(0x07b8, 0x2770) },

View File

@ -2408,7 +2408,7 @@ static const struct rt2x00_ops rt73usb_ops = {
/*
* rt73usb module information.
*/
static struct usb_device_id rt73usb_device_table[] = {
static const struct usb_device_id rt73usb_device_table[] = {
/* AboCom */
{ USB_DEVICE(0x07b8, 0xb21b) },
{ USB_DEVICE(0x07b8, 0xb21c) },

View File

@ -43,7 +43,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
MODULE_LICENSE("GPL");
static struct usb_device_id rtl8187_table[] = {
static const struct usb_device_id rtl8187_table[] = {
/* Asus */
{USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
/* Belkin */

View File

@ -6190,7 +6190,7 @@ static void rtl8xxxu_disconnect(struct usb_interface *interface)
ieee80211_free_hw(hw);
}
static struct usb_device_id dev_table[] = {
static const struct usb_device_id dev_table[] = {
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8724, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8723au_fops},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x1724, 0xff, 0xff, 0xff),

View File

@ -600,14 +600,8 @@ static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
0xffffff, 0x3);
break;
case 5:
if ((coex_sta->cck_ever_lock) && (coex_sta->scan_ap_num <= 5))
halbtc8723b1ant_coex_table(btcoexist, force_exec,
0x5a5a5a5a, 0x5aaa5a5a,
0xffffff, 0x3);
else
halbtc8723b1ant_coex_table(btcoexist, force_exec,
0x5a5a5a5a, 0x5aaa5a5a,
0xffffff, 0x3);
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
0x5aaa5a5a, 0xffffff, 0x3);
break;
case 6:
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,

Some files were not shown because too many files have changed in this diff Show More