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:
David S. Miller 2016-06-23 15:40:31 -04:00
commit dc14341ed6
83 changed files with 1257 additions and 1358 deletions

View File

@ -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/

View File

@ -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",

View File

@ -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");

View File

@ -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

View File

@ -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:

View File

@ -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_ */

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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);

View 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.

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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 {

View File

@ -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;

View File

@ -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 */

View File

@ -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 ||

View File

@ -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,

View File

@ -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,

View File

@ -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.

View File

@ -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 = {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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.,

View File

@ -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)

View File

@ -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,
};
/**

View File

@ -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

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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,
};

View File

@ -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_ */

View File

@ -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 */

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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),

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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[] = {

View File

@ -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);

View File

@ -788,3 +788,4 @@ poll_fw:
return ret;
}
EXPORT_SYMBOL_GPL(mwifiex_dnld_fw);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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]));

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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 = {