Merge tag 'wireless-drivers-next-for-davem-2017-04-21' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for 4.12 Quite a lot of patches for rtlwifi and iwlwifi this time, but changes also for other active wireless drivers. Major changes: ath9k * add support for Dell Wireless 1601 PCI device * add debugfs file to manually override noise floor ath10k * bump up FW API to 6 for a new QCA6174 firmware branch wil6210 * support 8 kB RX buffers iwlwifi * work to support A000 devices continues * add support for FW API 30 * add Geographical and Dynamic Specific Absorption Rate (SAR) support * support a few new PCI device IDs rtlwifi * work on adding Bluetooth coexistance support, not finished yet ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -2545,9 +2545,11 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
|
||||
priv->random_mac[i] |= get_random_int() &
|
||||
~(request->mac_addr_mask[i]);
|
||||
}
|
||||
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
|
||||
} else {
|
||||
eth_zero_addr(priv->random_mac);
|
||||
}
|
||||
|
||||
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
|
||||
user_scan_cfg->num_ssids = request->n_ssids;
|
||||
user_scan_cfg->ssid_list = request->ssids;
|
||||
|
||||
|
@@ -43,6 +43,24 @@ struct tx_packet_hdr {
|
||||
struct rfc_1042_hdr rfc1042_hdr;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_fw_header {
|
||||
__le32 dnld_cmd;
|
||||
__le32 base_addr;
|
||||
__le32 data_length;
|
||||
__le32 crc;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_fw_data {
|
||||
struct mwifiex_fw_header header;
|
||||
__le32 seq_num;
|
||||
u8 data[1];
|
||||
} __packed;
|
||||
|
||||
#define MWIFIEX_FW_DNLD_CMD_1 0x1
|
||||
#define MWIFIEX_FW_DNLD_CMD_5 0x5
|
||||
#define MWIFIEX_FW_DNLD_CMD_6 0x6
|
||||
#define MWIFIEX_FW_DNLD_CMD_7 0x7
|
||||
|
||||
#define B_SUPPORTED_RATES 5
|
||||
#define G_SUPPORTED_RATES 9
|
||||
#define BG_SUPPORTED_RATES 13
|
||||
|
@@ -149,7 +149,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
|
||||
|
||||
kfree(adapter->regd);
|
||||
|
||||
vfree(adapter->chan_stats);
|
||||
kfree(adapter);
|
||||
return 0;
|
||||
}
|
||||
@@ -632,6 +631,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
||||
goto done;
|
||||
|
||||
err_add_intf:
|
||||
vfree(adapter->chan_stats);
|
||||
wiphy_unregister(adapter->wiphy);
|
||||
wiphy_free(adapter->wiphy);
|
||||
err_init_fw:
|
||||
@@ -1416,6 +1416,7 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
|
||||
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
vfree(adapter->chan_stats);
|
||||
|
||||
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
|
||||
exit_return:
|
||||
@@ -1440,6 +1441,7 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
|
||||
init_waitqueue_head(&adapter->init_wait_q);
|
||||
adapter->is_suspended = false;
|
||||
adapter->hs_activated = false;
|
||||
adapter->is_cmd_timedout = 0;
|
||||
init_waitqueue_head(&adapter->hs_activate_wait_q);
|
||||
init_waitqueue_head(&adapter->cmd_wait_q.wait);
|
||||
adapter->cmd_wait_q.status = 0;
|
||||
@@ -1513,11 +1515,9 @@ static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv;
|
||||
|
||||
if (adapter->irq_wakeup >= 0) {
|
||||
dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
|
||||
adapter->wake_by_wifi = true;
|
||||
disable_irq_nosync(irq);
|
||||
}
|
||||
dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
|
||||
adapter->wake_by_wifi = true;
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
/* Notify PM core we are wakeup source */
|
||||
pm_wakeup_event(adapter->dev, 0);
|
||||
@@ -1726,6 +1726,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter)
|
||||
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
vfree(adapter->chan_stats);
|
||||
|
||||
wiphy_unregister(adapter->wiphy);
|
||||
wiphy_free(adapter->wiphy);
|
||||
@@ -1754,7 +1755,7 @@ void _mwifiex_dbg(const struct mwifiex_adapter *adapter, int mask,
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
if (!adapter->dev || !(adapter->debug_mask & mask))
|
||||
if (!(adapter->debug_mask & mask))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
@@ -1762,7 +1763,10 @@ void _mwifiex_dbg(const struct mwifiex_adapter *adapter, int mask,
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
|
||||
dev_info(adapter->dev, "%pV", &vaf);
|
||||
if (adapter->dev)
|
||||
dev_info(adapter->dev, "%pV", &vaf);
|
||||
else
|
||||
pr_info("%pV", &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
@@ -371,6 +371,8 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
|
||||
*/
|
||||
mwifiex_shutdown_sw(adapter);
|
||||
adapter->surprise_removed = true;
|
||||
clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
|
||||
clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
|
||||
} else {
|
||||
/* Kernel stores and restores PCIe function context before and
|
||||
* after performing FLR respectively. Reconfigure the software
|
||||
@@ -1035,6 +1037,7 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
|
||||
if (card && card->cmd_buf) {
|
||||
mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
|
||||
PCI_DMA_TODEVICE);
|
||||
dev_kfree_skb_any(card->cmd_buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1601,6 +1604,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
return -1;
|
||||
|
||||
card->cmd_buf = skb;
|
||||
/*
|
||||
* Need to keep a reference, since core driver might free up this
|
||||
* buffer before we've unmapped it.
|
||||
*/
|
||||
skb_get(skb);
|
||||
|
||||
/* To send a command, the driver will:
|
||||
1. Write the 64bit physical address of the data buffer to
|
||||
@@ -1703,6 +1711,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
|
||||
if (card->cmd_buf) {
|
||||
mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
|
||||
PCI_DMA_TODEVICE);
|
||||
dev_kfree_skb_any(card->cmd_buf);
|
||||
card->cmd_buf = NULL;
|
||||
}
|
||||
|
||||
@@ -1956,6 +1965,94 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Combo firmware image is a combination of
|
||||
* (1) combo crc heaer, start with CMD5
|
||||
* (2) bluetooth image, start with CMD7, end with CMD6, data wrapped in CMD1.
|
||||
* (3) wifi image.
|
||||
*
|
||||
* This function bypass the header and bluetooth part, return
|
||||
* the offset of tail wifi-only part.
|
||||
*/
|
||||
|
||||
static int mwifiex_extract_wifi_fw(struct mwifiex_adapter *adapter,
|
||||
const void *firmware, u32 firmware_len) {
|
||||
const struct mwifiex_fw_data *fwdata;
|
||||
u32 offset = 0, data_len, dnld_cmd;
|
||||
int ret = 0;
|
||||
bool cmd7_before = false;
|
||||
|
||||
while (1) {
|
||||
/* Check for integer and buffer overflow */
|
||||
if (offset + sizeof(fwdata->header) < sizeof(fwdata->header) ||
|
||||
offset + sizeof(fwdata->header) >= firmware_len) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"extract wifi-only fw failure!\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
fwdata = firmware + offset;
|
||||
dnld_cmd = le32_to_cpu(fwdata->header.dnld_cmd);
|
||||
data_len = le32_to_cpu(fwdata->header.data_length);
|
||||
|
||||
/* Skip past header */
|
||||
offset += sizeof(fwdata->header);
|
||||
|
||||
switch (dnld_cmd) {
|
||||
case MWIFIEX_FW_DNLD_CMD_1:
|
||||
if (!cmd7_before) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"no cmd7 before cmd1!\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
if (offset + data_len < data_len) {
|
||||
mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
offset += data_len;
|
||||
break;
|
||||
case MWIFIEX_FW_DNLD_CMD_5:
|
||||
/* Check for integer overflow */
|
||||
if (offset + data_len < data_len) {
|
||||
mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
offset += data_len;
|
||||
break;
|
||||
case MWIFIEX_FW_DNLD_CMD_6:
|
||||
/* Check for integer overflow */
|
||||
if (offset + data_len < data_len) {
|
||||
mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
offset += data_len;
|
||||
if (offset >= firmware_len) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"extract wifi-only fw failure!\n");
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = offset;
|
||||
}
|
||||
goto done;
|
||||
case MWIFIEX_FW_DNLD_CMD_7:
|
||||
cmd7_before = true;
|
||||
break;
|
||||
default:
|
||||
mwifiex_dbg(adapter, ERROR, "unknown dnld_cmd %d\n",
|
||||
dnld_cmd);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function downloads the firmware to the card.
|
||||
*
|
||||
@@ -1971,7 +2068,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
u32 firmware_len = fw->fw_len;
|
||||
u32 offset = 0;
|
||||
struct sk_buff *skb;
|
||||
u32 txlen, tx_blocks = 0, tries, len;
|
||||
u32 txlen, tx_blocks = 0, tries, len, val;
|
||||
u32 block_retry_cnt = 0;
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
|
||||
@@ -1998,6 +2095,24 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_13_REG, &val);
|
||||
if (ret) {
|
||||
mwifiex_dbg(adapter, FATAL, "Failed to read scratch register 13\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* PCIE FLR case: extract wifi part from combo firmware*/
|
||||
if (val == MWIFIEX_PCIE_FLR_HAPPENS) {
|
||||
ret = mwifiex_extract_wifi_fw(adapter, firmware, firmware_len);
|
||||
if (ret < 0) {
|
||||
mwifiex_dbg(adapter, ERROR, "Failed to extract wifi fw\n");
|
||||
goto done;
|
||||
}
|
||||
offset = ret;
|
||||
mwifiex_dbg(adapter, MSG,
|
||||
"info: dnld wifi firmware from %d bytes\n", offset);
|
||||
}
|
||||
|
||||
/* Perform firmware data transfer */
|
||||
do {
|
||||
u32 ireg_intr = 0;
|
||||
@@ -2494,8 +2609,8 @@ mwifiex_pcie_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
|
||||
int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
|
||||
PCIE_SCRATCH_13_REG,
|
||||
PCIE_SCRATCH_14_REG};
|
||||
PCIE_SCRATCH_14_REG,
|
||||
PCIE_SCRATCH_15_REG};
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
@@ -3070,12 +3185,6 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
|
||||
struct pci_dev *pdev = card->dev;
|
||||
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
|
||||
|
||||
/* Bluetooth is not on pcie interface. Download Wifi only firmware
|
||||
* during pcie FLR, so that bluetooth part of firmware which is
|
||||
* already running doesn't get affected.
|
||||
*/
|
||||
strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME);
|
||||
|
||||
/* tx_buf_size might be changed to 3584 by firmware during
|
||||
* data transfer, we should reset it to default size.
|
||||
*/
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#define PCIE8897_B0_FW_NAME "mrvl/pcie8897_uapsta.bin"
|
||||
#define PCIEUART8997_FW_NAME_V4 "mrvl/pcieuart8997_combo_v4.bin"
|
||||
#define PCIEUSB8997_FW_NAME_V4 "mrvl/pcieusb8997_combo_v4.bin"
|
||||
#define PCIE8997_DEFAULT_WIFIFW_NAME "mrvl/pcie8997_wlan_v4.bin"
|
||||
|
||||
#define PCIE_VENDOR_ID_MARVELL (0x11ab)
|
||||
#define PCIE_VENDOR_ID_V2_MARVELL (0x1b4b)
|
||||
@@ -77,8 +76,9 @@
|
||||
#define PCIE_SCRATCH_10_REG 0xCE8
|
||||
#define PCIE_SCRATCH_11_REG 0xCEC
|
||||
#define PCIE_SCRATCH_12_REG 0xCF0
|
||||
#define PCIE_SCRATCH_13_REG 0xCF8
|
||||
#define PCIE_SCRATCH_14_REG 0xCFC
|
||||
#define PCIE_SCRATCH_13_REG 0xCF4
|
||||
#define PCIE_SCRATCH_14_REG 0xCF8
|
||||
#define PCIE_SCRATCH_15_REG 0xCFC
|
||||
#define PCIE_RD_DATA_PTR_Q0_Q1 0xC08C
|
||||
#define PCIE_WR_DATA_PTR_Q0_Q1 0xC05C
|
||||
|
||||
@@ -119,6 +119,8 @@
|
||||
#define MWIFIEX_SLEEP_COOKIE_SIZE 4
|
||||
#define MWIFIEX_MAX_DELAY_COUNT 100
|
||||
|
||||
#define MWIFIEX_PCIE_FLR_HAPPENS 0xFEDCBABA
|
||||
|
||||
struct mwifiex_pcie_card_reg {
|
||||
u16 cmd_addr_lo;
|
||||
u16 cmd_addr_hi;
|
||||
@@ -217,8 +219,8 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = {
|
||||
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
|
||||
.pfu_enabled = 1,
|
||||
.sleep_cookie = 0,
|
||||
.fw_dump_ctrl = 0xcf4,
|
||||
.fw_dump_start = 0xcf8,
|
||||
.fw_dump_ctrl = PCIE_SCRATCH_13_REG,
|
||||
.fw_dump_start = PCIE_SCRATCH_14_REG,
|
||||
.fw_dump_end = 0xcff,
|
||||
.fw_dump_host_ready = 0xee,
|
||||
.fw_dump_read_done = 0xfe,
|
||||
@@ -254,8 +256,8 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8997 = {
|
||||
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
|
||||
.pfu_enabled = 1,
|
||||
.sleep_cookie = 0,
|
||||
.fw_dump_ctrl = 0xcf4,
|
||||
.fw_dump_start = 0xcf8,
|
||||
.fw_dump_ctrl = PCIE_SCRATCH_13_REG,
|
||||
.fw_dump_start = PCIE_SCRATCH_14_REG,
|
||||
.fw_dump_end = 0xcff,
|
||||
.fw_dump_host_ready = 0xcc,
|
||||
.fw_dump_read_done = 0xdd,
|
||||
|
@@ -1380,7 +1380,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
}
|
||||
|
||||
if (card->mpa_rx.pkt_cnt == 1)
|
||||
mport = adapter->ioport + port;
|
||||
mport = adapter->ioport + card->mpa_rx.start_port;
|
||||
|
||||
if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
|
||||
card->mpa_rx.buf_len, mport, 1))
|
||||
@@ -1813,7 +1813,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
}
|
||||
|
||||
if (card->mpa_tx.pkt_cnt == 1)
|
||||
mport = adapter->ioport + port;
|
||||
mport = adapter->ioport + card->mpa_tx.start_port;
|
||||
|
||||
ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
|
||||
card->mpa_tx.buf_len, mport);
|
||||
|
Reference in New Issue
Block a user