wireless-drivers patches for 4.8
Major changes: ath10k * enable btcoex support without restarting firmware * enable ipq4019 support using AHB bus * add QCA9887 chipset support * retrieve calibration data from EEPROM, currently only for QCA9887 wil6210 * add pm_notify handling brcmfmac * add support for the PCIE devices 43525 and 43465 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJXaRfMAAoJEG4XJFUm622bxwEH/iZm3o752MM62fJyCOEtEN6R 8vL7kyehX81G9szQyQ7bMQ7y0diobeBGsu8e7zzV4Mt+cU0Z9g/ezfca6HfE6Hrh 0ubKl/tSzAhRcAoQiNyKOI36yt455r1Mnr8a18OYO79pnNcjf7kSd7pJG2BW0Hdx dRsSxzcg+E0w4z7mJ/cgM5aRzjXmXvAUjw9cIt36y3+ng1fQ+M782lkCtscMZY3Q e5bkLCaP5TG+O9niPTjzrAzMlBTGwopknuEZnwIGDkNkx1PeBzRATVGeSa9Zba6d g17kGbP7QT1GaCJF/FfWColaVpMBDhviovQANeoaUi804C4ZKNZAcJirZC3W2eM= =uYcn -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2016-06-21' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers patches for 4.8 Major changes: ath10k * enable btcoex support without restarting firmware * enable ipq4019 support using AHB bus * add QCA9887 chipset support * retrieve calibration data from EEPROM, currently only for QCA9887 wil6210 * add pm_notify handling brcmfmac * add support for the PCIE devices 43525 and 43465 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
dc14341ed6
|
@ -2578,12 +2578,11 @@ S: Supported
|
|||
F: drivers/net/ethernet/broadcom/tg3.*
|
||||
|
||||
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
||||
M: Brett Rudley <brudley@broadcom.com>
|
||||
M: Arend van Spriel <arend@broadcom.com>
|
||||
M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
M: Hante Meuleman <meuleman@broadcom.com>
|
||||
M: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
M: Franky Lin <franky.lin@broadcom.com>
|
||||
M: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: brcm80211-dev-list@broadcom.com
|
||||
L: brcm80211-dev-list.pdl@broadcom.com
|
||||
S: Supported
|
||||
F: drivers/net/wireless/broadcom/brcm80211/
|
||||
|
||||
|
|
|
@ -25,10 +25,9 @@
|
|||
#include "ahb.h"
|
||||
|
||||
static const struct of_device_id ath10k_ahb_of_match[] = {
|
||||
/* TODO: enable this entry once everything in place.
|
||||
* { .compatible = "qcom,ipq4019-wifi",
|
||||
* .data = (void *)ATH10K_HW_QCA4019 },
|
||||
*/
|
||||
{ .compatible = "qcom,ipq4019-wifi",
|
||||
.data = (void *)ATH10K_HW_QCA4019
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -476,6 +475,7 @@ static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg)
|
|||
|
||||
static int ath10k_ahb_request_irq_legacy(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
|
||||
int ret;
|
||||
|
||||
|
@ -487,6 +487,7 @@ static int ath10k_ahb_request_irq_legacy(struct ath10k *ar)
|
|||
ar_ahb->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_LEGACY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -918,8 +919,6 @@ int ath10k_ahb_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_ERR "AHB support is still work in progress\n");
|
||||
|
||||
ret = platform_driver_register(&ath10k_ahb_driver);
|
||||
if (ret)
|
||||
printk(KERN_ERR "failed to register ath10k ahb driver: %d\n",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "mac.h"
|
||||
|
@ -55,7 +56,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca988x hw2.0",
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.has_shifted_cc_wraparound = true,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
|
@ -68,6 +69,25 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = QCA9887_HW_1_0_VERSION,
|
||||
.dev_id = QCA9887_1_0_DEVICE_ID,
|
||||
.name = "qca9887 hw1.0",
|
||||
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
.cal_data_len = 2116,
|
||||
.fw = {
|
||||
.dir = QCA9887_HW_1_0_FW_DIR,
|
||||
.board = QCA9887_HW_1_0_BOARD_DATA_FILE,
|
||||
.board_size = QCA9887_BOARD_DATA_SZ,
|
||||
.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = QCA6174_HW_2_1_VERSION,
|
||||
.dev_id = QCA6164_2_1_DEVICE_ID,
|
||||
|
@ -148,6 +168,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.uart_pin = 7,
|
||||
.otp_exe_param = 0x00000700,
|
||||
.continuous_frag_desc = true,
|
||||
.cck_rate_map_rev2 = true,
|
||||
.channel_counters_freq_hz = 150000,
|
||||
.max_probe_resp_desc_thres = 24,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
|
@ -162,6 +183,29 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = QCA9984_HW_1_0_DEV_VERSION,
|
||||
.dev_id = QCA9984_1_0_DEVICE_ID,
|
||||
.name = "qca9984/qca9994 hw1.0",
|
||||
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.otp_exe_param = 0x00000700,
|
||||
.continuous_frag_desc = true,
|
||||
.cck_rate_map_rev2 = true,
|
||||
.channel_counters_freq_hz = 150000,
|
||||
.max_probe_resp_desc_thres = 24,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
.tx_chain_mask = 0xf,
|
||||
.rx_chain_mask = 0xf,
|
||||
.max_spatial_stream = 4,
|
||||
.cal_data_len = 12064,
|
||||
.fw = {
|
||||
.dir = QCA9984_HW_1_0_FW_DIR,
|
||||
.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
|
||||
.board_size = QCA99X0_BOARD_DATA_SZ,
|
||||
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = QCA9377_HW_1_0_DEV_VERSION,
|
||||
.dev_id = QCA9377_1_0_DEVICE_ID,
|
||||
|
@ -202,9 +246,10 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.name = "qca4019 hw1.0",
|
||||
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.has_shifted_cc_wraparound = true,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
.otp_exe_param = 0x0010000,
|
||||
.continuous_frag_desc = true,
|
||||
.cck_rate_map_rev2 = true,
|
||||
.channel_counters_freq_hz = 125000,
|
||||
.max_probe_resp_desc_thres = 24,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
|
@ -236,6 +281,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
|
|||
[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
|
||||
[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
|
||||
[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
|
||||
[ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
|
||||
};
|
||||
|
||||
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
|
||||
|
@ -531,6 +577,35 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_download_cal_eeprom(struct ath10k *ar)
|
||||
{
|
||||
size_t data_len;
|
||||
void *data = NULL;
|
||||
int ret;
|
||||
|
||||
ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);
|
||||
if (ret) {
|
||||
if (ret != -EOPNOTSUPP)
|
||||
ath10k_warn(ar, "failed to read calibration data from EEPROM: %d\n",
|
||||
ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = ath10k_download_board_data(ar, data, data_len);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to download calibration data from EEPROM: %d\n",
|
||||
ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
||||
{
|
||||
u32 result, address;
|
||||
|
@ -1293,7 +1368,17 @@ static int ath10k_download_cal_data(struct ath10k *ar)
|
|||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
"boot did not find DT entry, try OTP next: %d\n",
|
||||
"boot did not find DT entry, try target EEPROM next: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_download_cal_eeprom(ar);
|
||||
if (ret == 0) {
|
||||
ar->cal_mode = ATH10K_CAL_MODE_EEPROM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
"boot did not find target EEPROM entry, try OTP next: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_download_and_run_otp(ar);
|
||||
|
@ -1733,6 +1818,16 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|||
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
|
||||
val |= WMI_10_4_BSS_CHANNEL_INFO_64;
|
||||
|
||||
/* 10.4 firmware supports BT-Coex without reloading firmware
|
||||
* via pdev param. To support Bluetooth coexistence pdev param,
|
||||
* WMI_COEX_GPIO_SUPPORT of extended resource config should be
|
||||
* enabled always.
|
||||
*/
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
|
||||
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
|
||||
ar->running_fw->fw_file.fw_features))
|
||||
val |= WMI_10_4_COEX_GPIO_SUPPORT;
|
||||
|
||||
status = ath10k_mac_ext_resource_config(ar, val);
|
||||
if (status) {
|
||||
ath10k_err(ar,
|
||||
|
@ -2062,6 +2157,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
|
||||
switch (hw_rev) {
|
||||
case ATH10K_HW_QCA988X:
|
||||
case ATH10K_HW_QCA9887:
|
||||
ar->regs = &qca988x_regs;
|
||||
ar->hw_values = &qca988x_values;
|
||||
break;
|
||||
|
@ -2071,6 +2167,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
ar->hw_values = &qca6174_values;
|
||||
break;
|
||||
case ATH10K_HW_QCA99X0:
|
||||
case ATH10K_HW_QCA9984:
|
||||
ar->regs = &qca99x0_regs;
|
||||
ar->hw_values = &qca99x0_values;
|
||||
break;
|
||||
|
@ -2159,5 +2256,5 @@ void ath10k_core_destroy(struct ath10k *ar)
|
|||
EXPORT_SYMBOL(ath10k_core_destroy);
|
||||
|
||||
MODULE_AUTHOR("Qualcomm Atheros");
|
||||
MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
|
||||
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ac wireless LAN cards.");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
|
|
@ -535,6 +535,13 @@ enum ath10k_fw_features {
|
|||
*/
|
||||
ATH10K_FW_FEATURE_PEER_FLOW_CONTROL = 13,
|
||||
|
||||
/* Firmware supports BT-Coex without reloading firmware via pdev param.
|
||||
* To support Bluetooth coexistence pdev param, WMI_COEX_GPIO_SUPPORT of
|
||||
* extended resource config should be enabled always. This firmware IE
|
||||
* is used to configure WMI_COEX_GPIO_SUPPORT.
|
||||
*/
|
||||
ATH10K_FW_FEATURE_BTCOEX_PARAM = 14,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_FW_FEATURE_COUNT,
|
||||
};
|
||||
|
@ -571,6 +578,7 @@ enum ath10k_cal_mode {
|
|||
ATH10K_CAL_MODE_DT,
|
||||
ATH10K_PRE_CAL_MODE_FILE,
|
||||
ATH10K_PRE_CAL_MODE_DT,
|
||||
ATH10K_CAL_MODE_EEPROM,
|
||||
};
|
||||
|
||||
enum ath10k_crypt_mode {
|
||||
|
@ -593,6 +601,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
|
|||
return "pre-cal-file";
|
||||
case ATH10K_PRE_CAL_MODE_DT:
|
||||
return "pre-cal-dt";
|
||||
case ATH10K_CAL_MODE_EEPROM:
|
||||
return "eeprom";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
|
@ -703,12 +713,10 @@ struct ath10k {
|
|||
int uart_pin;
|
||||
u32 otp_exe_param;
|
||||
|
||||
/* This is true if given HW chip has a quirky Cycle Counter
|
||||
* wraparound which resets to 0x7fffffff instead of 0. All
|
||||
* other CC related counters (e.g. Rx Clear Count) are divided
|
||||
* by 2 so they never wraparound themselves.
|
||||
/* Type of hw cycle counter wraparound logic, for more info
|
||||
* refer enum ath10k_hw_cc_wraparound_type.
|
||||
*/
|
||||
bool has_shifted_cc_wraparound;
|
||||
enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
|
||||
|
||||
/* Some of chip expects fragment descriptor to be continuous
|
||||
* memory for any TX operation. Set continuous_frag_desc flag
|
||||
|
@ -716,6 +724,12 @@ struct ath10k {
|
|||
*/
|
||||
bool continuous_frag_desc;
|
||||
|
||||
/* CCK hardware rate table mapping for the newer chipsets
|
||||
* like QCA99X0, QCA4019 got revised. The CCK h/w rate values
|
||||
* are in a proper order with respect to the rate/preamble
|
||||
*/
|
||||
bool cck_rate_map_rev2;
|
||||
|
||||
u32 channel_counters_freq_hz;
|
||||
|
||||
/* Mgmt tx descriptors threshold for limiting probe response
|
||||
|
|
|
@ -609,25 +609,23 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
|
|||
char buf[32];
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
/* drop the possible '\n' from the end */
|
||||
if (buf[count - 1] == '\n')
|
||||
buf[count - 1] = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON &&
|
||||
ar->state != ATH10K_STATE_RESTARTED) {
|
||||
ret = -ENETDOWN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* drop the possible '\n' from the end */
|
||||
if (buf[count - 1] == '\n') {
|
||||
buf[count - 1] = 0;
|
||||
count--;
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "soft")) {
|
||||
ath10k_info(ar, "simulating soft firmware crash\n");
|
||||
ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
|
||||
|
@ -2127,6 +2125,7 @@ static ssize_t ath10k_write_btcoex(struct file *file,
|
|||
size_t buf_size;
|
||||
int ret;
|
||||
bool val;
|
||||
u32 pdev_param;
|
||||
|
||||
buf_size = min(count, (sizeof(buf) - 1));
|
||||
if (copy_from_user(buf, ubuf, buf_size))
|
||||
|
@ -2150,14 +2149,25 @@ static ssize_t ath10k_write_btcoex(struct file *file,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
pdev_param = ar->wmi.pdev_param->enable_btcoex;
|
||||
if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
|
||||
ar->running_fw->fw_file.fw_features)) {
|
||||
ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
|
||||
ret = count;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
ath10k_info(ar, "restarting firmware due to btcoex change");
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
}
|
||||
|
||||
if (val)
|
||||
set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
else
|
||||
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
|
||||
ath10k_info(ar, "restarting firmware due to btcoex change");
|
||||
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
ret = count;
|
||||
|
||||
exit:
|
||||
|
|
|
@ -87,6 +87,10 @@ struct ath10k_hif_ops {
|
|||
|
||||
int (*suspend)(struct ath10k *ar);
|
||||
int (*resume)(struct ath10k *ar);
|
||||
|
||||
/* fetch calibration data from target eeprom */
|
||||
int (*fetch_cal_eeprom)(struct ath10k *ar, void **data,
|
||||
size_t *data_len);
|
||||
};
|
||||
|
||||
static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
|
||||
|
@ -202,4 +206,14 @@ static inline void ath10k_hif_write32(struct ath10k *ar,
|
|||
ar->hif.ops->write32(ar, address, data);
|
||||
}
|
||||
|
||||
static inline int ath10k_hif_fetch_cal_eeprom(struct ath10k *ar,
|
||||
void **data,
|
||||
size_t *data_len)
|
||||
{
|
||||
if (!ar->hif.ops->fetch_cal_eeprom)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->hif.ops->fetch_cal_eeprom(ar, data, data_len);
|
||||
}
|
||||
|
||||
#endif /* _HIF_H_ */
|
||||
|
|
|
@ -485,10 +485,10 @@ struct htt_mgmt_tx_completion {
|
|||
__le32 status;
|
||||
} __packed;
|
||||
|
||||
#define HTT_RX_INDICATION_INFO0_EXT_TID_MASK (0x3F)
|
||||
#define HTT_RX_INDICATION_INFO0_EXT_TID_MASK (0x1F)
|
||||
#define HTT_RX_INDICATION_INFO0_EXT_TID_LSB (0)
|
||||
#define HTT_RX_INDICATION_INFO0_FLUSH_VALID (1 << 6)
|
||||
#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 7)
|
||||
#define HTT_RX_INDICATION_INFO0_FLUSH_VALID (1 << 5)
|
||||
#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 6)
|
||||
|
||||
#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_MASK 0x0000003F
|
||||
#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_LSB 0
|
||||
|
|
|
@ -748,7 +748,7 @@ ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd)
|
|||
if (WARN_ON_ONCE(!arvif))
|
||||
return NULL;
|
||||
|
||||
if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
|
||||
if (WARN_ON_ONCE(ath10k_mac_vif_chan(arvif->vif, &def)))
|
||||
return NULL;
|
||||
|
||||
return def.chan;
|
||||
|
@ -939,7 +939,8 @@ static void ath10k_process_rx(struct ath10k *ar,
|
|||
is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
"mcast" : "ucast",
|
||||
(__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
status->flag == 0 ? "legacy" : "",
|
||||
(status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) == 0 ?
|
||||
"legacy" : "",
|
||||
status->flag & RX_FLAG_HT ? "ht" : "",
|
||||
status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
|
@ -2182,34 +2183,6 @@ static void ath10k_htt_rx_tx_mode_switch_ind(struct ath10k *ar,
|
|||
ath10k_mac_tx_push_pending(ar);
|
||||
}
|
||||
|
||||
static inline enum nl80211_band phy_mode_to_band(u32 phy_mode)
|
||||
{
|
||||
enum nl80211_band band;
|
||||
|
||||
switch (phy_mode) {
|
||||
case MODE_11A:
|
||||
case MODE_11NA_HT20:
|
||||
case MODE_11NA_HT40:
|
||||
case MODE_11AC_VHT20:
|
||||
case MODE_11AC_VHT40:
|
||||
case MODE_11AC_VHT80:
|
||||
band = NL80211_BAND_5GHZ;
|
||||
break;
|
||||
case MODE_11G:
|
||||
case MODE_11B:
|
||||
case MODE_11GONLY:
|
||||
case MODE_11NG_HT20:
|
||||
case MODE_11NG_HT40:
|
||||
case MODE_11AC_VHT20_2G:
|
||||
case MODE_11AC_VHT40_2G:
|
||||
case MODE_11AC_VHT80_2G:
|
||||
default:
|
||||
band = NL80211_BAND_2GHZ;
|
||||
}
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
bool release;
|
||||
|
@ -2291,7 +2264,6 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
|||
ath10k_htt_tx_mgmt_dec_pending(htt);
|
||||
spin_unlock_bh(&htt->tx_lock);
|
||||
}
|
||||
ath10k_mac_tx_push_pending(ar);
|
||||
break;
|
||||
}
|
||||
case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
|
||||
|
@ -2442,8 +2414,6 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
|
|||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
ath10k_mac_tx_push_pending(ar);
|
||||
|
||||
num_mpdus = atomic_read(&htt->num_mpdus_ready);
|
||||
|
||||
while (num_mpdus) {
|
||||
|
|
|
@ -179,17 +179,35 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
|
|||
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
|
||||
{
|
||||
u32 cc_fix = 0;
|
||||
u32 rcc_fix = 0;
|
||||
enum ath10k_hw_cc_wraparound_type wraparound_type;
|
||||
|
||||
survey->filled |= SURVEY_INFO_TIME |
|
||||
SURVEY_INFO_TIME_BUSY;
|
||||
|
||||
if (ar->hw_params.has_shifted_cc_wraparound && cc < cc_prev) {
|
||||
cc_fix = 0x7fffffff;
|
||||
survey->filled &= ~SURVEY_INFO_TIME_BUSY;
|
||||
wraparound_type = ar->hw_params.cc_wraparound_type;
|
||||
|
||||
if (cc < cc_prev || rcc < rcc_prev) {
|
||||
switch (wraparound_type) {
|
||||
case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
|
||||
if (cc < cc_prev) {
|
||||
cc_fix = 0x7fffffff;
|
||||
survey->filled &= ~SURVEY_INFO_TIME_BUSY;
|
||||
}
|
||||
break;
|
||||
case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
|
||||
if (cc < cc_prev)
|
||||
cc_fix = 0x7fffffff;
|
||||
else
|
||||
rcc_fix = 0x7fffffff;
|
||||
break;
|
||||
case ATH10K_HW_CC_WRAP_DISABLED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cc -= cc_prev - cc_fix;
|
||||
rcc -= rcc_prev;
|
||||
rcc -= rcc_prev - rcc_fix;
|
||||
|
||||
survey->time = CCNT_TO_MSEC(ar, cc);
|
||||
survey->time_busy = CCNT_TO_MSEC(ar, rcc);
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
#define QCA6164_2_1_DEVICE_ID (0x0041)
|
||||
#define QCA6174_2_1_DEVICE_ID (0x003e)
|
||||
#define QCA99X0_2_0_DEVICE_ID (0x0040)
|
||||
#define QCA9984_1_0_DEVICE_ID (0x0046)
|
||||
#define QCA9377_1_0_DEVICE_ID (0x0042)
|
||||
#define QCA9887_1_0_DEVICE_ID (0x0050)
|
||||
|
||||
/* QCA988X 1.0 definitions (unsupported) */
|
||||
#define QCA988X_HW_1_0_CHIP_ID_REV 0x0
|
||||
|
@ -38,6 +40,13 @@
|
|||
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
/* QCA9887 1.0 definitions */
|
||||
#define QCA9887_HW_1_0_VERSION 0x4100016d
|
||||
#define QCA9887_HW_1_0_CHIP_ID_REV 0
|
||||
#define QCA9887_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9887/hw1.0"
|
||||
#define QCA9887_HW_1_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA9887_HW_1_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
/* QCA6174 target BMI version signatures */
|
||||
#define QCA6174_HW_1_0_VERSION 0x05000000
|
||||
#define QCA6174_HW_1_1_VERSION 0x05000001
|
||||
|
@ -91,6 +100,14 @@ enum qca9377_chip_id_rev {
|
|||
#define QCA99X0_HW_2_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA99X0_HW_2_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
/* QCA9984 1.0 defines */
|
||||
#define QCA9984_HW_1_0_DEV_VERSION 0x1000000
|
||||
#define QCA9984_HW_DEV_TYPE 0xa
|
||||
#define QCA9984_HW_1_0_CHIP_ID_REV 0x0
|
||||
#define QCA9984_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9984/hw1.0"
|
||||
#define QCA9984_HW_1_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA9984_HW_1_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
||||
/* QCA9377 1.0 definitions */
|
||||
#define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0"
|
||||
#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin"
|
||||
|
@ -193,8 +210,10 @@ enum ath10k_hw_rev {
|
|||
ATH10K_HW_QCA988X,
|
||||
ATH10K_HW_QCA6174,
|
||||
ATH10K_HW_QCA99X0,
|
||||
ATH10K_HW_QCA9984,
|
||||
ATH10K_HW_QCA9377,
|
||||
ATH10K_HW_QCA4019,
|
||||
ATH10K_HW_QCA9887,
|
||||
};
|
||||
|
||||
struct ath10k_hw_regs {
|
||||
|
@ -247,8 +266,10 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
|
|||
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev);
|
||||
|
||||
#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X)
|
||||
#define QCA_REV_9887(ar) ((ar)->hw_rev == ATH10K_HW_QCA9887)
|
||||
#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
|
||||
#define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0)
|
||||
#define QCA_REV_9984(ar) ((ar)->hw_rev == ATH10K_HW_QCA9984)
|
||||
#define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377)
|
||||
#define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019)
|
||||
|
||||
|
@ -315,11 +336,41 @@ enum ath10k_hw_rate_cck {
|
|||
ATH10K_HW_RATE_CCK_SP_2M,
|
||||
};
|
||||
|
||||
enum ath10k_hw_rate_rev2_cck {
|
||||
ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
|
||||
ATH10K_HW_RATE_REV2_CCK_LP_2M,
|
||||
ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
|
||||
ATH10K_HW_RATE_REV2_CCK_LP_11M,
|
||||
ATH10K_HW_RATE_REV2_CCK_SP_2M,
|
||||
ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
|
||||
ATH10K_HW_RATE_REV2_CCK_SP_11M,
|
||||
};
|
||||
|
||||
enum ath10k_hw_4addr_pad {
|
||||
ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
};
|
||||
|
||||
enum ath10k_hw_cc_wraparound_type {
|
||||
ATH10K_HW_CC_WRAP_DISABLED = 0,
|
||||
|
||||
/* This type is when the HW chip has a quirky Cycle Counter
|
||||
* wraparound which resets to 0x7fffffff instead of 0. All
|
||||
* other CC related counters (e.g. Rx Clear Count) are divided
|
||||
* by 2 so they never wraparound themselves.
|
||||
*/
|
||||
ATH10K_HW_CC_WRAP_SHIFTED_ALL = 1,
|
||||
|
||||
/* Each hw counter wrapsaround independently. When the
|
||||
* counter overflows the repestive counter is right shifted
|
||||
* by 1, i.e reset to 0x7fffffff, and other counters will be
|
||||
* running unaffected. In this type of wraparound, it should
|
||||
* be possible to report accurate Rx busy time unlike the
|
||||
* first type.
|
||||
*/
|
||||
ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
|
||||
};
|
||||
|
||||
/* Target specific defines for MAIN firmware */
|
||||
#define TARGET_NUM_VDEVS 8
|
||||
#define TARGET_NUM_PEER_AST 2
|
||||
|
@ -547,7 +598,10 @@ enum ath10k_hw_4addr_pad {
|
|||
#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001
|
||||
|
||||
#define WLAN_GPIO_PIN0_ADDRESS 0x00000028
|
||||
#define WLAN_GPIO_PIN0_CONFIG_LSB 11
|
||||
#define WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800
|
||||
#define WLAN_GPIO_PIN0_PAD_PULL_LSB 5
|
||||
#define WLAN_GPIO_PIN0_PAD_PULL_MASK 0x00000060
|
||||
#define WLAN_GPIO_PIN1_ADDRESS 0x0000002c
|
||||
#define WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800
|
||||
#define WLAN_GPIO_PIN10_ADDRESS 0x00000050
|
||||
|
@ -560,6 +614,8 @@ enum ath10k_hw_4addr_pad {
|
|||
#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0
|
||||
|
||||
#define SI_CONFIG_OFFSET 0x00000000
|
||||
#define SI_CONFIG_ERR_INT_LSB 19
|
||||
#define SI_CONFIG_ERR_INT_MASK 0x00080000
|
||||
#define SI_CONFIG_BIDIR_OD_DATA_LSB 18
|
||||
#define SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000
|
||||
#define SI_CONFIG_I2C_LSB 16
|
||||
|
@ -573,7 +629,9 @@ enum ath10k_hw_4addr_pad {
|
|||
#define SI_CONFIG_DIVIDER_LSB 0
|
||||
#define SI_CONFIG_DIVIDER_MASK 0x0000000f
|
||||
#define SI_CS_OFFSET 0x00000004
|
||||
#define SI_CS_DONE_ERR_LSB 10
|
||||
#define SI_CS_DONE_ERR_MASK 0x00000400
|
||||
#define SI_CS_DONE_INT_LSB 9
|
||||
#define SI_CS_DONE_INT_MASK 0x00000200
|
||||
#define SI_CS_START_LSB 8
|
||||
#define SI_CS_START_MASK 0x00000100
|
||||
|
@ -624,7 +682,10 @@ enum ath10k_hw_4addr_pad {
|
|||
#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS
|
||||
#define GPIO_PIN0_OFFSET WLAN_GPIO_PIN0_ADDRESS
|
||||
#define GPIO_PIN1_OFFSET WLAN_GPIO_PIN1_ADDRESS
|
||||
#define GPIO_PIN0_CONFIG_LSB WLAN_GPIO_PIN0_CONFIG_LSB
|
||||
#define GPIO_PIN0_CONFIG_MASK WLAN_GPIO_PIN0_CONFIG_MASK
|
||||
#define GPIO_PIN0_PAD_PULL_LSB WLAN_GPIO_PIN0_PAD_PULL_LSB
|
||||
#define GPIO_PIN0_PAD_PULL_MASK WLAN_GPIO_PIN0_PAD_PULL_MASK
|
||||
#define GPIO_PIN1_CONFIG_MASK WLAN_GPIO_PIN1_CONFIG_MASK
|
||||
#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS
|
||||
#define SCRATCH_BASE_ADDRESS SOC_CORE_BASE_ADDRESS
|
||||
|
@ -679,6 +740,18 @@ enum ath10k_hw_4addr_pad {
|
|||
#define WINDOW_READ_ADDR_ADDRESS MISSING
|
||||
#define WINDOW_WRITE_ADDR_ADDRESS MISSING
|
||||
|
||||
#define QCA9887_1_0_I2C_SDA_GPIO_PIN 5
|
||||
#define QCA9887_1_0_I2C_SDA_PIN_CONFIG 3
|
||||
#define QCA9887_1_0_SI_CLK_GPIO_PIN 17
|
||||
#define QCA9887_1_0_SI_CLK_PIN_CONFIG 3
|
||||
#define QCA9887_1_0_GPIO_ENABLE_W1TS_LOW_ADDRESS 0x00000010
|
||||
|
||||
#define QCA9887_EEPROM_SELECT_READ 0xa10000a0
|
||||
#define QCA9887_EEPROM_ADDR_HI_MASK 0x0000ff00
|
||||
#define QCA9887_EEPROM_ADDR_HI_LSB 8
|
||||
#define QCA9887_EEPROM_ADDR_LO_MASK 0x00ff0000
|
||||
#define QCA9887_EEPROM_ADDR_LO_LSB 16
|
||||
|
||||
#define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB)
|
||||
|
||||
#endif /* _HW_H_ */
|
||||
|
|
|
@ -62,6 +62,32 @@ static struct ieee80211_rate ath10k_rates[] = {
|
|||
{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
|
||||
};
|
||||
|
||||
static struct ieee80211_rate ath10k_rates_rev2[] = {
|
||||
{ .bitrate = 10,
|
||||
.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
|
||||
{ .bitrate = 20,
|
||||
.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
|
||||
.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
|
||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
|
||||
{ .bitrate = 55,
|
||||
.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
|
||||
.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
|
||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
|
||||
{ .bitrate = 110,
|
||||
.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
|
||||
.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
|
||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
|
||||
|
||||
{ .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
|
||||
{ .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
|
||||
{ .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
|
||||
{ .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
|
||||
{ .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
|
||||
{ .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
|
||||
{ .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
|
||||
{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
|
||||
};
|
||||
|
||||
#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
|
||||
|
||||
#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
|
||||
|
@ -70,6 +96,9 @@ static struct ieee80211_rate ath10k_rates[] = {
|
|||
#define ath10k_g_rates (ath10k_rates + 0)
|
||||
#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
|
||||
|
||||
#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
|
||||
#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
|
||||
|
||||
static bool ath10k_mac_bitrate_is_cck(int bitrate)
|
||||
{
|
||||
switch (bitrate) {
|
||||
|
@ -3781,6 +3810,9 @@ void ath10k_mac_tx_push_pending(struct ath10k *ar)
|
|||
int ret;
|
||||
int max;
|
||||
|
||||
if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&ar->txqs_lock);
|
||||
rcu_read_lock();
|
||||
|
||||
|
@ -4051,9 +4083,7 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
|
|||
list_add_tail(&artxq->list, &ar->txqs);
|
||||
spin_unlock_bh(&ar->txqs_lock);
|
||||
|
||||
if (ath10k_mac_tx_can_push(hw, txq))
|
||||
tasklet_schedule(&ar->htt.txrx_compl_task);
|
||||
|
||||
ath10k_mac_tx_push_pending(ar);
|
||||
ath10k_htt_tx_txq_update(hw, txq);
|
||||
}
|
||||
|
||||
|
@ -4467,6 +4497,19 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
|||
}
|
||||
}
|
||||
|
||||
param = ar->wmi.pdev_param->enable_btcoex;
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
|
||||
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
|
||||
ar->running_fw->fw_file.fw_features)) {
|
||||
ret = ath10k_wmi_pdev_set_param(ar, param, 0);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to set btcoex param: %d\n", ret);
|
||||
goto err_core_stop;
|
||||
}
|
||||
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
}
|
||||
|
||||
ar->num_started_vdevs = 0;
|
||||
ath10k_regd_update(ar);
|
||||
|
||||
|
@ -7695,8 +7738,14 @@ int ath10k_mac_register(struct ath10k *ar)
|
|||
band = &ar->mac.sbands[NL80211_BAND_2GHZ];
|
||||
band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
|
||||
band->channels = channels;
|
||||
band->n_bitrates = ath10k_g_rates_size;
|
||||
band->bitrates = ath10k_g_rates;
|
||||
|
||||
if (ar->hw_params.cck_rate_map_rev2) {
|
||||
band->n_bitrates = ath10k_g_rates_rev2_size;
|
||||
band->bitrates = ath10k_g_rates_rev2;
|
||||
} else {
|
||||
band->n_bitrates = ath10k_g_rates_size;
|
||||
band->bitrates = ath10k_g_rates;
|
||||
}
|
||||
|
||||
ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,9 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
|
|||
{ PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
|
||||
{ PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
|
||||
{ PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */
|
||||
{ PCI_VDEVICE(ATHEROS, QCA9984_1_0_DEVICE_ID) }, /* PCI-E QCA9984 V1 */
|
||||
{ PCI_VDEVICE(ATHEROS, QCA9377_1_0_DEVICE_ID) }, /* PCI-E QCA9377 V1 */
|
||||
{ PCI_VDEVICE(ATHEROS, QCA9887_1_0_DEVICE_ID) }, /* PCI-E QCA9887 */
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -81,8 +83,12 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
|
|||
|
||||
{ QCA99X0_2_0_DEVICE_ID, QCA99X0_HW_2_0_CHIP_ID_REV },
|
||||
|
||||
{ QCA9984_1_0_DEVICE_ID, QCA9984_HW_1_0_CHIP_ID_REV },
|
||||
|
||||
{ QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV },
|
||||
{ QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV },
|
||||
|
||||
{ QCA9887_1_0_DEVICE_ID, QCA9887_HW_1_0_CHIP_ID_REV },
|
||||
};
|
||||
|
||||
static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
|
||||
|
@ -837,6 +843,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
|
|||
|
||||
switch (ar->hw_rev) {
|
||||
case ATH10K_HW_QCA988X:
|
||||
case ATH10K_HW_QCA9887:
|
||||
case ATH10K_HW_QCA6174:
|
||||
case ATH10K_HW_QCA9377:
|
||||
val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
|
@ -844,6 +851,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
|
|||
0x7ff) << 21;
|
||||
break;
|
||||
case ATH10K_HW_QCA99X0:
|
||||
case ATH10K_HW_QCA9984:
|
||||
case ATH10K_HW_QCA4019:
|
||||
val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
|
||||
break;
|
||||
|
@ -864,7 +872,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int ret = 0;
|
||||
u32 *buf;
|
||||
unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
|
||||
unsigned int completed_nbytes, alloc_nbytes, remaining_bytes;
|
||||
struct ath10k_ce_pipe *ce_diag;
|
||||
/* Host buffer address in CE space */
|
||||
u32 ce_data;
|
||||
|
@ -882,9 +890,10 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|||
* 1) 4-byte alignment
|
||||
* 2) Buffer in DMA-able space
|
||||
*/
|
||||
orig_nbytes = nbytes;
|
||||
alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT);
|
||||
|
||||
data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
|
||||
orig_nbytes,
|
||||
alloc_nbytes,
|
||||
&ce_data_base,
|
||||
GFP_ATOMIC);
|
||||
|
||||
|
@ -892,9 +901,9 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
memset(data_buf, 0, orig_nbytes);
|
||||
memset(data_buf, 0, alloc_nbytes);
|
||||
|
||||
remaining_bytes = orig_nbytes;
|
||||
remaining_bytes = nbytes;
|
||||
ce_data = ce_data_base;
|
||||
while (remaining_bytes) {
|
||||
nbytes = min_t(unsigned int, remaining_bytes,
|
||||
|
@ -954,19 +963,22 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|||
}
|
||||
|
||||
remaining_bytes -= nbytes;
|
||||
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read diag value at 0x%x: %d\n",
|
||||
address, ret);
|
||||
break;
|
||||
}
|
||||
memcpy(data, data_buf, nbytes);
|
||||
|
||||
address += nbytes;
|
||||
ce_data += nbytes;
|
||||
data += nbytes;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ret == 0)
|
||||
memcpy(data, data_buf, orig_nbytes);
|
||||
else
|
||||
ath10k_warn(ar, "failed to read diag value at 0x%x: %d\n",
|
||||
address, ret);
|
||||
|
||||
if (data_buf)
|
||||
dma_free_coherent(ar->dev, orig_nbytes, data_buf,
|
||||
dma_free_coherent(ar->dev, alloc_nbytes, data_buf,
|
||||
ce_data_base);
|
||||
|
||||
spin_unlock_bh(&ar_pci->ce_lock);
|
||||
|
@ -1560,6 +1572,7 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
|
|||
|
||||
switch (ar->hw_rev) {
|
||||
case ATH10K_HW_QCA988X:
|
||||
case ATH10K_HW_QCA9887:
|
||||
case ATH10K_HW_QCA6174:
|
||||
case ATH10K_HW_QCA9377:
|
||||
val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
|
@ -1569,6 +1582,7 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
|
|||
CORE_CTRL_ADDRESS, val);
|
||||
break;
|
||||
case ATH10K_HW_QCA99X0:
|
||||
case ATH10K_HW_QCA9984:
|
||||
case ATH10K_HW_QCA4019:
|
||||
/* TODO: Find appropriate register configuration for QCA99X0
|
||||
* to mask irq/MSI.
|
||||
|
@ -1583,6 +1597,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
|
|||
|
||||
switch (ar->hw_rev) {
|
||||
case ATH10K_HW_QCA988X:
|
||||
case ATH10K_HW_QCA9887:
|
||||
case ATH10K_HW_QCA6174:
|
||||
case ATH10K_HW_QCA9377:
|
||||
val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
|
@ -1592,6 +1607,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
|
|||
CORE_CTRL_ADDRESS, val);
|
||||
break;
|
||||
case ATH10K_HW_QCA99X0:
|
||||
case ATH10K_HW_QCA9984:
|
||||
case ATH10K_HW_QCA4019:
|
||||
/* TODO: Find appropriate register configuration for QCA99X0
|
||||
* to unmask irq/MSI.
|
||||
|
@ -1932,6 +1948,8 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
|
|||
switch (ar_pci->pdev->device) {
|
||||
case QCA988X_2_0_DEVICE_ID:
|
||||
case QCA99X0_2_0_DEVICE_ID:
|
||||
case QCA9984_1_0_DEVICE_ID:
|
||||
case QCA9887_1_0_DEVICE_ID:
|
||||
return 1;
|
||||
case QCA6164_2_1_DEVICE_ID:
|
||||
case QCA6174_2_1_DEVICE_ID:
|
||||
|
@ -2293,16 +2311,20 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_pci_qca99x0_soft_chip_reset(struct ath10k *ar)
|
||||
{
|
||||
ath10k_pci_irq_disable(ar);
|
||||
return ath10k_pci_qca99x0_chip_reset(ar);
|
||||
}
|
||||
|
||||
static int ath10k_pci_safe_chip_reset(struct ath10k *ar)
|
||||
{
|
||||
if (QCA_REV_988X(ar) || QCA_REV_6174(ar)) {
|
||||
return ath10k_pci_warm_reset(ar);
|
||||
} else if (QCA_REV_99X0(ar)) {
|
||||
ath10k_pci_irq_disable(ar);
|
||||
return ath10k_pci_qca99x0_chip_reset(ar);
|
||||
} else {
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (!ar_pci->pci_soft_reset)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return ar_pci->pci_soft_reset(ar);
|
||||
}
|
||||
|
||||
static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar)
|
||||
|
@ -2437,16 +2459,12 @@ static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar)
|
|||
|
||||
static int ath10k_pci_chip_reset(struct ath10k *ar)
|
||||
{
|
||||
if (QCA_REV_988X(ar))
|
||||
return ath10k_pci_qca988x_chip_reset(ar);
|
||||
else if (QCA_REV_6174(ar))
|
||||
return ath10k_pci_qca6174_chip_reset(ar);
|
||||
else if (QCA_REV_9377(ar))
|
||||
return ath10k_pci_qca6174_chip_reset(ar);
|
||||
else if (QCA_REV_99X0(ar))
|
||||
return ath10k_pci_qca99x0_chip_reset(ar);
|
||||
else
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (WARN_ON(!ar_pci->pci_hard_reset))
|
||||
return -ENOTSUPP;
|
||||
|
||||
return ar_pci->pci_hard_reset(ar);
|
||||
}
|
||||
|
||||
static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
||||
|
@ -2559,6 +2577,144 @@ static int ath10k_pci_hif_resume(struct ath10k *ar)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool ath10k_pci_validate_cal(void *data, size_t size)
|
||||
{
|
||||
__le16 *cal_words = data;
|
||||
u16 checksum = 0;
|
||||
size_t i;
|
||||
|
||||
if (size % 2 != 0)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < size / 2; i++)
|
||||
checksum ^= le16_to_cpu(cal_words[i]);
|
||||
|
||||
return checksum == 0xffff;
|
||||
}
|
||||
|
||||
static void ath10k_pci_enable_eeprom(struct ath10k *ar)
|
||||
{
|
||||
/* Enable SI clock */
|
||||
ath10k_pci_soc_write32(ar, CLOCK_CONTROL_OFFSET, 0x0);
|
||||
|
||||
/* Configure GPIOs for I2C operation */
|
||||
ath10k_pci_write32(ar,
|
||||
GPIO_BASE_ADDRESS + GPIO_PIN0_OFFSET +
|
||||
4 * QCA9887_1_0_I2C_SDA_GPIO_PIN,
|
||||
SM(QCA9887_1_0_I2C_SDA_PIN_CONFIG,
|
||||
GPIO_PIN0_CONFIG) |
|
||||
SM(1, GPIO_PIN0_PAD_PULL));
|
||||
|
||||
ath10k_pci_write32(ar,
|
||||
GPIO_BASE_ADDRESS + GPIO_PIN0_OFFSET +
|
||||
4 * QCA9887_1_0_SI_CLK_GPIO_PIN,
|
||||
SM(QCA9887_1_0_SI_CLK_PIN_CONFIG, GPIO_PIN0_CONFIG) |
|
||||
SM(1, GPIO_PIN0_PAD_PULL));
|
||||
|
||||
ath10k_pci_write32(ar,
|
||||
GPIO_BASE_ADDRESS +
|
||||
QCA9887_1_0_GPIO_ENABLE_W1TS_LOW_ADDRESS,
|
||||
1u << QCA9887_1_0_SI_CLK_GPIO_PIN);
|
||||
|
||||
/* In Swift ASIC - EEPROM clock will be (110MHz/512) = 214KHz */
|
||||
ath10k_pci_write32(ar,
|
||||
SI_BASE_ADDRESS + SI_CONFIG_OFFSET,
|
||||
SM(1, SI_CONFIG_ERR_INT) |
|
||||
SM(1, SI_CONFIG_BIDIR_OD_DATA) |
|
||||
SM(1, SI_CONFIG_I2C) |
|
||||
SM(1, SI_CONFIG_POS_SAMPLE) |
|
||||
SM(1, SI_CONFIG_INACTIVE_DATA) |
|
||||
SM(1, SI_CONFIG_INACTIVE_CLK) |
|
||||
SM(8, SI_CONFIG_DIVIDER));
|
||||
}
|
||||
|
||||
static int ath10k_pci_read_eeprom(struct ath10k *ar, u16 addr, u8 *out)
|
||||
{
|
||||
u32 reg;
|
||||
int wait_limit;
|
||||
|
||||
/* set device select byte and for the read operation */
|
||||
reg = QCA9887_EEPROM_SELECT_READ |
|
||||
SM(addr, QCA9887_EEPROM_ADDR_LO) |
|
||||
SM(addr >> 8, QCA9887_EEPROM_ADDR_HI);
|
||||
ath10k_pci_write32(ar, SI_BASE_ADDRESS + SI_TX_DATA0_OFFSET, reg);
|
||||
|
||||
/* write transmit data, transfer length, and START bit */
|
||||
ath10k_pci_write32(ar, SI_BASE_ADDRESS + SI_CS_OFFSET,
|
||||
SM(1, SI_CS_START) | SM(1, SI_CS_RX_CNT) |
|
||||
SM(4, SI_CS_TX_CNT));
|
||||
|
||||
/* wait max 1 sec */
|
||||
wait_limit = 100000;
|
||||
|
||||
/* wait for SI_CS_DONE_INT */
|
||||
do {
|
||||
reg = ath10k_pci_read32(ar, SI_BASE_ADDRESS + SI_CS_OFFSET);
|
||||
if (MS(reg, SI_CS_DONE_INT))
|
||||
break;
|
||||
|
||||
wait_limit--;
|
||||
udelay(10);
|
||||
} while (wait_limit > 0);
|
||||
|
||||
if (!MS(reg, SI_CS_DONE_INT)) {
|
||||
ath10k_err(ar, "timeout while reading device EEPROM at %04x\n",
|
||||
addr);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* clear SI_CS_DONE_INT */
|
||||
ath10k_pci_write32(ar, SI_BASE_ADDRESS + SI_CS_OFFSET, reg);
|
||||
|
||||
if (MS(reg, SI_CS_DONE_ERR)) {
|
||||
ath10k_err(ar, "failed to read device EEPROM at %04x\n", addr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* extract receive data */
|
||||
reg = ath10k_pci_read32(ar, SI_BASE_ADDRESS + SI_RX_DATA0_OFFSET);
|
||||
*out = reg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_pci_hif_fetch_cal_eeprom(struct ath10k *ar, void **data,
|
||||
size_t *data_len)
|
||||
{
|
||||
u8 *caldata = NULL;
|
||||
size_t calsize, i;
|
||||
int ret;
|
||||
|
||||
if (!QCA_REV_9887(ar))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
calsize = ar->hw_params.cal_data_len;
|
||||
caldata = kmalloc(calsize, GFP_KERNEL);
|
||||
if (!caldata)
|
||||
return -ENOMEM;
|
||||
|
||||
ath10k_pci_enable_eeprom(ar);
|
||||
|
||||
for (i = 0; i < calsize; i++) {
|
||||
ret = ath10k_pci_read_eeprom(ar, i, &caldata[i]);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (!ath10k_pci_validate_cal(caldata, calsize))
|
||||
goto err_free;
|
||||
|
||||
*data = caldata;
|
||||
*data_len = calsize;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
kfree(data);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
|
||||
.tx_sg = ath10k_pci_hif_tx_sg,
|
||||
.diag_read = ath10k_pci_hif_diag_read,
|
||||
|
@ -2578,6 +2734,7 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
|
|||
.suspend = ath10k_pci_hif_suspend,
|
||||
.resume = ath10k_pci_hif_resume,
|
||||
#endif
|
||||
.fetch_cal_eeprom = ath10k_pci_hif_fetch_cal_eeprom,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2976,24 +3133,47 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
enum ath10k_hw_rev hw_rev;
|
||||
u32 chip_id;
|
||||
bool pci_ps;
|
||||
int (*pci_soft_reset)(struct ath10k *ar);
|
||||
int (*pci_hard_reset)(struct ath10k *ar);
|
||||
|
||||
switch (pci_dev->device) {
|
||||
case QCA988X_2_0_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA988X;
|
||||
pci_ps = false;
|
||||
pci_soft_reset = ath10k_pci_warm_reset;
|
||||
pci_hard_reset = ath10k_pci_qca988x_chip_reset;
|
||||
break;
|
||||
case QCA9887_1_0_DEVICE_ID:
|
||||
dev_warn(&pdev->dev, "QCA9887 support is still experimental, there are likely bugs. You have been warned.\n");
|
||||
hw_rev = ATH10K_HW_QCA9887;
|
||||
pci_ps = false;
|
||||
pci_soft_reset = ath10k_pci_warm_reset;
|
||||
pci_hard_reset = ath10k_pci_qca988x_chip_reset;
|
||||
break;
|
||||
case QCA6164_2_1_DEVICE_ID:
|
||||
case QCA6174_2_1_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA6174;
|
||||
pci_ps = true;
|
||||
pci_soft_reset = ath10k_pci_warm_reset;
|
||||
pci_hard_reset = ath10k_pci_qca6174_chip_reset;
|
||||
break;
|
||||
case QCA99X0_2_0_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA99X0;
|
||||
pci_ps = false;
|
||||
pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
|
||||
pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
|
||||
break;
|
||||
case QCA9984_1_0_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA9984;
|
||||
pci_ps = false;
|
||||
pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
|
||||
pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
|
||||
break;
|
||||
case QCA9377_1_0_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA9377;
|
||||
pci_ps = true;
|
||||
pci_soft_reset = NULL;
|
||||
pci_hard_reset = ath10k_pci_qca6174_chip_reset;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
|
@ -3018,6 +3198,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
ar->dev_id = pci_dev->device;
|
||||
ar_pci->pci_ps = pci_ps;
|
||||
ar_pci->bus_ops = &ath10k_pci_bus_ops;
|
||||
ar_pci->pci_soft_reset = pci_soft_reset;
|
||||
ar_pci->pci_hard_reset = pci_hard_reset;
|
||||
|
||||
ar->id.vendor = pdev->vendor;
|
||||
ar->id.device = pdev->device;
|
||||
|
@ -3169,7 +3351,7 @@ static void __exit ath10k_pci_exit(void)
|
|||
module_exit(ath10k_pci_exit);
|
||||
|
||||
MODULE_AUTHOR("Qualcomm Atheros");
|
||||
MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
|
||||
MODULE_DESCRIPTION("Driver support for Qualcomm Atheros 802.11ac WLAN PCIe/AHB devices");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
/* QCA988x 2.0 firmware files */
|
||||
|
@ -3180,6 +3362,11 @@ MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API5_FILE);
|
|||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
|
||||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_BOARD_API2_FILE);
|
||||
|
||||
/* QCA9887 1.0 firmware files */
|
||||
MODULE_FIRMWARE(QCA9887_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE);
|
||||
MODULE_FIRMWARE(QCA9887_HW_1_0_FW_DIR "/" QCA9887_HW_1_0_BOARD_DATA_FILE);
|
||||
MODULE_FIRMWARE(QCA9887_HW_1_0_FW_DIR "/" ATH10K_BOARD_API2_FILE);
|
||||
|
||||
/* QCA6174 2.1 firmware files */
|
||||
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API4_FILE);
|
||||
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API5_FILE);
|
||||
|
|
|
@ -234,6 +234,12 @@ struct ath10k_pci {
|
|||
|
||||
const struct ath10k_bus_ops *bus_ops;
|
||||
|
||||
/* Chip specific pci reset routine used to do a safe reset */
|
||||
int (*pci_soft_reset)(struct ath10k *ar);
|
||||
|
||||
/* Chip specific pci full reset function */
|
||||
int (*pci_hard_reset)(struct ath10k *ar);
|
||||
|
||||
/* Keep this entry in the last, memory for struct ath10k_ahb is
|
||||
* allocated (ahb support enabled case) in the continuation of
|
||||
* this struct.
|
||||
|
|
|
@ -656,26 +656,6 @@ struct rx_msdu_end {
|
|||
* Reserved: HW should fill with zero. FW should ignore.
|
||||
*/
|
||||
|
||||
#define RX_PPDU_START_SIG_RATE_SELECT_OFDM 0
|
||||
#define RX_PPDU_START_SIG_RATE_SELECT_CCK 1
|
||||
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_48 0
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_24 1
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_12 2
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_6 3
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_54 4
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_36 5
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_18 6
|
||||
#define RX_PPDU_START_SIG_RATE_OFDM_9 7
|
||||
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_LP_11 0
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_LP_5_5 1
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_LP_2 2
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_LP_1 3
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_SP_11 4
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_SP_5_5 5
|
||||
#define RX_PPDU_START_SIG_RATE_CCK_SP_2 6
|
||||
|
||||
#define HTT_RX_PPDU_START_PREAMBLE_LEGACY 0x04
|
||||
#define HTT_RX_PPDU_START_PREAMBLE_HT 0x08
|
||||
#define HTT_RX_PPDU_START_PREAMBLE_HT_WITH_TXBF 0x09
|
||||
|
@ -711,25 +691,6 @@ struct rx_msdu_end {
|
|||
/* No idea what this flag means. It seems to be always set in rate. */
|
||||
#define RX_PPDU_START_RATE_FLAG BIT(3)
|
||||
|
||||
enum rx_ppdu_start_rate {
|
||||
RX_PPDU_START_RATE_OFDM_48M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_48M,
|
||||
RX_PPDU_START_RATE_OFDM_24M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_24M,
|
||||
RX_PPDU_START_RATE_OFDM_12M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_12M,
|
||||
RX_PPDU_START_RATE_OFDM_6M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_6M,
|
||||
RX_PPDU_START_RATE_OFDM_54M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_54M,
|
||||
RX_PPDU_START_RATE_OFDM_36M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_36M,
|
||||
RX_PPDU_START_RATE_OFDM_18M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_18M,
|
||||
RX_PPDU_START_RATE_OFDM_9M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_9M,
|
||||
|
||||
RX_PPDU_START_RATE_CCK_LP_11M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_11M,
|
||||
RX_PPDU_START_RATE_CCK_LP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_5_5M,
|
||||
RX_PPDU_START_RATE_CCK_LP_2M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_2M,
|
||||
RX_PPDU_START_RATE_CCK_LP_1M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_1M,
|
||||
RX_PPDU_START_RATE_CCK_SP_11M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_11M,
|
||||
RX_PPDU_START_RATE_CCK_SP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_5_5M,
|
||||
RX_PPDU_START_RATE_CCK_SP_2M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_2M,
|
||||
};
|
||||
|
||||
struct rx_ppdu_start {
|
||||
struct {
|
||||
u8 pri20_mhz;
|
||||
|
@ -994,7 +955,41 @@ struct rx_pkt_end {
|
|||
__le32 info0; /* %RX_PKT_END_INFO0_ */
|
||||
__le32 phy_timestamp_1;
|
||||
__le32 phy_timestamp_2;
|
||||
__le32 rx_location_info; /* %RX_LOCATION_INFO_ */
|
||||
} __packed;
|
||||
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_MASK 0x00003fff
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_LSB 0
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_VHT_MASK 0x1fff8000
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_VHT_LSB 15
|
||||
#define RX_LOCATION_INFO0_RTT_STRONGEST_CHAIN_MASK 0xc0000000
|
||||
#define RX_LOCATION_INFO0_RTT_STRONGEST_CHAIN_LSB 30
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_STATUS BIT(14)
|
||||
#define RX_LOCATION_INFO0_RTT_FAC_VHT_STATUS BIT(29)
|
||||
|
||||
#define RX_LOCATION_INFO1_RTT_PREAMBLE_TYPE_MASK 0x0000000c
|
||||
#define RX_LOCATION_INFO1_RTT_PREAMBLE_TYPE_LSB 2
|
||||
#define RX_LOCATION_INFO1_PKT_BW_MASK 0x00000030
|
||||
#define RX_LOCATION_INFO1_PKT_BW_LSB 4
|
||||
#define RX_LOCATION_INFO1_SKIP_P_SKIP_BTCF_MASK 0x0000ff00
|
||||
#define RX_LOCATION_INFO1_SKIP_P_SKIP_BTCF_LSB 8
|
||||
#define RX_LOCATION_INFO1_RTT_MSC_RATE_MASK 0x000f0000
|
||||
#define RX_LOCATION_INFO1_RTT_MSC_RATE_LSB 16
|
||||
#define RX_LOCATION_INFO1_RTT_PBD_LEG_BW_MASK 0x00300000
|
||||
#define RX_LOCATION_INFO1_RTT_PBD_LEG_BW_LSB 20
|
||||
#define RX_LOCATION_INFO1_TIMING_BACKOFF_MASK 0x07c00000
|
||||
#define RX_LOCATION_INFO1_TIMING_BACKOFF_LSB 22
|
||||
#define RX_LOCATION_INFO1_RTT_TX_FRAME_PHASE_MASK 0x18000000
|
||||
#define RX_LOCATION_INFO1_RTT_TX_FRAME_PHASE_LSB 27
|
||||
#define RX_LOCATION_INFO1_RTT_CFR_STATUS BIT(0)
|
||||
#define RX_LOCATION_INFO1_RTT_CIR_STATUS BIT(1)
|
||||
#define RX_LOCATION_INFO1_RTT_GI_TYPE BIT(7)
|
||||
#define RX_LOCATION_INFO1_RTT_MAC_PHY_PHASE BIT(29)
|
||||
#define RX_LOCATION_INFO1_RTT_TX_DATA_START_X_PHASE BIT(30)
|
||||
#define RX_LOCATION_INFO1_RX_LOCATION_VALID BIT(31)
|
||||
|
||||
struct rx_location_info {
|
||||
__le32 rx_location_info0; /* %RX_LOCATION_INFO0_ */
|
||||
__le32 rx_location_info1; /* %RX_LOCATION_INFO1_ */
|
||||
} __packed;
|
||||
|
||||
enum rx_phy_ppdu_end_info0 {
|
||||
|
@ -1067,6 +1062,17 @@ struct rx_phy_ppdu_end {
|
|||
|
||||
struct rx_ppdu_end_qca99x0 {
|
||||
struct rx_pkt_end rx_pkt_end;
|
||||
__le32 rx_location_info; /* %RX_LOCATION_INFO_ */
|
||||
struct rx_phy_ppdu_end rx_phy_ppdu_end;
|
||||
__le32 rx_timing_offset; /* %RX_PPDU_END_RX_TIMING_OFFSET_ */
|
||||
__le32 rx_info; /* %RX_PPDU_END_RX_INFO_ */
|
||||
__le16 bb_length;
|
||||
__le16 info1; /* %RX_PPDU_END_INFO1_ */
|
||||
} __packed;
|
||||
|
||||
struct rx_ppdu_end_qca9984 {
|
||||
struct rx_pkt_end rx_pkt_end;
|
||||
struct rx_location_info rx_location_info;
|
||||
struct rx_phy_ppdu_end rx_phy_ppdu_end;
|
||||
__le32 rx_timing_offset; /* %RX_PPDU_END_RX_TIMING_OFFSET_ */
|
||||
__le32 rx_info; /* %RX_PPDU_END_RX_INFO_ */
|
||||
|
@ -1080,6 +1086,7 @@ struct rx_ppdu_end {
|
|||
struct rx_ppdu_end_qca988x qca988x;
|
||||
struct rx_ppdu_end_qca6174 qca6174;
|
||||
struct rx_ppdu_end_qca99x0 qca99x0;
|
||||
struct rx_ppdu_end_qca9984 qca9984;
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
|
|
|
@ -447,6 +447,9 @@ Fw Mode/SubMode Mask
|
|||
#define QCA988X_BOARD_DATA_SZ 7168
|
||||
#define QCA988X_BOARD_EXT_DATA_SZ 0
|
||||
|
||||
#define QCA9887_BOARD_DATA_SZ 7168
|
||||
#define QCA9887_BOARD_EXT_DATA_SZ 0
|
||||
|
||||
#define QCA6174_BOARD_DATA_SZ 8192
|
||||
#define QCA6174_BOARD_EXT_DATA_SZ 0
|
||||
|
||||
|
|
|
@ -117,6 +117,9 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|||
|
||||
ieee80211_tx_status(htt->ar->hw, msdu);
|
||||
/* we do not own the msdu anymore */
|
||||
|
||||
ath10k_mac_tx_push_pending(ar);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1104,6 +1104,7 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
|
|||
.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
|
||||
|
@ -1199,6 +1200,7 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
|
|||
.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = {
|
||||
|
@ -1294,6 +1296,7 @@ static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = {
|
|||
.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* firmware 10.2 specific mappings */
|
||||
|
@ -1550,6 +1553,7 @@ static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
|
|||
.wapi_mbssid_offset = WMI_10_4_PDEV_PARAM_WAPI_MBSSID_OFFSET,
|
||||
.arp_srcaddr = WMI_10_4_PDEV_PARAM_ARP_SRCADDR,
|
||||
.arp_dstaddr = WMI_10_4_PDEV_PARAM_ARP_DSTADDR,
|
||||
.enable_btcoex = WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_peer_flags_map = {
|
||||
|
|
|
@ -3447,6 +3447,7 @@ struct wmi_pdev_param_map {
|
|||
u32 wapi_mbssid_offset;
|
||||
u32 arp_srcaddr;
|
||||
u32 arp_dstaddr;
|
||||
u32 enable_btcoex;
|
||||
};
|
||||
|
||||
#define WMI_PDEV_PARAM_UNSUPPORTED 0
|
||||
|
@ -3760,6 +3761,9 @@ enum wmi_10_4_pdev_param {
|
|||
WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCH,
|
||||
WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR,
|
||||
WMI_10_4_PDEV_PARAM_CUST_TXPOWER_SCALE,
|
||||
WMI_10_4_PDEV_PARAM_ATF_DYNAMIC_ENABLE,
|
||||
WMI_10_4_PDEV_PARAM_ATF_SSID_GROUP_POLICY,
|
||||
WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX,
|
||||
};
|
||||
|
||||
struct wmi_pdev_set_param_cmd {
|
||||
|
|
|
@ -219,8 +219,8 @@ ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
|
|||
sifs = AR5K_INIT_SIFS_QUARTER_RATE;
|
||||
break;
|
||||
case AR5K_BWMODE_DEFAULT:
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
|
||||
default:
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
|
||||
if (channel->band == NL80211_BAND_5GHZ)
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_A;
|
||||
break;
|
||||
|
|
|
@ -148,7 +148,7 @@ enum ath6kl_fw_capability {
|
|||
/* ratetable is the 2 stream version (max MCS15) */
|
||||
ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
||||
|
||||
/* firmare doesn't support IP checksumming */
|
||||
/* firmware doesn't support IP checksumming */
|
||||
ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
||||
|
||||
/* this needs to be last */
|
||||
|
|
|
@ -2544,8 +2544,7 @@ int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
|
|||
s32 nominal_phy = 0;
|
||||
int ret;
|
||||
|
||||
if (!((params->user_pri < 8) &&
|
||||
(params->user_pri <= 0x7) &&
|
||||
if (!((params->user_pri <= 0x7) &&
|
||||
(up_to_ac[params->user_pri & 0x7] == params->traffic_class) &&
|
||||
(params->traffic_direc == UPLINK_TRAFFIC ||
|
||||
params->traffic_direc == DNLINK_TRAFFIC ||
|
||||
|
|
|
@ -3202,8 +3202,7 @@ static int ar9300_compress_decision(struct ath_hw *ah,
|
|||
it, length);
|
||||
break;
|
||||
case _CompressBlock:
|
||||
if (reference == 0) {
|
||||
} else {
|
||||
if (reference != 0) {
|
||||
eep = ar9003_eeprom_struct_find_by_id(reference);
|
||||
if (eep == NULL) {
|
||||
ath_dbg(common, EEPROM,
|
||||
|
|
|
@ -132,7 +132,6 @@ static int ath9k_tx99_init(struct ath_softc *sc)
|
|||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
atomic_set(&ah->intr_ref_cnt, -1);
|
||||
ath_drain_all_txq(sc);
|
||||
ath_stoprecv(sc);
|
||||
|
||||
|
@ -266,7 +265,7 @@ static const struct file_operations fops_tx99_power = {
|
|||
|
||||
void ath9k_tx99_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah))
|
||||
if (!AR_SREV_9280_20_OR_LATER(sc->sc_ah))
|
||||
return;
|
||||
|
||||
debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
|
||||
|
|
|
@ -5,12 +5,10 @@ config CARL9170
|
|||
select FW_LOADER
|
||||
select CRC32
|
||||
help
|
||||
This is another driver for the Atheros "otus" 802.11n USB devices.
|
||||
This is the mainline driver for the Atheros "otus" 802.11n USB devices.
|
||||
|
||||
This driver provides more features than the original,
|
||||
but it needs a special firmware (carl9170-1.fw) to do that.
|
||||
|
||||
The firmware can be downloaded from our wiki here:
|
||||
It needs a special firmware (carl9170-1.fw), which can be downloaded
|
||||
from our wiki here:
|
||||
<http://wireless.kernel.org/en/users/Drivers/carl9170>
|
||||
|
||||
If you choose to build a module, it'll be called carl9170.
|
||||
|
|
|
@ -378,6 +378,10 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
|||
/* social scan on P2P_DEVICE is handled as p2p search */
|
||||
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
|
||||
wil_p2p_is_social_scan(request)) {
|
||||
if (!wil->p2p.p2p_dev_started) {
|
||||
wil_err(wil, "P2P search requested on stopped P2P device\n");
|
||||
return -EIO;
|
||||
}
|
||||
wil->scan_request = request;
|
||||
wil->radio_wdev = wdev;
|
||||
rc = wil_p2p_search(wil, request);
|
||||
|
@ -1351,6 +1355,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
|
|||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
wil->p2p.p2p_dev_started = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1358,8 +1363,19 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
|
|||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
u8 started;
|
||||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
mutex_lock(&wil->mutex);
|
||||
started = wil_p2p_stop_discovery(wil);
|
||||
if (started && wil->scan_request) {
|
||||
cfg80211_scan_done(wil->scan_request, 1);
|
||||
wil->scan_request = NULL;
|
||||
wil->radio_wdev = wil->wdev;
|
||||
}
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
||||
wil->p2p.p2p_dev_started = 0;
|
||||
}
|
||||
|
||||
static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2013,2016 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,34 +19,31 @@
|
|||
|
||||
void __wil_err(struct wil6210_priv *wil, const char *fmt, ...)
|
||||
{
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
netdev_err(ndev, "%pV", &vaf);
|
||||
netdev_err(wil_to_ndev(wil), "%pV", &vaf);
|
||||
trace_wil6210_log_err(&vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...)
|
||||
{
|
||||
if (net_ratelimit()) {
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
netdev_err(ndev, "%pV", &vaf);
|
||||
trace_wil6210_log_err(&vaf);
|
||||
va_end(args);
|
||||
}
|
||||
if (!net_ratelimit())
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
netdev_err(wil_to_ndev(wil), "%pV", &vaf);
|
||||
trace_wil6210_log_err(&vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...)
|
||||
|
@ -67,27 +64,24 @@ void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...)
|
|||
|
||||
void __wil_info(struct wil6210_priv *wil, const char *fmt, ...)
|
||||
{
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
netdev_info(ndev, "%pV", &vaf);
|
||||
netdev_info(wil_to_ndev(wil), "%pV", &vaf);
|
||||
trace_wil6210_log_info(&vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
trace_wil6210_log_dbg(&vaf);
|
||||
va_end(args);
|
||||
|
|
|
@ -114,8 +114,10 @@ int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
|
|||
u8 channel = P2P_DMG_SOCIAL_CHANNEL;
|
||||
int rc;
|
||||
|
||||
if (chan)
|
||||
channel = chan->hw_value;
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
channel = chan->hw_value;
|
||||
|
||||
wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -18,13 +18,20 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/suspend.h>
|
||||
#include "wil6210.h"
|
||||
|
||||
static bool use_msi = true;
|
||||
module_param(use_msi, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true");
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int wil6210_pm_notify(struct notifier_block *notify_block,
|
||||
unsigned long mode, void *unused);
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static
|
||||
void wil_set_capabilities(struct wil6210_priv *wil)
|
||||
{
|
||||
|
@ -238,6 +245,18 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto bus_disable;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
wil->pm_notify.notifier_call = wil6210_pm_notify;
|
||||
rc = register_pm_notifier(&wil->pm_notify);
|
||||
if (rc)
|
||||
/* Do not fail the driver initialization, as suspend can
|
||||
* be prevented in a later phase if needed
|
||||
*/
|
||||
wil_err(wil, "register_pm_notifier failed: %d\n", rc);
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
wil6210_debugfs_init(wil);
|
||||
|
||||
|
||||
|
@ -267,6 +286,12 @@ static void wil_pcie_remove(struct pci_dev *pdev)
|
|||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
unregister_pm_notifier(&wil->pm_notify);
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
wil6210_debugfs_remove(wil);
|
||||
wil_if_remove(wil);
|
||||
wil_if_pcie_disable(wil);
|
||||
|
@ -335,6 +360,45 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int wil6210_pm_notify(struct notifier_block *notify_block,
|
||||
unsigned long mode, void *unused)
|
||||
{
|
||||
struct wil6210_priv *wil = container_of(
|
||||
notify_block, struct wil6210_priv, pm_notify);
|
||||
int rc = 0;
|
||||
enum wil_platform_event evt;
|
||||
|
||||
wil_dbg_pm(wil, "%s: mode (%ld)\n", __func__, mode);
|
||||
|
||||
switch (mode) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
case PM_RESTORE_PREPARE:
|
||||
rc = wil_can_suspend(wil, false);
|
||||
if (rc)
|
||||
break;
|
||||
evt = WIL_PLATFORM_EVT_PRE_SUSPEND;
|
||||
if (wil->platform_ops.notify)
|
||||
rc = wil->platform_ops.notify(wil->platform_handle,
|
||||
evt);
|
||||
break;
|
||||
case PM_POST_SUSPEND:
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_RESTORE:
|
||||
evt = WIL_PLATFORM_EVT_POST_SUSPEND;
|
||||
if (wil->platform_ops.notify)
|
||||
rc = wil->platform_ops.notify(wil->platform_handle,
|
||||
evt);
|
||||
break;
|
||||
default:
|
||||
wil_dbg_pm(wil, "unhandled notify mode %ld\n", mode);
|
||||
break;
|
||||
}
|
||||
|
||||
wil_dbg_pm(wil, "notification mode %ld: rc (%d)\n", mode, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil6210_pm_suspend(struct device *dev)
|
||||
{
|
||||
return wil6210_suspend(dev, false);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014,2016 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -24,10 +24,32 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
|
|||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
|
||||
if (!netif_running(wil_to_ndev(wil))) {
|
||||
/* can always sleep when down */
|
||||
wil_dbg_pm(wil, "Interface is down\n");
|
||||
goto out;
|
||||
}
|
||||
if (test_bit(wil_status_resetting, wil->status)) {
|
||||
wil_dbg_pm(wil, "Delay suspend when resetting\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
if (wil->recovery_state != fw_recovery_idle) {
|
||||
wil_dbg_pm(wil, "Delay suspend during recovery\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* interface is running */
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
if (test_bit(wil_status_fwconnecting, wil->status)) {
|
||||
wil_dbg_pm(wil, "Delay suspend when connecting\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
/* AP-like interface - can't suspend */
|
||||
default:
|
||||
|
@ -36,6 +58,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
|
|||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
wil_dbg_pm(wil, "%s(%s) => %s (%d)\n", __func__,
|
||||
is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);
|
||||
|
||||
|
|
|
@ -184,6 +184,13 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
|
|||
&vring->va[vring->swtail].tx;
|
||||
|
||||
ctx = &vring->ctx[vring->swtail];
|
||||
if (!ctx) {
|
||||
wil_dbg_txrx(wil,
|
||||
"ctx(%d) was already completed\n",
|
||||
vring->swtail);
|
||||
vring->swtail = wil_vring_next_tail(vring);
|
||||
continue;
|
||||
}
|
||||
*d = *_d;
|
||||
wil_txdesc_unmap(dev, d, ctx);
|
||||
if (ctx->skb)
|
||||
|
@ -544,6 +551,12 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure all writes to descriptors (shared memory) are done before
|
||||
* committing them to HW
|
||||
*/
|
||||
wmb();
|
||||
|
||||
wil_w(wil, v->hwtail, v->swtail);
|
||||
|
||||
return rc;
|
||||
|
@ -969,6 +982,13 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
|
|||
txdata->dot1x_open = false;
|
||||
txdata->enabled = 0; /* no Tx can be in progress or start anew */
|
||||
spin_unlock_bh(&txdata->lock);
|
||||
/* napi_synchronize waits for completion of the current NAPI but will
|
||||
* not prevent the next NAPI run.
|
||||
* Add a memory barrier to guarantee that txdata->enabled is zeroed
|
||||
* before napi_synchronize so that the next scheduled NAPI will not
|
||||
* handle this vring
|
||||
*/
|
||||
wmb();
|
||||
/* make sure NAPI won't touch this vring */
|
||||
if (test_bit(wil_status_napi_en, wil->status))
|
||||
napi_synchronize(&wil->napi_tx);
|
||||
|
@ -1551,6 +1571,13 @@ static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring,
|
|||
vring_index, used, used + descs_used);
|
||||
}
|
||||
|
||||
/* Make sure to advance the head only after descriptor update is done.
|
||||
* This will prevent a race condition where the completion thread
|
||||
* will see the DU bit set from previous run and will handle the
|
||||
* skb before it was completed.
|
||||
*/
|
||||
wmb();
|
||||
|
||||
/* advance swhead */
|
||||
wil_vring_advance_head(vring, descs_used);
|
||||
wil_dbg_txrx(wil, "TSO: Tx swhead %d -> %d\n", swhead, vring->swhead);
|
||||
|
@ -1567,7 +1594,7 @@ mem_error:
|
|||
while (descs_used > 0) {
|
||||
struct wil_ctx *ctx;
|
||||
|
||||
i = (swhead + descs_used) % vring->size;
|
||||
i = (swhead + descs_used - 1) % vring->size;
|
||||
d = (struct vring_tx_desc *)&vring->va[i].tx;
|
||||
_desc = &vring->va[i].tx;
|
||||
*d = *_desc;
|
||||
|
@ -1691,6 +1718,13 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
|
|||
vring_index, used, used + nr_frags + 1);
|
||||
}
|
||||
|
||||
/* Make sure to advance the head only after descriptor update is done.
|
||||
* This will prevent a race condition where the completion thread
|
||||
* will see the DU bit set from previous run and will handle the
|
||||
* skb before it was completed.
|
||||
*/
|
||||
wmb();
|
||||
|
||||
/* advance swhead */
|
||||
wil_vring_advance_head(vring, nr_frags + 1);
|
||||
wil_dbg_txrx(wil, "Tx[%2d] swhead %d -> %d\n", vring_index, swhead,
|
||||
|
@ -1914,6 +1948,12 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
|
|||
wil_consume_skb(skb, d->dma.error == 0);
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
/* Make sure the ctx is zeroed before updating the tail
|
||||
* to prevent a case where wil_tx_vring will see
|
||||
* this descriptor as used and handle it before ctx zero
|
||||
* is completed.
|
||||
*/
|
||||
wmb();
|
||||
/* There is no need to touch HW descriptor:
|
||||
* - ststus bit TX_DMA_STATUS_DU is set by design,
|
||||
* so hardware will not try to process this desc.,
|
||||
|
|
|
@ -458,6 +458,7 @@ struct wil_tid_crypto_rx {
|
|||
struct wil_p2p_info {
|
||||
struct ieee80211_channel listen_chan;
|
||||
u8 discovery_started;
|
||||
u8 p2p_dev_started;
|
||||
u64 cookie;
|
||||
struct timer_list discovery_timer; /* listen/search duration */
|
||||
struct work_struct discovery_expired_work; /* listen/search expire */
|
||||
|
@ -662,6 +663,11 @@ struct wil6210_priv {
|
|||
/* High Access Latency Policy voting */
|
||||
struct wil_halp halp;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
struct notifier_block pm_notify;
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
#endif /* CONFIG_PM */
|
||||
};
|
||||
|
||||
#define wil_to_wiphy(i) (i->wdev->wiphy)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -23,6 +23,8 @@ enum wil_platform_event {
|
|||
WIL_PLATFORM_EVT_FW_CRASH = 0,
|
||||
WIL_PLATFORM_EVT_PRE_RESET = 1,
|
||||
WIL_PLATFORM_EVT_FW_RDY = 2,
|
||||
WIL_PLATFORM_EVT_PRE_SUSPEND = 3,
|
||||
WIL_PLATFORM_EVT_POST_SUSPEND = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
b43-y += main.o
|
||||
b43-y += bus.o
|
||||
b43-$(CONFIG_B43_PHY_G) += phy_a.o phy_g.o tables.o lo.o wa.o
|
||||
b43-$(CONFIG_B43_PHY_G) += phy_g.o tables.o lo.o wa.o
|
||||
b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
|
||||
b43-$(CONFIG_B43_PHY_N) += radio_2055.o
|
||||
b43-$(CONFIG_B43_PHY_N) += radio_2056.o
|
||||
|
|
|
@ -222,7 +222,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
|
|||
sprom[2] = dev->dev->bus_sprom->gpio2;
|
||||
sprom[3] = dev->dev->bus_sprom->gpio3;
|
||||
|
||||
if (sprom[led_index] == 0xFF) {
|
||||
if ((sprom[0] & sprom[1] & sprom[2] & sprom[3]) == 0xff) {
|
||||
/* There is no LED information in the SPROM
|
||||
* for this LED. Hardcode it here. */
|
||||
*activelow = false;
|
||||
|
@ -250,7 +250,11 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
*behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
|
||||
/* keep LED disabled if no mapping is defined */
|
||||
if (sprom[led_index] == 0xff)
|
||||
*behaviour = B43_LED_OFF;
|
||||
else
|
||||
*behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
|
||||
*activelow = !!(sprom[led_index] & B43_LED_ACTIVELOW);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3180,7 +3180,6 @@ static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
|
|||
static void b43_rate_memory_init(struct b43_wldev *dev)
|
||||
{
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
|
@ -3194,8 +3193,6 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
|
|||
b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1);
|
||||
b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1);
|
||||
b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1);
|
||||
if (dev->phy.type == B43_PHYTYPE_A)
|
||||
break;
|
||||
/* fallthrough */
|
||||
case B43_PHYTYPE_B:
|
||||
b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0);
|
||||
|
@ -4604,14 +4601,6 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
|||
if (radio_manuf != 0x17F /* Broadcom */)
|
||||
unsupported = 1;
|
||||
switch (phy_type) {
|
||||
case B43_PHYTYPE_A:
|
||||
if (radio_id != 0x2060)
|
||||
unsupported = 1;
|
||||
if (radio_rev != 1)
|
||||
unsupported = 1;
|
||||
if (radio_manuf != 0x17F)
|
||||
unsupported = 1;
|
||||
break;
|
||||
case B43_PHYTYPE_B:
|
||||
if ((radio_id & 0xFFF0) != 0x2050)
|
||||
unsupported = 1;
|
||||
|
@ -4766,10 +4755,7 @@ static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
|
|||
u16 pu_delay;
|
||||
|
||||
/* The time value is in microseconds. */
|
||||
if (dev->phy.type == B43_PHYTYPE_A)
|
||||
pu_delay = 3700;
|
||||
else
|
||||
pu_delay = 1050;
|
||||
pu_delay = 1050;
|
||||
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle)
|
||||
pu_delay = 500;
|
||||
if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
|
||||
|
@ -4784,14 +4770,10 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
|
|||
u16 pretbtt;
|
||||
|
||||
/* The time value is in microseconds. */
|
||||
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) {
|
||||
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
|
||||
pretbtt = 2;
|
||||
} else {
|
||||
if (dev->phy.type == B43_PHYTYPE_A)
|
||||
pretbtt = 120;
|
||||
else
|
||||
pretbtt = 250;
|
||||
}
|
||||
else
|
||||
pretbtt = 250;
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt);
|
||||
b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt);
|
||||
}
|
||||
|
@ -5380,10 +5362,6 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy,
|
|||
|
||||
/* As a fallback, try to guess using PHY type */
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
*have_2ghz_phy = false;
|
||||
*have_5ghz_phy = true;
|
||||
return;
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
|
@ -5455,7 +5433,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
|||
/* We don't support 5 GHz on some PHYs yet */
|
||||
if (have_5ghz_phy) {
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_LP:
|
||||
case B43_PHYTYPE_HT:
|
||||
|
|
|
@ -1,595 +0,0 @@
|
|||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11a PHY driver
|
||||
|
||||
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
|
||||
Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
|
||||
Copyright (c) 2005-2008 Michael Buesch <m@bues.ch>
|
||||
Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
|
||||
Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "b43.h"
|
||||
#include "phy_a.h"
|
||||
#include "phy_common.h"
|
||||
#include "wa.h"
|
||||
#include "tables.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
/* Get the freq, as it has to be written to the device. */
|
||||
static inline u16 channel2freq_a(u8 channel)
|
||||
{
|
||||
B43_WARN_ON(channel > 200);
|
||||
|
||||
return (5000 + 5 * channel);
|
||||
}
|
||||
|
||||
static inline u16 freq_r3A_value(u16 frequency)
|
||||
{
|
||||
u16 value;
|
||||
|
||||
if (frequency < 5091)
|
||||
value = 0x0040;
|
||||
else if (frequency < 5321)
|
||||
value = 0x0000;
|
||||
else if (frequency < 5806)
|
||||
value = 0x0080;
|
||||
else
|
||||
value = 0x0040;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This function converts a TSSI value to dBm in Q5.2 */
|
||||
static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_a *aphy = phy->a;
|
||||
s8 dbm = 0;
|
||||
s32 tmp;
|
||||
|
||||
tmp = (aphy->tgt_idle_tssi - aphy->cur_idle_tssi + tssi);
|
||||
tmp += 0x80;
|
||||
tmp = clamp_val(tmp, 0x00, 0xFF);
|
||||
dbm = aphy->tssi2dbm[tmp];
|
||||
//TODO: There's a FIXME on the specs
|
||||
|
||||
return dbm;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void b43_radio_set_tx_iq(struct b43_wldev *dev)
|
||||
{
|
||||
static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
|
||||
static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
|
||||
u16 tmp = b43_radio_read16(dev, 0x001E);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (j = 0; j < 5; j++) {
|
||||
if (tmp == (data_high[i] << 4 | data_low[j])) {
|
||||
b43_phy_write(dev, 0x0069,
|
||||
(i - j) << 8 | 0x00C0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
|
||||
{
|
||||
u16 freq, r8, tmp;
|
||||
|
||||
freq = channel2freq_a(channel);
|
||||
|
||||
r8 = b43_radio_read16(dev, 0x0008);
|
||||
b43_write16(dev, 0x03F0, freq);
|
||||
b43_radio_write16(dev, 0x0008, r8);
|
||||
|
||||
//TODO: write max channel TX power? to Radio 0x2D
|
||||
tmp = b43_radio_read16(dev, 0x002E);
|
||||
tmp &= 0x0080;
|
||||
//TODO: OR tmp with the Power out estimation for this channel?
|
||||
b43_radio_write16(dev, 0x002E, tmp);
|
||||
|
||||
if (freq >= 4920 && freq <= 5500) {
|
||||
/*
|
||||
* r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
|
||||
* = (freq * 0.025862069
|
||||
*/
|
||||
r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
|
||||
}
|
||||
b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
|
||||
b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
|
||||
b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
|
||||
b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
|
||||
b43_radio_write16(dev, 0x002A, (r8 << 4));
|
||||
b43_radio_write16(dev, 0x002B, (r8 << 4));
|
||||
b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
|
||||
b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
|
||||
b43_radio_write16(dev, 0x0035, 0x00AA);
|
||||
b43_radio_write16(dev, 0x0036, 0x0085);
|
||||
b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
|
||||
b43_radio_mask(dev, 0x003D, 0x00FF);
|
||||
b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
|
||||
b43_radio_mask(dev, 0x0035, 0xFFEF);
|
||||
b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
|
||||
b43_radio_set_tx_iq(dev);
|
||||
//TODO: TSSI2dbm workaround
|
||||
//FIXME b43_phy_xmitpower(dev);
|
||||
}
|
||||
|
||||
static void b43_radio_init2060(struct b43_wldev *dev)
|
||||
{
|
||||
b43_radio_write16(dev, 0x0004, 0x00C0);
|
||||
b43_radio_write16(dev, 0x0005, 0x0008);
|
||||
b43_radio_write16(dev, 0x0009, 0x0040);
|
||||
b43_radio_write16(dev, 0x0005, 0x00AA);
|
||||
b43_radio_write16(dev, 0x0032, 0x008F);
|
||||
b43_radio_write16(dev, 0x0006, 0x008F);
|
||||
b43_radio_write16(dev, 0x0034, 0x008F);
|
||||
b43_radio_write16(dev, 0x002C, 0x0007);
|
||||
b43_radio_write16(dev, 0x0082, 0x0080);
|
||||
b43_radio_write16(dev, 0x0080, 0x0000);
|
||||
b43_radio_write16(dev, 0x003F, 0x00DA);
|
||||
b43_radio_mask(dev, 0x0005, ~0x0008);
|
||||
b43_radio_mask(dev, 0x0081, ~0x0010);
|
||||
b43_radio_mask(dev, 0x0081, ~0x0020);
|
||||
b43_radio_mask(dev, 0x0081, ~0x0020);
|
||||
msleep(1); /* delay 400usec */
|
||||
|
||||
b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
|
||||
msleep(1); /* delay 400usec */
|
||||
|
||||
b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
|
||||
b43_radio_mask(dev, 0x0085, ~0x0010);
|
||||
b43_radio_mask(dev, 0x0005, ~0x0008);
|
||||
b43_radio_mask(dev, 0x0081, ~0x0040);
|
||||
b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
|
||||
b43_radio_write16(dev, 0x0005,
|
||||
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
|
||||
b43_phy_write(dev, 0x0063, 0xDDC6);
|
||||
b43_phy_write(dev, 0x0069, 0x07BE);
|
||||
b43_phy_write(dev, 0x006A, 0x0000);
|
||||
|
||||
aphy_channel_switch(dev, dev->phy.ops->get_default_chan(dev));
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->phy.rev < 3) {
|
||||
if (enable)
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, 0xFFF8);
|
||||
}
|
||||
else
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
|
||||
}
|
||||
} else {
|
||||
if (enable)
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, 0x0820);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_phy_ww(struct b43_wldev *dev)
|
||||
{
|
||||
u16 b, curr_s, best_s = 0xFFFF;
|
||||
int i;
|
||||
|
||||
b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
|
||||
b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
|
||||
b43_radio_set(dev, 0x0009, 0x0080);
|
||||
b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
|
||||
b43_wa_initgains(dev);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
|
||||
b = b43_phy_read(dev, B43_PHY_PWRDOWN);
|
||||
b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
|
||||
b43_radio_set(dev, 0x0004, 0x0004);
|
||||
for (i = 0x10; i <= 0x20; i++) {
|
||||
b43_radio_write16(dev, 0x0013, i);
|
||||
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
|
||||
if (!curr_s) {
|
||||
best_s = 0x0000;
|
||||
break;
|
||||
} else if (curr_s >= 0x0080)
|
||||
curr_s = 0x0100 - curr_s;
|
||||
if (curr_s < best_s)
|
||||
best_s = curr_s;
|
||||
}
|
||||
b43_phy_write(dev, B43_PHY_PWRDOWN, b);
|
||||
b43_radio_mask(dev, 0x0004, 0xFFFB);
|
||||
b43_radio_write16(dev, 0x0013, best_s);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
|
||||
for (i = 0; i < 6; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
|
||||
b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
|
||||
}
|
||||
|
||||
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void b43_phy_inita(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
/* This lowlevel A-PHY init is also called from G-PHY init.
|
||||
* So we must not access phy->a, if called from G-PHY code.
|
||||
*/
|
||||
B43_WARN_ON((phy->type != B43_PHYTYPE_A) &&
|
||||
(phy->type != B43_PHYTYPE_G));
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (phy->rev >= 6) {
|
||||
if (phy->type == B43_PHYTYPE_A)
|
||||
b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
|
||||
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
|
||||
b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
|
||||
else
|
||||
b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
|
||||
}
|
||||
|
||||
b43_wa_all(dev);
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
if (phy->gmode && (phy->rev < 3))
|
||||
b43_phy_set(dev, 0x0034, 0x0001);
|
||||
b43_phy_rssiagc(dev, 0);
|
||||
|
||||
b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
|
||||
|
||||
b43_radio_init2060(dev);
|
||||
|
||||
if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
((dev->dev->board_type == SSB_BOARD_BU4306) ||
|
||||
(dev->dev->board_type == SSB_BOARD_BU4309))) {
|
||||
; //TODO: A PHY LO
|
||||
}
|
||||
|
||||
if (phy->rev >= 3)
|
||||
b43_phy_ww(dev);
|
||||
|
||||
hardware_pctl_init_aphy(dev);
|
||||
|
||||
//TODO: radar detection
|
||||
}
|
||||
|
||||
if ((phy->type == B43_PHYTYPE_G) &&
|
||||
(dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) {
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise the TSSI->dBm lookup table */
|
||||
static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_a *aphy = phy->a;
|
||||
s16 pab0, pab1, pab2;
|
||||
|
||||
pab0 = (s16) (dev->dev->bus_sprom->pa1b0);
|
||||
pab1 = (s16) (dev->dev->bus_sprom->pa1b1);
|
||||
pab2 = (s16) (dev->dev->bus_sprom->pa1b2);
|
||||
|
||||
if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
|
||||
pab0 != -1 && pab1 != -1 && pab2 != -1) {
|
||||
/* The pabX values are set in SPROM. Use them. */
|
||||
if ((s8) dev->dev->bus_sprom->itssi_a != 0 &&
|
||||
(s8) dev->dev->bus_sprom->itssi_a != -1)
|
||||
aphy->tgt_idle_tssi =
|
||||
(s8) (dev->dev->bus_sprom->itssi_a);
|
||||
else
|
||||
aphy->tgt_idle_tssi = 62;
|
||||
aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
|
||||
pab1, pab2);
|
||||
if (!aphy->tssi2dbm)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* pabX values not set in SPROM,
|
||||
* but APHY needs a generated table. */
|
||||
aphy->tssi2dbm = NULL;
|
||||
b43err(dev->wl, "Could not generate tssi2dBm "
|
||||
"table (wrong SPROM info)!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b43_aphy_op_allocate(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_a *aphy;
|
||||
int err;
|
||||
|
||||
aphy = kzalloc(sizeof(*aphy), GFP_KERNEL);
|
||||
if (!aphy)
|
||||
return -ENOMEM;
|
||||
dev->phy.a = aphy;
|
||||
|
||||
err = b43_aphy_init_tssi2dbm_table(dev);
|
||||
if (err)
|
||||
goto err_free_aphy;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_aphy:
|
||||
kfree(aphy);
|
||||
dev->phy.a = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void b43_aphy_op_prepare_structs(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_a *aphy = phy->a;
|
||||
const void *tssi2dbm;
|
||||
int tgt_idle_tssi;
|
||||
|
||||
/* tssi2dbm table is constant, so it is initialized at alloc time.
|
||||
* Save a copy of the pointer. */
|
||||
tssi2dbm = aphy->tssi2dbm;
|
||||
tgt_idle_tssi = aphy->tgt_idle_tssi;
|
||||
|
||||
/* Zero out the whole PHY structure. */
|
||||
memset(aphy, 0, sizeof(*aphy));
|
||||
|
||||
aphy->tssi2dbm = tssi2dbm;
|
||||
aphy->tgt_idle_tssi = tgt_idle_tssi;
|
||||
|
||||
//TODO init struct b43_phy_a
|
||||
|
||||
}
|
||||
|
||||
static void b43_aphy_op_free(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_a *aphy = phy->a;
|
||||
|
||||
kfree(aphy->tssi2dbm);
|
||||
aphy->tssi2dbm = NULL;
|
||||
|
||||
kfree(aphy);
|
||||
dev->phy.a = NULL;
|
||||
}
|
||||
|
||||
static int b43_aphy_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_inita(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
|
||||
{
|
||||
/* OFDM registers are base-registers for the A-PHY. */
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
|
||||
offset &= ~B43_PHYROUTE;
|
||||
offset |= B43_PHYROUTE_BASE;
|
||||
}
|
||||
|
||||
#if B43_DEBUG
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
|
||||
/* Ext-G registers are only available on G-PHYs */
|
||||
b43err(dev->wl, "Invalid EXT-G PHY access at "
|
||||
"0x%04X on A-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
|
||||
/* N-BMODE registers are only available on N-PHYs */
|
||||
b43err(dev->wl, "Invalid N-BMODE PHY access at "
|
||||
"0x%04X on A-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
#endif /* B43_DEBUG */
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
reg = adjust_phyreg(dev, reg);
|
||||
b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_PHY_DATA);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
reg = adjust_phyreg(dev, reg);
|
||||
b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_DATA, value);
|
||||
}
|
||||
|
||||
static u16 b43_aphy_op_radio_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
/* A-PHY needs 0x40 for read access */
|
||||
reg |= 0x40;
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
|
||||
}
|
||||
|
||||
static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
|
||||
{
|
||||
return (dev->phy.rev >= 5);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
|
||||
bool blocked)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (!blocked) {
|
||||
if (phy->radio_on)
|
||||
return;
|
||||
b43_radio_write16(dev, 0x0004, 0x00C0);
|
||||
b43_radio_write16(dev, 0x0005, 0x0008);
|
||||
b43_phy_mask(dev, 0x0010, 0xFFF7);
|
||||
b43_phy_mask(dev, 0x0011, 0xFFF7);
|
||||
b43_radio_init2060(dev);
|
||||
} else {
|
||||
b43_radio_write16(dev, 0x0004, 0x00FF);
|
||||
b43_radio_write16(dev, 0x0005, 0x00FB);
|
||||
b43_phy_set(dev, 0x0010, 0x0008);
|
||||
b43_phy_set(dev, 0x0011, 0x0008);
|
||||
}
|
||||
}
|
||||
|
||||
static int b43_aphy_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
if (new_channel > 200)
|
||||
return -EINVAL;
|
||||
aphy_channel_switch(dev, new_channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
|
||||
{
|
||||
return 36; /* Default to channel 36 */
|
||||
}
|
||||
|
||||
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
|
||||
{//TODO
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u16 tmp;
|
||||
int autodiv = 0;
|
||||
|
||||
if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
|
||||
autodiv = 1;
|
||||
|
||||
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
|
||||
|
||||
b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
|
||||
(autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
|
||||
B43_PHY_BBANDCFG_RXANT_SHIFT);
|
||||
|
||||
if (autodiv) {
|
||||
tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
|
||||
if (antenna == B43_ANTENNA_AUTO1)
|
||||
tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
|
||||
else
|
||||
tmp |= B43_PHY_ANTDWELL_AUTODIV1;
|
||||
b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
|
||||
}
|
||||
if (phy->rev < 3)
|
||||
b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24);
|
||||
else {
|
||||
b43_phy_set(dev, B43_PHY_OFDM61, 0x10);
|
||||
if (phy->rev == 3) {
|
||||
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D);
|
||||
b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
|
||||
} else {
|
||||
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A);
|
||||
b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
|
||||
}
|
||||
}
|
||||
|
||||
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static enum b43_txpwr_result b43_aphy_op_recalc_txpower(struct b43_wldev *dev,
|
||||
bool ignore_tssi)
|
||||
{//TODO
|
||||
return B43_TXPWR_RES_DONE;
|
||||
}
|
||||
|
||||
static void b43_aphy_op_pwork_15sec(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static const struct b43_phy_operations b43_phyops_a = {
|
||||
.allocate = b43_aphy_op_allocate,
|
||||
.free = b43_aphy_op_free,
|
||||
.prepare_structs = b43_aphy_op_prepare_structs,
|
||||
.init = b43_aphy_op_init,
|
||||
.phy_read = b43_aphy_op_read,
|
||||
.phy_write = b43_aphy_op_write,
|
||||
.radio_read = b43_aphy_op_radio_read,
|
||||
.radio_write = b43_aphy_op_radio_write,
|
||||
.supports_hwpctl = b43_aphy_op_supports_hwpctl,
|
||||
.software_rfkill = b43_aphy_op_software_rfkill,
|
||||
.switch_analog = b43_phyop_switch_analog_generic,
|
||||
.switch_channel = b43_aphy_op_switch_channel,
|
||||
.get_default_chan = b43_aphy_op_get_default_chan,
|
||||
.set_rx_antenna = b43_aphy_op_set_rx_antenna,
|
||||
.recalc_txpower = b43_aphy_op_recalc_txpower,
|
||||
.adjust_txpower = b43_aphy_op_adjust_txpower,
|
||||
.pwork_15sec = b43_aphy_op_pwork_15sec,
|
||||
.pwork_60sec = b43_aphy_op_pwork_60sec,
|
||||
};
|
|
@ -101,26 +101,4 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
|
|||
void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u32 value);
|
||||
|
||||
|
||||
struct b43_phy_a {
|
||||
/* Pointer to the table used to convert a
|
||||
* TSSI value to dBm-Q5.2 */
|
||||
const s8 *tssi2dbm;
|
||||
/* Target idle TSSI */
|
||||
int tgt_idle_tssi;
|
||||
/* Current idle TSSI */
|
||||
int cur_idle_tssi;//FIXME value currently not set
|
||||
|
||||
/* A-PHY TX Power control value. */
|
||||
u16 txpwr_offset;
|
||||
|
||||
//TODO lots of missing stuff
|
||||
};
|
||||
|
||||
/**
|
||||
* b43_phy_inita - Lowlevel A-PHY init routine.
|
||||
* This is _only_ used by the G-PHY code.
|
||||
*/
|
||||
void b43_phy_inita(struct b43_wldev *dev);
|
||||
|
||||
#endif /* LINUX_B43_PHY_A_H_ */
|
||||
|
|
|
@ -190,7 +190,6 @@ struct b43_phy_operations {
|
|||
void (*pwork_60sec)(struct b43_wldev *dev);
|
||||
};
|
||||
|
||||
struct b43_phy_a;
|
||||
struct b43_phy_g;
|
||||
struct b43_phy_n;
|
||||
struct b43_phy_lp;
|
||||
|
@ -210,8 +209,6 @@ struct b43_phy {
|
|||
#else
|
||||
union {
|
||||
#endif
|
||||
/* A-PHY specific information */
|
||||
struct b43_phy_a *a;
|
||||
/* G-PHY specific information */
|
||||
struct b43_phy_g *g;
|
||||
/* N-PHY specific information */
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "phy_common.h"
|
||||
#include "lo.h"
|
||||
#include "main.h"
|
||||
#include "wa.h"
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -1987,6 +1988,25 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
|
|||
b43_shm_clear_tssi(dev);
|
||||
}
|
||||
|
||||
static void b43_phy_inita(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (phy->rev >= 6) {
|
||||
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
|
||||
b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
|
||||
else
|
||||
b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
|
||||
}
|
||||
|
||||
b43_wa_all(dev);
|
||||
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
|
||||
}
|
||||
|
||||
static void b43_phy_initg(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
@ -2150,11 +2170,6 @@ static void default_radio_attenuation(struct b43_wldev *dev,
|
|||
}
|
||||
}
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
rf->att = 0x60;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (phy->radio_ver) {
|
||||
case 0x2053:
|
||||
switch (phy->radio_rev) {
|
||||
|
|
|
@ -30,33 +30,6 @@
|
|||
#include "phy_common.h"
|
||||
#include "wa.h"
|
||||
|
||||
static void b43_wa_papd(struct b43_wldev *dev)
|
||||
{
|
||||
u16 backup;
|
||||
|
||||
backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0);
|
||||
b43_dummy_transmission(dev, true, true);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup);
|
||||
}
|
||||
|
||||
static void b43_wa_auxclipthr(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800);
|
||||
}
|
||||
|
||||
static void b43_wa_afcdac(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_write(dev, 0x0035, 0x03FF);
|
||||
b43_phy_write(dev, 0x0036, 0x0400);
|
||||
}
|
||||
|
||||
static void b43_wa_txdc_offset(struct b43_wldev *dev)
|
||||
{
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051);
|
||||
}
|
||||
|
||||
void b43_wa_initgains(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
@ -81,41 +54,6 @@ void b43_wa_initgains(struct b43_wldev *dev)
|
|||
b43_phy_write(dev, 0x00BA, 0x3ED5);
|
||||
}
|
||||
|
||||
static void b43_wa_divider(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_mask(dev, 0x002B, ~0x0100);
|
||||
b43_phy_write(dev, 0x008E, 0x58C1);
|
||||
}
|
||||
|
||||
static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */
|
||||
{
|
||||
if (dev->phy.rev <= 2) {
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7);
|
||||
} else {
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
|
||||
{
|
||||
int i;
|
||||
|
@ -133,15 +71,11 @@ static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
|
|||
|
||||
static void b43_wa_analog(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u16 ofdmrev;
|
||||
|
||||
ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION;
|
||||
if (ofdmrev > 2) {
|
||||
if (phy->type == B43_PHYTYPE_A)
|
||||
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808);
|
||||
else
|
||||
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
|
||||
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
|
||||
} else {
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201);
|
||||
|
@ -149,26 +83,13 @@ static void b43_wa_analog(struct b43_wldev *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void b43_wa_dac(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->phy.analog == 1)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
|
||||
(b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008);
|
||||
else
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
|
||||
(b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010);
|
||||
}
|
||||
|
||||
static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->phy.type == B43_PHYTYPE_A)
|
||||
for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]);
|
||||
for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i,
|
||||
b43_tab_finefreqg[i]);
|
||||
}
|
||||
|
||||
static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
|
||||
|
@ -176,21 +97,14 @@ static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
|
|||
struct b43_phy *phy = &dev->phy;
|
||||
int i;
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
if (phy->rev == 2)
|
||||
for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]);
|
||||
} else {
|
||||
if (phy->rev == 1)
|
||||
for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]);
|
||||
}
|
||||
if (phy->rev == 1)
|
||||
for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
|
||||
b43_tab_noiseg1[i]);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
|
||||
b43_tab_noiseg2[i]);
|
||||
}
|
||||
|
||||
static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
|
||||
|
@ -201,14 +115,6 @@ static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
|
|||
b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
|
||||
}
|
||||
|
||||
static void b43_write_null_nst(struct b43_wldev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, 0);
|
||||
}
|
||||
|
||||
static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
|
||||
{
|
||||
int i;
|
||||
|
@ -221,24 +127,13 @@ static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
|
|||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
if (phy->rev <= 1)
|
||||
b43_write_null_nst(dev);
|
||||
else if (phy->rev == 2)
|
||||
b43_write_nst(dev, b43_tab_noisescalea2);
|
||||
else if (phy->rev == 3)
|
||||
b43_write_nst(dev, b43_tab_noisescalea3);
|
||||
else
|
||||
if (phy->rev >= 6) {
|
||||
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
|
||||
b43_write_nst(dev, b43_tab_noisescaleg3);
|
||||
else
|
||||
b43_write_nst(dev, b43_tab_noisescaleg2);
|
||||
} else {
|
||||
if (phy->rev >= 6) {
|
||||
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
|
||||
b43_write_nst(dev, b43_tab_noisescaleg3);
|
||||
else
|
||||
b43_write_nst(dev, b43_tab_noisescaleg2);
|
||||
} else {
|
||||
b43_write_nst(dev, b43_tab_noisescaleg1);
|
||||
}
|
||||
b43_write_nst(dev, b43_tab_noisescaleg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,41 +146,13 @@ static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */
|
|||
i, b43_tab_retard[i]);
|
||||
}
|
||||
|
||||
static void b43_wa_txlna_gain(struct b43_wldev *dev)
|
||||
{
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000);
|
||||
}
|
||||
|
||||
static void b43_wa_crs_reset(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_write(dev, 0x002C, 0x0064);
|
||||
}
|
||||
|
||||
static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
|
||||
{
|
||||
b43_hf_write(dev, b43_hf_read(dev) |
|
||||
B43_HF_2060W);
|
||||
}
|
||||
|
||||
static void b43_wa_lms(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
|
||||
}
|
||||
|
||||
static void b43_wa_mixedsignal(struct b43_wldev *dev)
|
||||
{
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3);
|
||||
}
|
||||
|
||||
static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
int i;
|
||||
const u16 *tab;
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
tab = b43_tab_sigmasqr1;
|
||||
} else if (phy->type == B43_PHYTYPE_G) {
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
tab = b43_tab_sigmasqr2;
|
||||
} else {
|
||||
B43_WARN_ON(1);
|
||||
|
@ -298,13 +165,6 @@ static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
|
|||
}
|
||||
}
|
||||
|
||||
static void b43_wa_iqadc(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->phy.analog == 4)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0,
|
||||
b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000);
|
||||
}
|
||||
|
||||
static void b43_wa_crs_ed(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
@ -450,38 +310,6 @@ static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
|
|||
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0);
|
||||
}
|
||||
|
||||
static void b43_wa_rssi_adc(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->phy.analog == 4)
|
||||
b43_phy_write(dev, 0x00DC, 0x7454);
|
||||
}
|
||||
|
||||
static void b43_wa_boards_a(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
|
||||
dev->dev->board_type == SSB_BOARD_BU4306 &&
|
||||
dev->dev->board_rev < 0x30) {
|
||||
b43_phy_write(dev, 0x0010, 0xE000);
|
||||
b43_phy_write(dev, 0x0013, 0x0140);
|
||||
b43_phy_write(dev, 0x0014, 0x0280);
|
||||
} else {
|
||||
if (dev->dev->board_type == SSB_BOARD_MP4318 &&
|
||||
dev->dev->board_rev < 0x20) {
|
||||
b43_phy_write(dev, 0x0013, 0x0210);
|
||||
b43_phy_write(dev, 0x0014, 0x0840);
|
||||
} else {
|
||||
b43_phy_write(dev, 0x0013, 0x0140);
|
||||
b43_phy_write(dev, 0x0014, 0x0280);
|
||||
}
|
||||
if (dev->phy.rev <= 4)
|
||||
b43_phy_write(dev, 0x0010, 0xE000);
|
||||
else
|
||||
b43_phy_write(dev, 0x0010, 0x2000);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_wa_boards_g(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
@ -518,80 +346,7 @@ void b43_wa_all(struct b43_wldev *dev)
|
|||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
switch (phy->rev) {
|
||||
case 2:
|
||||
b43_wa_papd(dev);
|
||||
b43_wa_auxclipthr(dev);
|
||||
b43_wa_afcdac(dev);
|
||||
b43_wa_txdc_offset(dev);
|
||||
b43_wa_initgains(dev);
|
||||
b43_wa_divider(dev);
|
||||
b43_wa_gt(dev);
|
||||
b43_wa_rssi_lt(dev);
|
||||
b43_wa_analog(dev);
|
||||
b43_wa_dac(dev);
|
||||
b43_wa_fft(dev);
|
||||
b43_wa_nft(dev);
|
||||
b43_wa_rt(dev);
|
||||
b43_wa_nst(dev);
|
||||
b43_wa_art(dev);
|
||||
b43_wa_txlna_gain(dev);
|
||||
b43_wa_crs_reset(dev);
|
||||
b43_wa_2060txlna_gain(dev);
|
||||
b43_wa_lms(dev);
|
||||
break;
|
||||
case 3:
|
||||
b43_wa_papd(dev);
|
||||
b43_wa_mixedsignal(dev);
|
||||
b43_wa_rssi_lt(dev);
|
||||
b43_wa_txdc_offset(dev);
|
||||
b43_wa_initgains(dev);
|
||||
b43_wa_dac(dev);
|
||||
b43_wa_nft(dev);
|
||||
b43_wa_nst(dev);
|
||||
b43_wa_msst(dev);
|
||||
b43_wa_analog(dev);
|
||||
b43_wa_gt(dev);
|
||||
b43_wa_txpuoff_rxpuon(dev);
|
||||
b43_wa_txlna_gain(dev);
|
||||
break;
|
||||
case 5:
|
||||
b43_wa_iqadc(dev);
|
||||
case 6:
|
||||
b43_wa_papd(dev);
|
||||
b43_wa_rssi_lt(dev);
|
||||
b43_wa_txdc_offset(dev);
|
||||
b43_wa_initgains(dev);
|
||||
b43_wa_dac(dev);
|
||||
b43_wa_nft(dev);
|
||||
b43_wa_nst(dev);
|
||||
b43_wa_msst(dev);
|
||||
b43_wa_analog(dev);
|
||||
b43_wa_gt(dev);
|
||||
b43_wa_txpuoff_rxpuon(dev);
|
||||
b43_wa_txlna_gain(dev);
|
||||
break;
|
||||
case 7:
|
||||
b43_wa_iqadc(dev);
|
||||
b43_wa_papd(dev);
|
||||
b43_wa_rssi_lt(dev);
|
||||
b43_wa_txdc_offset(dev);
|
||||
b43_wa_initgains(dev);
|
||||
b43_wa_dac(dev);
|
||||
b43_wa_nft(dev);
|
||||
b43_wa_nst(dev);
|
||||
b43_wa_msst(dev);
|
||||
b43_wa_analog(dev);
|
||||
b43_wa_gt(dev);
|
||||
b43_wa_txpuoff_rxpuon(dev);
|
||||
b43_wa_txlna_gain(dev);
|
||||
b43_wa_rssi_adc(dev);
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
}
|
||||
b43_wa_boards_a(dev);
|
||||
} else if (phy->type == B43_PHYTYPE_G) {
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
switch (phy->rev) {
|
||||
case 1://XXX review rev1
|
||||
b43_wa_crs_ed(dev);
|
||||
|
|
|
@ -205,7 +205,7 @@ static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
|
|||
return control;
|
||||
}
|
||||
|
||||
static u8 b43_calc_fallback_rate(u8 bitrate)
|
||||
static u8 b43_calc_fallback_rate(u8 bitrate, int gmode)
|
||||
{
|
||||
switch (bitrate) {
|
||||
case B43_CCK_RATE_1MB:
|
||||
|
@ -216,8 +216,15 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
|
|||
return B43_CCK_RATE_2MB;
|
||||
case B43_CCK_RATE_11MB:
|
||||
return B43_CCK_RATE_5MB;
|
||||
/*
|
||||
* Don't just fallback to CCK; it may be in 5GHz operation
|
||||
* and falling back to CCK won't work out very well.
|
||||
*/
|
||||
case B43_OFDM_RATE_6MB:
|
||||
return B43_CCK_RATE_5MB;
|
||||
if (gmode)
|
||||
return B43_CCK_RATE_5MB;
|
||||
else
|
||||
return B43_OFDM_RATE_6MB;
|
||||
case B43_OFDM_RATE_9MB:
|
||||
return B43_OFDM_RATE_6MB;
|
||||
case B43_OFDM_RATE_12MB:
|
||||
|
@ -438,7 +445,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
|
|||
|
||||
rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
|
||||
rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
|
||||
rts_rate_fb = b43_calc_fallback_rate(rts_rate);
|
||||
rts_rate_fb = b43_calc_fallback_rate(rts_rate, phy->gmode);
|
||||
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
|
||||
|
||||
if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
|
@ -642,11 +649,7 @@ static s8 b43_rssinoise_postprocess(struct b43_wldev *dev, u8 in_rssi)
|
|||
struct b43_phy *phy = &dev->phy;
|
||||
s8 ret;
|
||||
|
||||
if (phy->type == B43_PHYTYPE_A) {
|
||||
//TODO: Incomplete specs.
|
||||
ret = 0;
|
||||
} else
|
||||
ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
|
||||
ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -663,7 +666,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
u16 uninitialized_var(chanstat), uninitialized_var(mactime);
|
||||
u32 uninitialized_var(macstat);
|
||||
u16 chanid;
|
||||
u16 phytype;
|
||||
int padding, rate_idx;
|
||||
|
||||
memset(&status, 0, sizeof(status));
|
||||
|
@ -684,7 +686,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
chanstat = le16_to_cpu(rxhdr->format_351.channel);
|
||||
break;
|
||||
}
|
||||
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
|
||||
|
||||
if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
|
||||
dev->wl->ieee_stats.dot11FCSErrorCount++;
|
||||
|
@ -755,7 +756,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
else
|
||||
status.signal = max(rxhdr->power0, rxhdr->power1);
|
||||
break;
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_B:
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_LP:
|
||||
|
@ -802,14 +802,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
|
||||
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
|
||||
switch (chanstat & B43_RX_CHAN_PHYTYPE) {
|
||||
case B43_PHYTYPE_A:
|
||||
status.band = NL80211_BAND_5GHZ;
|
||||
B43_WARN_ON(1);
|
||||
/* FIXME: We don't really know which value the "chanid" contains.
|
||||
* So the following assignment might be wrong. */
|
||||
status.freq =
|
||||
ieee80211_channel_to_frequency(chanid, status.band);
|
||||
break;
|
||||
case B43_PHYTYPE_G:
|
||||
status.band = NL80211_BAND_2GHZ;
|
||||
/* Somewhere between 478.104 and 508.1084 firmware for G-PHY
|
||||
|
|
|
@ -166,41 +166,45 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
|
|||
sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
|
||||
sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
sdiodev->sd_irq_requested = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
|
||||
void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
struct brcmfmac_sdio_pd *pdata;
|
||||
|
||||
brcmf_dbg(SDIO, "Entering\n");
|
||||
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
|
||||
sdiodev->oob_irq_requested,
|
||||
sdiodev->sd_irq_requested);
|
||||
|
||||
pdata = &sdiodev->settings->bus.sdio;
|
||||
if (pdata->oob_irq_supported) {
|
||||
if (sdiodev->oob_irq_requested) {
|
||||
struct brcmfmac_sdio_pd *pdata;
|
||||
|
||||
pdata = &sdiodev->settings->bus.sdio;
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
if (sdiodev->oob_irq_requested) {
|
||||
sdiodev->oob_irq_requested = false;
|
||||
if (sdiodev->irq_wake) {
|
||||
disable_irq_wake(pdata->oob_irq_nr);
|
||||
sdiodev->irq_wake = false;
|
||||
}
|
||||
free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
|
||||
sdiodev->irq_en = false;
|
||||
sdiodev->oob_irq_requested = false;
|
||||
if (sdiodev->irq_wake) {
|
||||
disable_irq_wake(pdata->oob_irq_nr);
|
||||
sdiodev->irq_wake = false;
|
||||
}
|
||||
} else {
|
||||
free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
|
||||
sdiodev->irq_en = false;
|
||||
sdiodev->oob_irq_requested = false;
|
||||
}
|
||||
|
||||
if (sdiodev->sd_irq_requested) {
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
sdio_release_irq(sdiodev->func[2]);
|
||||
sdio_release_irq(sdiodev->func[1]);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
sdiodev->sd_irq_requested = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
|
||||
|
@ -1197,12 +1201,17 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
|
|||
brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
|
||||
brcmf_dbg(SDIO, "Function: %d\n", func->num);
|
||||
|
||||
if (func->num != 1)
|
||||
return;
|
||||
|
||||
bus_if = dev_get_drvdata(&func->dev);
|
||||
if (bus_if) {
|
||||
sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
/* start by unregistering irqs */
|
||||
brcmf_sdiod_intr_unregister(sdiodev);
|
||||
|
||||
if (func->num != 1)
|
||||
return;
|
||||
|
||||
/* only proceed with rest of cleanup if func 1 */
|
||||
brcmf_sdiod_remove(sdiodev);
|
||||
|
||||
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
|
||||
|
|
|
@ -541,6 +541,21 @@ brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
|
|||
ADDR_INDIRECT);
|
||||
}
|
||||
|
||||
static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
|
||||
{
|
||||
int bsscfgidx;
|
||||
|
||||
for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
|
||||
/* bsscfgidx 1 is reserved for legacy P2P */
|
||||
if (bsscfgidx == 1)
|
||||
continue;
|
||||
if (!drvr->iflist[bsscfgidx])
|
||||
return bsscfgidx;
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_mbss_ssid_le mbss_ssid_le;
|
||||
|
@ -548,7 +563,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
|||
int err;
|
||||
|
||||
memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
|
||||
bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
|
||||
bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
|
||||
if (bsscfgidx < 0)
|
||||
return bsscfgidx;
|
||||
|
||||
|
@ -586,7 +601,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
|
|||
|
||||
brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
|
||||
|
||||
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
|
||||
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
|
||||
if (IS_ERR(vif))
|
||||
return (struct wireless_dev *)vif;
|
||||
|
||||
|
@ -669,20 +684,24 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
case NL80211_IFTYPE_AP:
|
||||
wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
|
||||
if (!IS_ERR(wdev))
|
||||
brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
return wdev;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
|
||||
if (!IS_ERR(wdev))
|
||||
brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
return wdev;
|
||||
break;
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (IS_ERR(wdev))
|
||||
brcmf_err("add iface %s type %d failed: err=%d\n",
|
||||
name, type, (int)PTR_ERR(wdev));
|
||||
else
|
||||
brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
|
||||
return wdev;
|
||||
}
|
||||
|
||||
static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
|
||||
|
@ -2750,7 +2769,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
|
|||
if (!bi->ctl_ch) {
|
||||
ch.chspec = le16_to_cpu(bi->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
bi->ctl_ch = ch.chnum;
|
||||
bi->ctl_ch = ch.control_ch_num;
|
||||
}
|
||||
channel = bi->ctl_ch;
|
||||
|
||||
|
@ -2868,7 +2887,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
|
|||
else
|
||||
band = wiphy->bands[NL80211_BAND_5GHZ];
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
|
||||
cfg->channel = freq;
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
|
@ -2878,7 +2897,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
|
|||
notify_ielen = le32_to_cpu(bi->ie_length);
|
||||
notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
|
||||
|
||||
brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
|
||||
brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
|
||||
brcmf_dbg(CONN, "capability: %X\n", notify_capability);
|
||||
brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
|
||||
brcmf_dbg(CONN, "signal: %d\n", notify_signal);
|
||||
|
@ -4439,7 +4458,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
struct brcmf_join_params join_params;
|
||||
enum nl80211_iftype dev_role;
|
||||
struct brcmf_fil_bss_enable_le bss_enable;
|
||||
u16 chanspec;
|
||||
u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
|
||||
bool mbss;
|
||||
int is_11d;
|
||||
|
||||
|
@ -4515,16 +4534,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
|
||||
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
|
||||
|
||||
/* Parameters shared by all radio interfaces */
|
||||
if (!mbss) {
|
||||
chanspec = chandef_to_chanspec(&cfg->d11inf,
|
||||
&settings->chandef);
|
||||
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
if (err < 0) {
|
||||
brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
chanspec, err);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (is_11d != ifp->vif->is_11d) {
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
is_11d);
|
||||
|
@ -4572,6 +4583,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Interface specific setup */
|
||||
if (dev_role == NL80211_IFTYPE_AP) {
|
||||
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
|
||||
brcmf_fil_iovar_int_set(ifp, "mbss", 1);
|
||||
|
@ -4581,6 +4594,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
brcmf_err("setting AP mode failed %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
if (!mbss) {
|
||||
/* Firmware 10.x requires setting channel after enabling
|
||||
* AP and before bringing interface up.
|
||||
*/
|
||||
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
if (err < 0) {
|
||||
brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
chanspec, err);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
|
||||
if (err < 0) {
|
||||
brcmf_err("BRCMF_C_UP error (%d)\n", err);
|
||||
|
@ -4602,7 +4626,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
goto exit;
|
||||
}
|
||||
brcmf_dbg(TRACE, "AP mode configuration complete\n");
|
||||
} else {
|
||||
} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
|
||||
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
if (err < 0) {
|
||||
brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
chanspec, err);
|
||||
goto exit;
|
||||
}
|
||||
err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
|
||||
sizeof(ssid_le));
|
||||
if (err < 0) {
|
||||
|
@ -4619,7 +4649,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
}
|
||||
|
||||
brcmf_dbg(TRACE, "GO mode configuration complete\n");
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
brcmf_net_setcarrier(ifp, true);
|
||||
|
||||
|
@ -4908,6 +4941,68 @@ exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct net_device *ndev = wdev->netdev;
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmu_chan ch;
|
||||
enum nl80211_band band = 0;
|
||||
enum nl80211_chan_width width = 0;
|
||||
u32 chanspec;
|
||||
int freq, err;
|
||||
|
||||
if (!ndev)
|
||||
return -ENODEV;
|
||||
ifp = netdev_priv(ndev);
|
||||
|
||||
err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
|
||||
if (err) {
|
||||
brcmf_err("chanspec failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
ch.chspec = chanspec;
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
|
||||
switch (ch.band) {
|
||||
case BRCMU_CHAN_BAND_2G:
|
||||
band = NL80211_BAND_2GHZ;
|
||||
break;
|
||||
case BRCMU_CHAN_BAND_5G:
|
||||
band = NL80211_BAND_5GHZ;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ch.bw) {
|
||||
case BRCMU_CHAN_BW_80:
|
||||
width = NL80211_CHAN_WIDTH_80;
|
||||
break;
|
||||
case BRCMU_CHAN_BW_40:
|
||||
width = NL80211_CHAN_WIDTH_40;
|
||||
break;
|
||||
case BRCMU_CHAN_BW_20:
|
||||
width = NL80211_CHAN_WIDTH_20;
|
||||
break;
|
||||
case BRCMU_CHAN_BW_80P80:
|
||||
width = NL80211_CHAN_WIDTH_80P80;
|
||||
break;
|
||||
case BRCMU_CHAN_BW_160:
|
||||
width = NL80211_CHAN_WIDTH_160;
|
||||
break;
|
||||
}
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
|
||||
chandef->chan = ieee80211_get_channel(wiphy, freq);
|
||||
chandef->width = width;
|
||||
chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
|
||||
chandef->center_freq2 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
enum nl80211_crit_proto_id proto,
|
||||
|
@ -5070,6 +5165,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
|
|||
.mgmt_tx = brcmf_cfg80211_mgmt_tx,
|
||||
.remain_on_channel = brcmf_p2p_remain_on_channel,
|
||||
.cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
|
||||
.get_channel = brcmf_cfg80211_get_channel,
|
||||
.start_p2p_device = brcmf_p2p_start_device,
|
||||
.stop_p2p_device = brcmf_p2p_stop_device,
|
||||
.crit_proto_start = brcmf_cfg80211_crit_proto_start,
|
||||
|
@ -5078,8 +5174,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
|
|||
};
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
enum nl80211_iftype type,
|
||||
bool pm_block)
|
||||
enum nl80211_iftype type)
|
||||
{
|
||||
struct brcmf_cfg80211_vif *vif_walk;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
|
@ -5094,8 +5189,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
|||
vif->wdev.wiphy = cfg->wiphy;
|
||||
vif->wdev.iftype = type;
|
||||
|
||||
vif->pm_block = pm_block;
|
||||
|
||||
brcmf_init_prof(&vif->profile);
|
||||
|
||||
if (type == NL80211_IFTYPE_AP) {
|
||||
|
@ -5296,7 +5389,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
|
|||
else
|
||||
band = wiphy->bands[NL80211_BAND_5GHZ];
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
done:
|
||||
|
@ -5352,7 +5445,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
|
|||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
static int generation;
|
||||
u32 event = e->event_code;
|
||||
u32 reason = e->reason;
|
||||
|
@ -5363,8 +5455,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
|
|||
ndev != cfg_to_ndev(cfg)) {
|
||||
brcmf_dbg(CONN, "AP mode link down\n");
|
||||
complete(&cfg->vif_disabled);
|
||||
if (ifp->vif->mbss)
|
||||
brcmf_remove_interface(ifp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5818,14 +5908,15 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
|
|||
channel = band->channels;
|
||||
index = band->n_channels;
|
||||
for (j = 0; j < band->n_channels; j++) {
|
||||
if (channel[j].hw_value == ch.chnum) {
|
||||
if (channel[j].hw_value == ch.control_ch_num) {
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
channel[index].center_freq =
|
||||
ieee80211_channel_to_frequency(ch.chnum, band->band);
|
||||
channel[index].hw_value = ch.chnum;
|
||||
ieee80211_channel_to_frequency(ch.control_ch_num,
|
||||
band->band);
|
||||
channel[index].hw_value = ch.control_ch_num;
|
||||
|
||||
/* assuming the chanspecs order is HT20,
|
||||
* HT40 upper, HT40 lower, and VHT80.
|
||||
|
@ -5927,7 +6018,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
|
|||
if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
|
||||
continue;
|
||||
for (j = 0; j < band->n_channels; j++) {
|
||||
if (band->channels[j].hw_value == ch.chnum)
|
||||
if (band->channels[j].hw_value == ch.control_ch_num)
|
||||
break;
|
||||
}
|
||||
if (WARN_ON(j == band->n_channels))
|
||||
|
@ -6715,11 +6806,10 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ops = kzalloc(sizeof(*ops), GFP_KERNEL);
|
||||
ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
|
||||
if (!ops)
|
||||
return NULL;
|
||||
|
||||
memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
|
||||
ifp = netdev_priv(ndev);
|
||||
#ifdef CONFIG_PM
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
|
||||
|
@ -6740,7 +6830,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
|||
init_vif_event(&cfg->vif_event);
|
||||
INIT_LIST_HEAD(&cfg->vif_list);
|
||||
|
||||
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
|
||||
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
|
||||
if (IS_ERR(vif))
|
||||
goto wiphy_out;
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
/* for brcmu_d11inf */
|
||||
#include <brcmu_d11.h>
|
||||
|
||||
#include "fwil_types.h"
|
||||
#include "p2p.h"
|
||||
|
||||
#define WL_NUM_SCAN_MAX 10
|
||||
#define WL_TLV_INFO_MAX 1024
|
||||
#define WL_BSS_INFO_MAX 2048
|
||||
|
@ -167,7 +170,6 @@ struct vif_saved_ie {
|
|||
* @wdev: wireless device.
|
||||
* @profile: profile information.
|
||||
* @sme_state: SME state using enum brcmf_vif_status bits.
|
||||
* @pm_block: power-management blocked.
|
||||
* @list: linked list.
|
||||
* @mgmt_rx_reg: registered rx mgmt frame types.
|
||||
* @mbss: Multiple BSS type, set if not first AP (not relevant for P2P).
|
||||
|
@ -177,7 +179,6 @@ struct brcmf_cfg80211_vif {
|
|||
struct wireless_dev wdev;
|
||||
struct brcmf_cfg80211_profile profile;
|
||||
unsigned long sme_state;
|
||||
bool pm_block;
|
||||
struct vif_saved_ie saved_ie;
|
||||
struct list_head list;
|
||||
u16 mgmt_rx_reg;
|
||||
|
@ -388,8 +389,7 @@ s32 brcmf_cfg80211_down(struct net_device *ndev);
|
|||
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
enum nl80211_iftype type,
|
||||
bool pm_block);
|
||||
enum nl80211_iftype type);
|
||||
void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
|
||||
|
||||
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
||||
|
|
|
@ -685,6 +685,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
|
|||
case BRCM_CC_43602_CHIP_ID:
|
||||
case BRCM_CC_4371_CHIP_ID:
|
||||
return 0x180000;
|
||||
case BRCM_CC_43465_CHIP_ID:
|
||||
case BRCM_CC_43525_CHIP_ID:
|
||||
case BRCM_CC_4365_CHIP_ID:
|
||||
case BRCM_CC_4366_CHIP_ID:
|
||||
return 0x200000;
|
||||
|
|
|
@ -516,7 +516,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
|
|||
/* set appropriate operations */
|
||||
ndev->netdev_ops = &brcmf_netdev_ops_pri;
|
||||
|
||||
ndev->hard_header_len += drvr->hdrlen;
|
||||
ndev->needed_headroom += drvr->hdrlen;
|
||||
ndev->ethtool_ops = &brcmf_ethtool_ops;
|
||||
|
||||
drvr->rxsz = ndev->mtu + ndev->hard_header_len +
|
||||
|
@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf_if *ifp)
|
|||
brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
|
||||
}
|
||||
|
||||
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
|
||||
{
|
||||
int ifidx;
|
||||
int bsscfgidx;
|
||||
bool available;
|
||||
int highest;
|
||||
|
||||
available = false;
|
||||
bsscfgidx = 2;
|
||||
highest = 2;
|
||||
for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
|
||||
if (drvr->iflist[ifidx]) {
|
||||
if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx)
|
||||
bsscfgidx = highest + 1;
|
||||
else if (drvr->iflist[ifidx]->bsscfgidx > highest)
|
||||
highest = drvr->iflist[ifidx]->bsscfgidx;
|
||||
} else {
|
||||
available = true;
|
||||
}
|
||||
}
|
||||
|
||||
return available ? bsscfgidx : -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INET
|
||||
#define ARPOL_MAX_ENTRIES 8
|
||||
static int brcmf_inetaddr_changed(struct notifier_block *nb,
|
||||
|
|
|
@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
|||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, char *name, u8 *mac_addr);
|
||||
void brcmf_remove_interface(struct brcmf_if *ifp);
|
||||
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
|
|
|
@ -2101,7 +2101,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
|
|||
|
||||
brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
|
||||
/* determine the priority */
|
||||
if (!skb->priority)
|
||||
if ((skb->priority == 0) || (skb->priority > 7))
|
||||
skb->priority = cfg80211_classify8021d(skb, NULL);
|
||||
|
||||
drvr->tx_multicast += !!multicast;
|
||||
|
|
|
@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
|
|||
if (!bi->ctl_ch) {
|
||||
ch.chspec = le16_to_cpu(bi->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
bi->ctl_ch = ch.chnum;
|
||||
bi->ctl_ch = ch.control_ch_num;
|
||||
}
|
||||
afx_hdl->peer_chan = bi->ctl_ch;
|
||||
brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
|
||||
|
@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
|
|||
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
|
||||
&p2p->status) &&
|
||||
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
|
||||
afx_hdl->peer_chan = ch.chnum;
|
||||
afx_hdl->peer_chan = ch.control_ch_num;
|
||||
brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
|
||||
afx_hdl->peer_chan);
|
||||
complete(&afx_hdl->act_frm_scan);
|
||||
|
@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
|
|||
memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
|
||||
mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.chnum,
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num,
|
||||
ch.band == BRCMU_CHAN_BAND_2G ?
|
||||
NL80211_BAND_2GHZ :
|
||||
NL80211_BAND_5GHZ);
|
||||
|
@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
|
|||
|
||||
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
|
||||
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
|
||||
afx_hdl->peer_chan = ch.chnum;
|
||||
afx_hdl->peer_chan = ch.control_ch_num;
|
||||
brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
|
||||
afx_hdl->peer_chan);
|
||||
complete(&afx_hdl->act_frm_scan);
|
||||
|
@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
|
|||
|
||||
mgmt_frame = (u8 *)(rxframe + 1);
|
||||
mgmt_frame_len = e->datalen - sizeof(*rxframe);
|
||||
freq = ieee80211_channel_to_frequency(ch.chnum,
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num,
|
||||
ch.band == BRCMU_CHAN_BAND_2G ?
|
||||
NL80211_BAND_2GHZ :
|
||||
NL80211_BAND_5GHZ);
|
||||
|
@ -2030,8 +2030,6 @@ static int brcmf_p2p_request_p2p_if(struct brcmf_p2p_info *p2p,
|
|||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
|
||||
sizeof(if_request));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -2076,8 +2074,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
|
|||
if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
|
||||
return ERR_PTR(-ENOSPC);
|
||||
|
||||
p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE,
|
||||
false);
|
||||
p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE);
|
||||
if (IS_ERR(p2p_vif)) {
|
||||
brcmf_err("could not create discovery vif\n");
|
||||
return (struct wireless_dev *)p2p_vif;
|
||||
|
@ -2177,7 +2174,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
vif = brcmf_alloc_vif(cfg, type, false);
|
||||
vif = brcmf_alloc_vif(cfg, type);
|
||||
if (IS_ERR(vif))
|
||||
return (struct wireless_dev *)vif;
|
||||
brcmf_cfg80211_arm_vif_event(cfg, vif);
|
||||
|
|
|
@ -54,21 +54,25 @@ BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt");
|
|||
BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");
|
||||
|
||||
static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
|
||||
|
|
|
@ -1384,8 +1384,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
|
|||
return -ENXIO;
|
||||
}
|
||||
if (rd->seq_num != rx_seq) {
|
||||
brcmf_err("seq %d: sequence number error, expect %d\n",
|
||||
rx_seq, rd->seq_num);
|
||||
brcmf_dbg(SDIO, "seq %d, expected %d\n", rx_seq, rd->seq_num);
|
||||
bus->sdcnt.rx_badseq++;
|
||||
rd->seq_num = rx_seq;
|
||||
}
|
||||
|
@ -3666,7 +3665,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
|
|||
str_shift = 11;
|
||||
break;
|
||||
default:
|
||||
brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
|
||||
brcmf_dbg(INFO, "No SDIO driver strength init needed for chip %s rev %d pmurev %d\n",
|
||||
ci->name, ci->chiprev, ci->pmurev);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -186,6 +186,7 @@ struct brcmf_sdio_dev {
|
|||
struct brcmf_bus *bus_if;
|
||||
struct brcmf_mp_device *settings;
|
||||
bool oob_irq_requested;
|
||||
bool sd_irq_requested;
|
||||
bool irq_en; /* irq enable flags */
|
||||
spinlock_t irq_en_lock;
|
||||
bool irq_wake; /* irq wake enable flags */
|
||||
|
@ -293,7 +294,7 @@ struct sdpcmd_regs {
|
|||
|
||||
/* Register/deregister interrupt handler. */
|
||||
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
|
||||
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
|
||||
void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
/* sdio device register access interface */
|
||||
u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
|
||||
|
|
|
@ -27017,7 +27017,7 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
|
|||
tx_core = 1 - rx_core;
|
||||
|
||||
num_samps = 1024;
|
||||
desired_log2_pwr = (cal_type == 0) ? 13 : 13;
|
||||
desired_log2_pwr = 13;
|
||||
|
||||
wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
|
||||
zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
|
||||
|
|
|
@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
|
|||
u16 val;
|
||||
|
||||
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
|
||||
ch->control_ch_num = ch->chnum;
|
||||
|
||||
switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
|
||||
case BRCMU_CHSPEC_D11N_BW_20:
|
||||
|
@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
|
|||
val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK;
|
||||
if (val == BRCMU_CHSPEC_D11N_SB_L) {
|
||||
ch->sb = BRCMU_CHAN_SB_L;
|
||||
ch->chnum -= CH_10MHZ_APART;
|
||||
ch->control_ch_num -= CH_10MHZ_APART;
|
||||
} else {
|
||||
ch->sb = BRCMU_CHAN_SB_U;
|
||||
ch->chnum += CH_10MHZ_APART;
|
||||
ch->control_ch_num += CH_10MHZ_APART;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
|||
u16 val;
|
||||
|
||||
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
|
||||
ch->control_ch_num = ch->chnum;
|
||||
|
||||
switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
|
||||
case BRCMU_CHSPEC_D11AC_BW_20:
|
||||
|
@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
|||
val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK;
|
||||
if (val == BRCMU_CHSPEC_D11AC_SB_L) {
|
||||
ch->sb = BRCMU_CHAN_SB_L;
|
||||
ch->chnum -= CH_10MHZ_APART;
|
||||
ch->control_ch_num -= CH_10MHZ_APART;
|
||||
} else if (val == BRCMU_CHSPEC_D11AC_SB_U) {
|
||||
ch->sb = BRCMU_CHAN_SB_U;
|
||||
ch->chnum += CH_10MHZ_APART;
|
||||
ch->control_ch_num += CH_10MHZ_APART;
|
||||
} else {
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
|||
BRCMU_CHSPEC_D11AC_SB_SHIFT);
|
||||
switch (ch->sb) {
|
||||
case BRCMU_CHAN_SB_LL:
|
||||
ch->chnum -= CH_30MHZ_APART;
|
||||
ch->control_ch_num -= CH_30MHZ_APART;
|
||||
break;
|
||||
case BRCMU_CHAN_SB_LU:
|
||||
ch->chnum -= CH_10MHZ_APART;
|
||||
ch->control_ch_num -= CH_10MHZ_APART;
|
||||
break;
|
||||
case BRCMU_CHAN_SB_UL:
|
||||
ch->chnum += CH_10MHZ_APART;
|
||||
ch->control_ch_num += CH_10MHZ_APART;
|
||||
break;
|
||||
case BRCMU_CHAN_SB_UU:
|
||||
ch->chnum += CH_30MHZ_APART;
|
||||
ch->control_ch_num += CH_30MHZ_APART;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
#define BRCM_CC_4339_CHIP_ID 0x4339
|
||||
#define BRCM_CC_43430_CHIP_ID 43430
|
||||
#define BRCM_CC_4345_CHIP_ID 0x4345
|
||||
#define BRCM_CC_43465_CHIP_ID 43465
|
||||
#define BRCM_CC_4350_CHIP_ID 0x4350
|
||||
#define BRCM_CC_43525_CHIP_ID 43525
|
||||
#define BRCM_CC_4354_CHIP_ID 0x4354
|
||||
#define BRCM_CC_4356_CHIP_ID 0x4356
|
||||
#define BRCM_CC_43566_CHIP_ID 43566
|
||||
|
|
|
@ -125,14 +125,36 @@ enum brcmu_chan_sb {
|
|||
BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmu_chan - stores channel formats
|
||||
*
|
||||
* This structure can be used with functions translating chanspec into generic
|
||||
* channel info and the other way.
|
||||
*
|
||||
* @chspec: firmware specific format
|
||||
* @chnum: center channel number
|
||||
* @control_ch_num: control channel number
|
||||
* @band: frequency band
|
||||
* @bw: channel width
|
||||
* @sb: control sideband (location of control channel against the center one)
|
||||
*/
|
||||
struct brcmu_chan {
|
||||
u16 chspec;
|
||||
u8 chnum;
|
||||
u8 control_ch_num;
|
||||
u8 band;
|
||||
enum brcmu_chan_bw bw;
|
||||
enum brcmu_chan_sb sb;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmu_d11inf - provides functions translating channel format
|
||||
*
|
||||
* @io_type: determines version of channel format used by firmware
|
||||
* @encchspec: encodes channel info into a chanspec, requires center channel
|
||||
* number, ignores control one
|
||||
* @decchspec: decodes chanspec into generic info
|
||||
*/
|
||||
struct brcmu_d11inf {
|
||||
u8 io_type;
|
||||
|
||||
|
|
|
@ -1019,12 +1019,13 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
|
|||
int txq_id;
|
||||
|
||||
/* Tx queues */
|
||||
if (il->txq)
|
||||
if (il->txq) {
|
||||
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
|
||||
if (txq_id == IL39_CMD_QUEUE_NUM)
|
||||
il_cmd_queue_free(il);
|
||||
else
|
||||
il_tx_queue_free(il, txq_id);
|
||||
}
|
||||
|
||||
/* free tx queue structure */
|
||||
il_free_txq_mem(il);
|
||||
|
|
|
@ -1228,7 +1228,7 @@ static int if_sdio_probe(struct sdio_func *func,
|
|||
}
|
||||
|
||||
spin_lock_init(&card->lock);
|
||||
card->workqueue = create_workqueue("libertas_sdio");
|
||||
card->workqueue = alloc_workqueue("libertas_sdio", WQ_MEM_RECLAIM, 0);
|
||||
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
|
||||
init_waitqueue_head(&card->pwron_waitq);
|
||||
|
||||
|
@ -1326,7 +1326,6 @@ static void if_sdio_remove(struct sdio_func *func)
|
|||
lbs_stop_card(card->priv);
|
||||
lbs_remove_card(card->priv);
|
||||
|
||||
flush_workqueue(card->workqueue);
|
||||
destroy_workqueue(card->workqueue);
|
||||
|
||||
while (card->packets) {
|
||||
|
|
|
@ -1180,7 +1180,7 @@ static int if_spi_probe(struct spi_device *spi)
|
|||
priv->fw_ready = 1;
|
||||
|
||||
/* Initialize interrupt handling stuff. */
|
||||
card->workqueue = create_workqueue("libertas_spi");
|
||||
card->workqueue = alloc_workqueue("libertas_spi", WQ_MEM_RECLAIM, 0);
|
||||
INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
|
||||
INIT_WORK(&card->resume_work, if_spi_resume_worker);
|
||||
|
||||
|
@ -1208,7 +1208,6 @@ static int if_spi_probe(struct spi_device *spi)
|
|||
release_irq:
|
||||
free_irq(spi->irq, card);
|
||||
terminate_workqueue:
|
||||
flush_workqueue(card->workqueue);
|
||||
destroy_workqueue(card->workqueue);
|
||||
lbs_remove_card(priv); /* will call free_netdev */
|
||||
free_card:
|
||||
|
@ -1235,7 +1234,6 @@ static int libertas_spi_remove(struct spi_device *spi)
|
|||
lbs_remove_card(priv); /* will call free_netdev */
|
||||
|
||||
free_irq(spi->irq, card);
|
||||
flush_workqueue(card->workqueue);
|
||||
destroy_workqueue(card->workqueue);
|
||||
if (card->pdata->teardown)
|
||||
card->pdata->teardown(spi);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/module.h>
|
||||
#include "libertas_tf.h"
|
||||
|
||||
#define DRIVER_RELEASE_VERSION "004.p0"
|
||||
/* thinfirm version: 5.132.X.pX */
|
||||
#define LBTF_FW_VER_MIN 0x05840300
|
||||
#define LBTF_FW_VER_MAX 0x0584ffff
|
||||
|
@ -27,12 +26,6 @@ unsigned int lbtf_debug;
|
|||
EXPORT_SYMBOL_GPL(lbtf_debug);
|
||||
module_param_named(libertas_tf_debug, lbtf_debug, int, 0644);
|
||||
|
||||
static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION
|
||||
#ifdef DEBUG
|
||||
"-dbg"
|
||||
#endif
|
||||
"";
|
||||
|
||||
struct workqueue_struct *lbtf_wq;
|
||||
|
||||
static const struct ieee80211_channel lbtf_channels[] = {
|
||||
|
|
|
@ -184,7 +184,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
|||
|
||||
tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
|
||||
skb_aggr = mwifiex_alloc_dma_align_buf(adapter->tx_buf_size,
|
||||
GFP_ATOMIC | GFP_DMA);
|
||||
GFP_ATOMIC);
|
||||
if (!skb_aggr) {
|
||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||
ra_list_flags);
|
||||
|
|
|
@ -788,3 +788,4 @@ poll_fw:
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mwifiex_dnld_fw);
|
||||
|
|
|
@ -1281,7 +1281,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
|||
if (result) {
|
||||
mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n");
|
||||
if (priv->media_connected)
|
||||
mwifiex_reset_connect_state(priv, result);
|
||||
mwifiex_reset_connect_state(priv, result, true);
|
||||
|
||||
memset(&priv->curr_bss_params.bss_descriptor,
|
||||
0x00, sizeof(struct mwifiex_bssdescriptor));
|
||||
|
|
|
@ -526,10 +526,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
|||
fw.fw_buf = (u8 *) adapter->firmware->data;
|
||||
fw.fw_len = adapter->firmware->size;
|
||||
|
||||
if (adapter->if_ops.dnld_fw)
|
||||
if (adapter->if_ops.dnld_fw) {
|
||||
ret = adapter->if_ops.dnld_fw(adapter, &fw);
|
||||
else
|
||||
} else {
|
||||
ret = mwifiex_dnld_fw(adapter, &fw);
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
goto err_dnld_fw;
|
||||
|
||||
|
|
|
@ -1128,7 +1128,8 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
|||
struct mwifiex_bssdescriptor *bss_desc);
|
||||
int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp);
|
||||
void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
|
||||
void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason,
|
||||
bool from_ap);
|
||||
u8 mwifiex_band_to_radio_type(u8 band);
|
||||
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
|
||||
void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter);
|
||||
|
|
|
@ -507,7 +507,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
|
|||
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
|
||||
/* Allocate skb here so that firmware can DMA data from it */
|
||||
skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
GFP_KERNEL);
|
||||
if (!skb) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"Unable to allocate skb for RX ring.\n");
|
||||
|
@ -1319,7 +1319,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
|
|||
}
|
||||
|
||||
skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
GFP_KERNEL);
|
||||
if (!skb_tmp) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"Unable to allocate skb.\n");
|
||||
|
@ -2804,7 +2804,7 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
|
|||
}
|
||||
|
||||
/*
|
||||
* This function get firmare name for downloading by revision id
|
||||
* This function gets the firmware name for downloading by revision id
|
||||
*
|
||||
* Read revision id register to get revision id
|
||||
*/
|
||||
|
@ -2901,10 +2901,11 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
|
|||
{
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
const struct mwifiex_pcie_card_reg *reg;
|
||||
struct pci_dev *pdev = card->dev;
|
||||
struct pci_dev *pdev;
|
||||
int i;
|
||||
|
||||
if (card) {
|
||||
pdev = card->dev;
|
||||
if (card->msix_enable) {
|
||||
for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
|
||||
synchronize_irq(card->msix_entries[i].vector);
|
||||
|
|
|
@ -102,10 +102,9 @@ static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card)
|
|||
struct mwifiex_plt_wake_cfg *cfg;
|
||||
int ret;
|
||||
|
||||
if (!dev->of_node ||
|
||||
!of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) {
|
||||
dev_err(dev, "sdio platform data not available\n");
|
||||
return -1;
|
||||
if (!of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) {
|
||||
dev_err(dev, "required compatible string missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
card->plt_of_node = dev->of_node;
|
||||
|
@ -115,7 +114,7 @@ static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card)
|
|||
if (cfg && card->plt_of_node) {
|
||||
cfg->irq_wifi = irq_of_parse_and_map(card->plt_of_node, 0);
|
||||
if (!cfg->irq_wifi) {
|
||||
dev_err(dev,
|
||||
dev_dbg(dev,
|
||||
"fail to parse irq_wifi from device tree\n");
|
||||
} else {
|
||||
ret = devm_request_irq(dev, cfg->irq_wifi,
|
||||
|
@ -183,24 +182,35 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
|
|||
sdio_release_host(func);
|
||||
|
||||
if (ret) {
|
||||
pr_err("%s: failed to enable function\n", __func__);
|
||||
kfree(card);
|
||||
return -EIO;
|
||||
dev_err(&func->dev, "failed to enable function\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
/* device tree node parsing and platform specific configuration*/
|
||||
mwifiex_sdio_probe_of(&func->dev, card);
|
||||
|
||||
if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops,
|
||||
MWIFIEX_SDIO)) {
|
||||
pr_err("%s: add card failed\n", __func__);
|
||||
kfree(card);
|
||||
sdio_claim_host(func);
|
||||
ret = sdio_disable_func(func);
|
||||
sdio_release_host(func);
|
||||
ret = -1;
|
||||
if (func->dev.of_node) {
|
||||
ret = mwifiex_sdio_probe_of(&func->dev, card);
|
||||
if (ret) {
|
||||
dev_err(&func->dev, "SDIO dt node parse failed\n");
|
||||
goto err_disable;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops,
|
||||
MWIFIEX_SDIO);
|
||||
if (ret) {
|
||||
dev_err(&func->dev, "add card failed\n");
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
sdio_claim_host(func);
|
||||
sdio_disable_func(func);
|
||||
sdio_release_host(func);
|
||||
err_free:
|
||||
kfree(card);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -544,6 +554,19 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
|
|||
return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0);
|
||||
}
|
||||
|
||||
static int mwifiex_sdio_dnld_fw(struct mwifiex_adapter *adapter,
|
||||
struct mwifiex_fw_image *fw)
|
||||
{
|
||||
struct sdio_mmc_card *card = adapter->card;
|
||||
int ret;
|
||||
|
||||
sdio_claim_host(card->func);
|
||||
ret = mwifiex_dnld_fw(adapter, fw);
|
||||
sdio_release_host(card->func);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to initialize IO ports for the
|
||||
* chipsets supporting SDIO new mode eg SD8897.
|
||||
|
@ -1492,7 +1515,7 @@ rx_curr_single:
|
|||
mwifiex_dbg(adapter, INFO, "info: RX: port: %d, rx_len: %d\n",
|
||||
port, rx_len);
|
||||
|
||||
skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
|
||||
skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"single skb allocated fail,\t"
|
||||
|
@ -1597,7 +1620,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
|||
rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
|
||||
mwifiex_dbg(adapter, INFO, "info: rx_len = %d\n", rx_len);
|
||||
|
||||
skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
|
||||
skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -1;
|
||||
|
||||
|
@ -2732,6 +2755,7 @@ static struct mwifiex_if_ops sdio_ops = {
|
|||
.cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
|
||||
.cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
|
||||
.event_complete = mwifiex_sdio_event_complete,
|
||||
.dnld_fw = mwifiex_sdio_dnld_fw,
|
||||
.card_reset = mwifiex_sdio_card_reset,
|
||||
.reg_dump = mwifiex_sdio_reg_dump,
|
||||
.device_dump = mwifiex_sdio_device_dump,
|
||||
|
|
|
@ -553,7 +553,8 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
|
|||
if (!memcmp(resp->params.deauth.mac_addr,
|
||||
&priv->curr_bss_params.bss_descriptor.mac_address,
|
||||
sizeof(resp->params.deauth.mac_addr)))
|
||||
mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
|
||||
mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING,
|
||||
false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -566,7 +567,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
|
|||
static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
|
||||
mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
* - Erases current SSID and BSSID information
|
||||
* - Sends a disconnect event to upper layers/applications.
|
||||
*/
|
||||
void
|
||||
mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
|
||||
void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
|
||||
bool from_ap)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
|
||||
|
@ -140,7 +140,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
|
|||
if (priv->bss_mode == NL80211_IFTYPE_STATION ||
|
||||
priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
|
||||
cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
|
||||
false, GFP_KERNEL);
|
||||
!from_ap, GFP_KERNEL);
|
||||
}
|
||||
eth_zero_addr(priv->cfg_bssid);
|
||||
|
||||
|
@ -574,7 +574,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
|||
if (priv->media_connected) {
|
||||
reason_code =
|
||||
le16_to_cpu(*(__le16 *)adapter->event_body);
|
||||
mwifiex_reset_connect_state(priv, reason_code);
|
||||
mwifiex_reset_connect_state(priv, reason_code, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -589,7 +589,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
|||
if (priv->media_connected) {
|
||||
reason_code =
|
||||
le16_to_cpu(*(__le16 *)adapter->event_body);
|
||||
mwifiex_reset_connect_state(priv, reason_code);
|
||||
mwifiex_reset_connect_state(priv, reason_code, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -599,7 +599,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
|||
if (priv->media_connected) {
|
||||
reason_code =
|
||||
le16_to_cpu(*(__le16 *)adapter->event_body);
|
||||
mwifiex_reset_connect_state(priv, reason_code);
|
||||
mwifiex_reset_connect_state(priv, reason_code, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv,
|
|||
int mwifiex_uap_recv_packet(struct mwifiex_private *priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = adapter;
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct mwifiex_sta_node *src_node;
|
||||
struct ethhdr *p_ethhdr;
|
||||
struct sk_buff *skb_uap;
|
||||
|
|
|
@ -1839,20 +1839,22 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
|
|||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
break;
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
} else {
|
||||
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"boot from neither eeprom nor efuse, check it !!");
|
||||
return;
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
|
|
@ -1680,21 +1680,28 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
break;
|
||||
|
||||
memcpy((void *)hwinfo,
|
||||
(void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
||||
|
|
|
@ -351,15 +351,21 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
|
|||
u8 hwinfo[HWSET_MAX_SIZE] = {0};
|
||||
u16 eeprom_id;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
memcpy((void *)hwinfo,
|
||||
(void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
break;
|
||||
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!\n");
|
||||
return;
|
||||
|
||||
default:
|
||||
pr_warn("rtl92cu: no efuse data\n\n");
|
||||
return;
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
|
||||
|
|
|
@ -1744,23 +1744,29 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
unsigned long flags;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags);
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
_rtl92de_efuse_update_chip_version(hw);
|
||||
spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
|
||||
memcpy((void *)hwinfo, (void *)&rtlefuse->efuse_map
|
||||
[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
break;
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!\n");
|
||||
return;
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
||||
|
|
|
@ -2102,20 +2102,22 @@ static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw)
|
|||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
break;
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
} else {
|
||||
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"boot from neither eeprom nor efuse, check it !!");
|
||||
return;
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
|
|
@ -2414,19 +2414,10 @@ static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw,
|
|||
static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
|
||||
bool is_patha_on, bool is2t)
|
||||
{
|
||||
u32 pathon;
|
||||
u32 i;
|
||||
|
||||
pathon = is_patha_on ? 0x0fc01616 : 0x0fc01616;
|
||||
if (!is2t) {
|
||||
pathon = 0x0fc01616;
|
||||
rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0fc01616);
|
||||
} else {
|
||||
rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
|
||||
}
|
||||
|
||||
for (i = 1; i < IQK_ADDA_REG_NUM; i++)
|
||||
rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
|
||||
for (i = 0; i < IQK_ADDA_REG_NUM; i++)
|
||||
rtl_set_bbreg(hw, addareg[i], MASKDWORD, 0x0fc01616);
|
||||
}
|
||||
|
||||
static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw,
|
||||
|
|
|
@ -1673,23 +1673,31 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u16 eeprom_id;
|
||||
u8 tempval;
|
||||
u8 hwinfo[HWSET_MAX_SIZE_92S];
|
||||
u8 rf_path, index;
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
break;
|
||||
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!\n");
|
||||
} else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
return;
|
||||
|
||||
memcpy((void *)hwinfo, (void *)
|
||||
&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE_92S);
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE_92S);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
|
||||
hwinfo, HWSET_MAX_SIZE_92S);
|
||||
|
||||
|
|
|
@ -1630,6 +1630,7 @@ static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw,
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
@ -1638,15 +1639,19 @@ static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw,
|
|||
/* need add */
|
||||
return;
|
||||
}
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
|
|
@ -2026,6 +2026,7 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
@ -2055,15 +2056,22 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
|
|||
/* needs to be added */
|
||||
return;
|
||||
}
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
break;
|
||||
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
return;
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
||||
|
|
|
@ -1019,7 +1019,7 @@ static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u8 index = (channel - 1);
|
||||
u8 txpower;
|
||||
u8 txpower = 0;
|
||||
u8 power_diff_byrate = 0;
|
||||
|
||||
if (channel > 14 || channel < 1) {
|
||||
|
|
|
@ -3101,6 +3101,7 @@ static void _rtl8821ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_
|
|||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
|
||||
u16 i, usvalue;
|
||||
u8 hwinfo[HWSET_MAX_SIZE];
|
||||
u16 eeprom_id;
|
||||
|
@ -3109,14 +3110,20 @@ static void _rtl8821ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_
|
|||
;/* need add */
|
||||
}
|
||||
|
||||
if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
|
||||
switch (rtlefuse->epromtype) {
|
||||
case EEPROM_BOOT_EFUSE:
|
||||
rtl_efuse_shadow_map_update(hw);
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
|
||||
HWSET_MAX_SIZE);
|
||||
} else if (rtlefuse->epromtype == EEPROM_93C46) {
|
||||
break;
|
||||
|
||||
case EEPROM_93C46:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"RTL819X Not boot from eeprom, check it !!");
|
||||
return;
|
||||
|
||||
default:
|
||||
dev_warn(dev, "no efuse data\n");
|
||||
}
|
||||
memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n",
|
||||
hwinfo, HWSET_MAX_SIZE);
|
||||
|
|
|
@ -398,7 +398,7 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
|
|||
return -ENOLINK;
|
||||
|
||||
msg_len -= pad_bytes;
|
||||
if ((msg_len <= 0) || (!msg)) {
|
||||
if (msg_len <= 0) {
|
||||
rsi_dbg(MGMT_RX_ZONE,
|
||||
"%s: Invalid rx msg of len = %d\n",
|
||||
__func__, msg_len);
|
||||
|
|
|
@ -378,8 +378,7 @@ static int wl3501_esbq_exec(struct wl3501_card *this, void *sig, int sig_size)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
|
||||
void *bf, int size)
|
||||
static int wl3501_request_mib(struct wl3501_card *this, u8 index, void *bf)
|
||||
{
|
||||
struct wl3501_get_req sig = {
|
||||
.sig_id = WL3501_SIG_GET_REQ,
|
||||
|
@ -395,20 +394,32 @@ static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
|
|||
wl3501_set_to_wla(this, ptr, &sig, sizeof(sig));
|
||||
wl3501_esbq_req(this, &ptr);
|
||||
this->sig_get_confirm.mib_status = 255;
|
||||
spin_unlock_irqrestore(&this->lock, flags);
|
||||
rc = wait_event_interruptible(this->wait,
|
||||
this->sig_get_confirm.mib_status != 255);
|
||||
if (!rc)
|
||||
memcpy(bf, this->sig_get_confirm.mib_value,
|
||||
size);
|
||||
goto out;
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&this->lock, flags);
|
||||
out:
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
|
||||
void *bf, int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = wl3501_request_mib(this, index, bf);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = wait_event_interruptible(this->wait,
|
||||
this->sig_get_confirm.mib_status != 255);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memcpy(bf, this->sig_get_confirm.mib_value, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl3501_pwr_mgmt(struct wl3501_card *this, int suspend)
|
||||
{
|
||||
struct wl3501_pwr_mgmt_req sig = {
|
||||
|
|
Loading…
Reference in New Issue