mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-20 16:30:53 +00:00
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>
This commit is contained in:
commit
7619de85d0
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
1106
drivers/net/wireless/ath/ath10k/usb.c
Normal file
1106
drivers/net/wireless/ath/ath10k/usb.c
Normal file
File diff suppressed because it is too large
Load Diff
128
drivers/net/wireless/ath/ath10k/usb.h
Normal file
128
drivers/net/wireless/ath/ath10k/usb.h
Normal 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
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 */ }
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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_* */
|
||||
|
||||
/*
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
71
drivers/net/wireless/intel/iwlwifi/fw/api/led.h
Normal file
71
drivers/net/wireless/intel/iwlwifi/fw/api/led.h
Normal 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__ */
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_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(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_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(¬if_wait->notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(¬if_wait->notif_wait_lock);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_remove_notification);
|
||||
|
162
drivers/net/wireless/intel/iwlwifi/fw/nvm.c
Normal file
162
drivers/net/wireless/intel/iwlwifi/fw/nvm.c
Normal 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);
|
@ -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__ */
|
||||
|
@ -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++)
|
||||
|
@ -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__ */
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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__ */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 ?
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)},
|
||||
|
@ -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 */
|
||||
|
@ -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 },
|
||||
|
@ -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) },
|
||||
|
@ -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, ¶ms->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)
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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]))
|
||||
|
@ -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) },
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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) },
|
||||
|
@ -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))
|
||||
|
@ -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) },
|
||||
|
@ -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) },
|
||||
|
@ -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 */
|
||||
|
@ -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),
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user