diff options
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/Kconfig | 25 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/carl9170.h | 14 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/cmd.c | 14 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/debug.c | 61 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/fw.c | 28 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/fwcmd.h | 18 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/fwdesc.h | 22 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/hw.h | 75 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/led.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/mac.c | 20 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 203 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/phy.c | 23 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/rx.c | 41 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/tx.c | 57 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/usb.c | 159 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/version.h | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/wlan.h | 24 |
18 files changed, 407 insertions, 387 deletions
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig index 1a796e5f69ec..ba9bea79381c 100644 --- a/drivers/net/wireless/ath/carl9170/Kconfig +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only config CARL9170 tristate "Linux Community AR9170 802.11n USB support" depends on USB && MAC80211 @@ -5,25 +6,21 @@ 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: - <http://wireless.kernel.org/en/users/Drivers/carl9170> + It needs a special firmware (carl9170-1.fw), which can be downloaded + from our wiki here: + <https://wireless.wiki.kernel.org/en/users/Drivers/carl9170> If you choose to build a module, it'll be called carl9170. config CARL9170_LEDS bool "SoftLED Support" - depends on CARL9170 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS default y + depends on CARL9170 + depends on MAC80211_LEDS help - This option is necessary, if you want your device' LEDs to blink + This option is necessary, if you want your device's LEDs to blink. Say Y, unless you need the LEDs for firmware debugging. @@ -42,9 +39,9 @@ config CARL9170_WPC default y config CARL9170_HWRNG - bool "Random number generator" - depends on CARL9170 && (HW_RANDOM = y || HW_RANDOM = CARL9170) - default n + bool "Random number generator" + depends on CARL9170 && (HW_RANDOM = y || HW_RANDOM = CARL9170) + default n help Provides a hardware random number generator to the kernel. diff --git a/drivers/net/wireless/ath/carl9170/Makefile b/drivers/net/wireless/ath/carl9170/Makefile index f64ed76af8ad..1a81868ce26d 100644 --- a/drivers/net/wireless/ath/carl9170/Makefile +++ b/drivers/net/wireless/ath/carl9170/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 8596aba34f96..ba29b4aebe9f 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -68,7 +68,10 @@ #define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) -static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; +static inline u8 ar9170_qmap(u8 idx) +{ + return 3 - idx; /* { 3, 2, 1, 0 } */ +} #define CARL9170_MAX_RX_BUFFER_SIZE 8192 @@ -256,6 +259,7 @@ struct ar9170 { atomic_t rx_work_urbs; atomic_t rx_pool_urbs; kernel_ulong_t features; + bool usb_ep_cmd_is_bulk; /* firmware settings */ struct completion fw_load_wait; @@ -454,7 +458,6 @@ struct ar9170 { # define CARL9170_HWRNG_CACHE_SIZE CARL9170_MAX_CMD_PAYLOAD_LEN struct { struct hwrng rng; - bool initialized; char name[30 + 1]; u16 cache[CARL9170_HWRNG_CACHE_SIZE / sizeof(u16)]; unsigned int cache_idx; @@ -627,14 +630,9 @@ static inline u16 carl9170_get_seq(struct sk_buff *skb) return get_seq_h(carl9170_get_hdr(skb)); } -static inline u16 get_tid_h(struct ieee80211_hdr *hdr) -{ - return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; -} - static inline u16 carl9170_get_tid(struct sk_buff *skb) { - return get_tid_h(carl9170_get_hdr(skb)); + return ieee80211_get_tid(carl9170_get_hdr(skb)); } static inline struct ieee80211_vif * diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index 39a63874b275..b8ed193c0195 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -120,7 +120,7 @@ struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, { struct carl9170_cmd *tmp; - tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC); + tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); if (tmp) { tmp->hdr.cmd = cmd; tmp->hdr.len = len; @@ -188,12 +188,12 @@ int carl9170_collect_tally(struct ar9170 *ar) if (ar->channel) { info = &ar->survey[ar->channel->hw_value]; - info->channel_time = ar->tally.active; - info->channel_time_busy = ar->tally.cca; - info->channel_time_tx = ar->tally.tx_time; - do_div(info->channel_time, 1000); - do_div(info->channel_time_busy, 1000); - do_div(info->channel_time_tx, 1000); + info->time = ar->tally.active; + info->time_busy = ar->tally.cca; + info->time_tx = ar->tally.tx_time; + do_div(info->time, 1000); + do_div(info->time_busy, 1000); + do_div(info->time_tx, 1000); } } return 0; diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 3d70cd277fd7..2d734567000a 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c @@ -37,7 +37,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/seq_file.h> @@ -46,7 +45,7 @@ #include "cmd.h" #define ADD(buf, off, max, fmt, args...) \ - off += snprintf(&buf[off], max - off, fmt, ##args); + off += scnprintf(&buf[off], max - off, fmt, ##args) struct carl9170_debugfs_fops { @@ -55,7 +54,6 @@ struct carl9170_debugfs_fops { char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize, ssize_t *len); ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size); - const struct file_operations fops; enum carl9170_device_state req_dev_state; }; @@ -63,7 +61,7 @@ struct carl9170_debugfs_fops { static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - struct carl9170_debugfs_fops *dfops; + const struct carl9170_debugfs_fops *dfops; struct ar9170 *ar; char *buf = NULL, *res_buf = NULL; ssize_t ret = 0; @@ -76,7 +74,7 @@ static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf, if (!ar) return -ENODEV; - dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->read) return -ENOSYS; @@ -113,7 +111,7 @@ out_free: static ssize_t carl9170_debugfs_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - struct carl9170_debugfs_fops *dfops; + const struct carl9170_debugfs_fops *dfops; struct ar9170 *ar; char *buf = NULL; int err = 0; @@ -128,7 +126,7 @@ static ssize_t carl9170_debugfs_write(struct file *file, if (!ar) return -ENODEV; - dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->write) return -ENOSYS; @@ -164,6 +162,11 @@ out_free: return err; } +static struct debugfs_short_fops debugfs_fops = { + .read = carl9170_debugfs_read, + .write = carl9170_debugfs_write, +}; + #define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ _attr, _dstate) \ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ @@ -172,12 +175,6 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ .write = _write, \ .attr = _attr, \ .req_dev_state = _dstate, \ - .fops = { \ - .open = simple_open, \ - .read = carl9170_debugfs_read, \ - .write = carl9170_debugfs_write, \ - .owner = THIS_MODULE \ - }, \ } #define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \ @@ -186,21 +183,21 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ #define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ - NULL, _read_bufsize, S_IRUSR) + NULL, _read_bufsize, 0400) #define DEBUGFS_DECLARE_WO_FILE(name) \ DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ - 0, S_IWUSR) + 0, 0200) #define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ carl9170_debugfs_##name ##_write, \ - _read_bufsize, S_IRUSR | S_IWUSR) + _read_bufsize, 0600) #define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ carl9170_debugfs_##name ##_write, \ - _read_bufsize, S_IRUSR | S_IWUSR, _dstate) + _read_bufsize, 0600, _dstate) #define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ @@ -215,14 +212,10 @@ DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf, size_t bufsize, ssize_t *len) { - ADD(buf, *len, bufsize, "jar: ["); - spin_lock_bh(&ar->mem_lock); - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - ar->mem_bitmap, ar->fw.mem_blocks); - - ADD(buf, *len, bufsize, "]\n"); + ADD(buf, *len, bufsize, "jar: [%*pb]\n", + ar->fw.mem_blocks, ar->mem_bitmap); ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n", bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks), @@ -317,17 +310,13 @@ static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf, cnt, iter->tid, iter->bsn, iter->snx, iter->hsn, iter->max, iter->state, iter->counter); - ADD(buf, *len, bufsize, "\tWindow: ["); - - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - iter->bitmap, CARL9170_BAW_BITS); + ADD(buf, *len, bufsize, "\tWindow: [%*pb,W]\n", + CARL9170_BAW_BITS, iter->bitmap); #define BM_STR_OFF(offset) \ ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \ (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1) - ADD(buf, *len, bufsize, ",W]\n"); - offset = BM_STR_OFF(0); ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T"); @@ -449,12 +438,8 @@ static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf, ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n", ar->vifs, ar->fw.vif_num); - ADD(buf, *len, bufsize, "VIF bitmap: ["); - - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - &ar->vif_bitmap, ar->fw.vif_num); - - ADD(buf, *len, bufsize, "]\n"); + ADD(buf, *len, bufsize, "VIF bitmap: [%*pb]\n", + ar->fw.vif_num, &ar->vif_bitmap); rcu_read_lock(); list_for_each_entry_rcu(iter, &ar->vif_list, list) { @@ -827,9 +812,9 @@ void carl9170_debugfs_register(struct ar9170 *ar) ar->hw->wiphy->debugfsdir); #define DEBUGFS_ADD(name) \ - debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \ - ar->debug_dir, ar, \ - &carl_debugfs_##name ## _ops.fops); + debugfs_create_file_aux(#name, carl_debugfs_##name ##_ops.attr, \ + ar->debug_dir, ar, &carl_debugfs_##name ## _ops, \ + &debugfs_fops) DEBUGFS_ADD(usb_tx_anch_urbs); DEBUGFS_ADD(usb_rx_pool_urbs); diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 47d5c2e910ad..419f5530f885 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Atheros CARL9170 driver * * firmware parser * * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * 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, see - * http://www.gnu.org/licenses/. */ #include <linux/kernel.h> @@ -28,7 +15,7 @@ #include "fwcmd.h" #include "version.h" -static const u8 otus_magic[4] = { OTUS_MAGIC }; +static const u8 otus_magic[4] __nonstring = { OTUS_MAGIC }; static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], const unsigned int len, const u8 compatible_revision) @@ -118,7 +105,7 @@ static void carl9170_fw_info(struct ar9170 *ar) CARL9170FW_GET_MONTH(fw_date), CARL9170FW_GET_DAY(fw_date)); - strlcpy(ar->hw->wiphy->fw_version, motd_desc->release, + strscpy(ar->hw->wiphy->fw_version, motd_desc->release, sizeof(ar->hw->wiphy->fw_version)); } } @@ -286,7 +273,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) } if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) - ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS; + ieee80211_hw_set(ar->hw, SUPPORTS_PS); if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) { dev_err(&ar->udev->dev, "firmware does not provide " @@ -310,8 +297,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (SUPP(CARL9170FW_RX_FILTER)) { ar->fw.rx_filter = true; ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | - FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS | - FIF_PROMISC_IN_BSS; + FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS; } if (SUPP(CARL9170FW_HW_COUNTERS)) @@ -352,9 +338,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (SUPP(CARL9170FW_WLANTX_CAB)) { - if_comb_types |= - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO); + if_comb_types |= BIT(NL80211_IFTYPE_AP); #ifdef CONFIG_MAC80211_MESH if_comb_types |= diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index 9111d4ffc1b3..e5bcc364f088 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -56,6 +56,7 @@ enum carl9170_cmd_oids { CARL9170_CMD_RX_FILTER = 0x07, CARL9170_CMD_WOL = 0x08, CARL9170_CMD_TALLY = 0x09, + CARL9170_CMD_WREGB = 0x0a, /* CAM */ CARL9170_CMD_EKEY = 0x10, @@ -117,10 +118,16 @@ struct carl9170_reg_list { } __packed; struct carl9170_write_reg { - struct { + DECLARE_FLEX_ARRAY(struct { __le32 addr; __le32 val; - } regs[0] __packed; + } __packed, regs); +} __packed; + +struct carl9170_write_reg_byte { + __le32 addr; + __le32 count; + u8 val[]; } __packed; #define CARL9170FW_PHY_HT_ENABLE 0x4 @@ -226,13 +233,14 @@ struct carl9170_cmd { struct carl9170_u32_list echo; struct carl9170_reg_list rreg; struct carl9170_write_reg wreg; + struct carl9170_write_reg_byte wregb; struct carl9170_rf_init rf_init; struct carl9170_psm psm; struct carl9170_wol_cmd wol; struct carl9170_bcn_ctrl_cmd bcn_ctrl; struct carl9170_rx_filter_cmd rx_filter; u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; - } __packed; + } __packed __aligned(4); } __packed __aligned(4); #define CARL9170_TX_STATUS_QUEUE 3 @@ -312,9 +320,9 @@ struct carl9170_rsp { struct carl9170_u32_list rreg_res; struct carl9170_u32_list echo; #ifdef __CARL9170FW__ - struct carl9170_tx_status tx_status[0]; + DECLARE_FLEX_ARRAY(struct carl9170_tx_status, tx_status); #endif /* __CARL9170FW__ */ - struct _carl9170_tx_status _tx_status[0]; + DECLARE_FLEX_ARRAY(struct _carl9170_tx_status, _tx_status); struct carl9170_gpio gpio; struct carl9170_tsf_rsp tsf; struct carl9170_psm psm; diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h index 66848d47c88e..10acb6ad30d0 100644 --- a/drivers/net/wireless/ath/carl9170/fwdesc.h +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -1,22 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Shared CARL9170 Header * * Firmware descriptor format * * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> - * - * 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. - * - * 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, see - * http://www.gnu.org/licenses/. */ #ifndef __CARL9170_SHARED_FWDESC_H @@ -81,6 +69,12 @@ enum carl9170fw_feature_list { /* Firmware will pass BA when BARs are queued */ CARL9170FW_RX_BA_FILTER, + /* Firmware has support to write a byte at a time */ + CARL9170FW_HAS_WREGB_CMD, + + /* Pattern generator */ + CARL9170FW_PATTERN_GENERATOR, + /* KEEP LAST */ __CARL9170FW_FEATURE_NUM }; @@ -155,7 +149,7 @@ struct carl9170fw_fix_entry { struct carl9170fw_fix_desc { struct carl9170fw_desc_head head; - struct carl9170fw_fix_entry data[0]; + struct carl9170fw_fix_entry data[]; } __packed; #define CARL9170FW_FIX_DESC_SIZE \ (sizeof(struct carl9170fw_fix_desc)) diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index 0db874abde50..555ad4975970 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -453,9 +453,74 @@ #define AR9170_MC_REG_BASE 0x1d1000 #define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) -#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) -#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) -#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) + +#define AR9170_SPI_REG_BASE (AR9170_MC_REG_BASE + 0x200) +#define AR9170_SPI_REG_CONTROL0 (AR9170_SPI_REG_BASE + 0x000) +#define AR9170_SPI_CONTROL0_BUSY BIT(0) +#define AR9170_SPI_CONTROL0_CMD_GO BIT(1) +#define AR9170_SPI_CONTROL0_PAGE_WR BIT(2) +#define AR9170_SPI_CONTROL0_SEQ_RD BIT(3) +#define AR9170_SPI_CONTROL0_CMD_ABORT BIT(4) +#define AR9170_SPI_CONTROL0_CMD_LEN_S 8 +#define AR9170_SPI_CONTROL0_CMD_LEN 0x00000f00 +#define AR9170_SPI_CONTROL0_RD_LEN_S 12 +#define AR9170_SPI_CONTROL0_RD_LEN 0x00007000 + +#define AR9170_SPI_REG_CONTROL1 (AR9170_SPI_REG_BASE + 0x004) +#define AR9170_SPI_CONTROL1_SCK_RATE BIT(0) +#define AR9170_SPI_CONTROL1_DRIVE_SDO BIT(1) +#define AR9170_SPI_CONTROL1_MODE_SEL_S 2 +#define AR9170_SPI_CONTROL1_MODE_SEL 0x000000c0 +#define AR9170_SPI_CONTROL1_WRITE_PROTECT BIT(4) + +#define AR9170_SPI_REG_COMMAND_PORT0 (AR9170_SPI_REG_BASE + 0x008) +#define AR9170_SPI_COMMAND_PORT0_CMD0_S 0 +#define AR9170_SPI_COMMAND_PORT0_CMD0 0x000000ff +#define AR9170_SPI_COMMAND_PORT0_CMD1_S 8 +#define AR9170_SPI_COMMAND_PORT0_CMD1 0x0000ff00 +#define AR9170_SPI_COMMAND_PORT0_CMD2_S 16 +#define AR9170_SPI_COMMAND_PORT0_CMD2 0x00ff0000 +#define AR9170_SPI_COMMAND_PORT0_CMD3_S 24 +#define AR9170_SPI_COMMAND_PORT0_CMD3 0xff000000 + +#define AR9170_SPI_REG_COMMAND_PORT1 (AR9170_SPI_REG_BASE + 0x00C) +#define AR9170_SPI_COMMAND_PORT1_CMD4_S 0 +#define AR9170_SPI_COMMAND_PORT1_CMD4 0x000000ff +#define AR9170_SPI_COMMAND_PORT1_CMD5_S 8 +#define AR9170_SPI_COMMAND_PORT1_CMD5 0x0000ff00 +#define AR9170_SPI_COMMAND_PORT1_CMD6_S 16 +#define AR9170_SPI_COMMAND_PORT1_CMD6 0x00ff0000 +#define AR9170_SPI_COMMAND_PORT1_CMD7_S 24 +#define AR9170_SPI_COMMAND_PORT1_CMD7 0xff000000 + +#define AR9170_SPI_REG_DATA_PORT (AR9170_SPI_REG_BASE + 0x010) +#define AR9170_SPI_REG_PAGE_WRITE_LEN (AR9170_SPI_REG_BASE + 0x014) + +#define AR9170_EEPROM_REG_BASE (AR9170_MC_REG_BASE + 0x400) +#define AR9170_EEPROM_REG_WP_MAGIC1 (AR9170_EEPROM_REG_BASE + 0x000) +#define AR9170_EEPROM_WP_MAGIC1 0x12345678 + +#define AR9170_EEPROM_REG_WP_MAGIC2 (AR9170_EEPROM_REG_BASE + 0x004) +#define AR9170_EEPROM_WP_MAGIC2 0x55aa00ff + +#define AR9170_EEPROM_REG_WP_MAGIC3 (AR9170_EEPROM_REG_BASE + 0x008) +#define AR9170_EEPROM_WP_MAGIC3 0x13579ace + +#define AR9170_EEPROM_REG_CLOCK_DIV (AR9170_EEPROM_REG_BASE + 0x00C) +#define AR9170_EEPROM_CLOCK_DIV_FAC_S 0 +#define AR9170_EEPROM_CLOCK_DIV_FAC 0x000001ff +#define AR9170_EEPROM_CLOCK_DIV_FAC_39KHZ 0xff +#define AR9170_EEPROM_CLOCK_DIV_FAC_78KHZ 0x7f +#define AR9170_EEPROM_CLOCK_DIV_FAC_312KHZ 0x1f +#define AR9170_EEPROM_CLOCK_DIV_FAC_10MHZ 0x0 +#define AR9170_EEPROM_CLOCK_DIV_SOFT_RST BIT(9) + +#define AR9170_EEPROM_REG_MODE (AR9170_EEPROM_REG_BASE + 0x010) +#define AR9170_EEPROM_MODE_EEPROM_SIZE_16K_PLUS BIT(31) + +#define AR9170_EEPROM_REG_WRITE_PROTECT (AR9170_EEPROM_REG_BASE + 0x014) +#define AR9170_EEPROM_WRITE_PROTECT_WP_STATUS BIT(0) +#define AR9170_EEPROM_WRITE_PROTECT_WP_SET BIT(8) /* Interrupt Controller */ #define AR9170_MAX_INT_SRC 9 @@ -589,11 +654,13 @@ #define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) #define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) +#define AR9170_USB_EP_IN_STALL 0x8 #define AR9170_USB_EP_IN_TOGGLE 0x10 #define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) #define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) +#define AR9170_USB_EP_OUT_STALL 0x8 #define AR9170_USB_EP_OUT_TOGGLE 0x10 #define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) @@ -784,7 +851,7 @@ struct ar9170_stream { __le16 length; __le16 tag; - u8 payload[0]; + u8 payload[]; } __packed __aligned(4); #define AR9170_STREAM_LEN 4 diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c index 78dadc797558..2c74425f5059 100644 --- a/drivers/net/wireless/ath/carl9170/led.c +++ b/drivers/net/wireless/ath/carl9170/led.c @@ -122,7 +122,7 @@ static void carl9170_led_set_brightness(struct led_classdev *led, } static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, - char *trigger) + const char *trigger) { int err; diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index a2f005703c04..20ceed0dd4be 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -36,7 +36,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "carl9170.h" #include "cmd.h" @@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) if (conf_is_ht40(&ar->hw->conf)) val = 0x010a; else { - if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) + if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) val = 0x105; else val = 0x104; @@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar) rts_rate = 0x1da; cts_rate = 0x10a; } else { - if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { + if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { /* 11 mbit CCK */ rts_rate = 033; cts_rate = 003; @@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar) return 0; } - if ((ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) || + if ((ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) || vif->bss_conf.use_short_slot) slottime = 9; @@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar) basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; rcu_read_unlock(); - if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) + if (ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ else mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ @@ -329,10 +329,6 @@ int carl9170_set_operating_mode(struct ar9170 *ar) /* iwlagn 802.11n STA Workaround */ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; break; - case NL80211_IFTYPE_WDS: - cam_mode |= AR9170_MAC_CAM_AP_WDS; - rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; - break; case NL80211_IFTYPE_STATION: cam_mode |= AR9170_MAC_CAM_STA; rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; @@ -512,14 +508,14 @@ int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) chains = AR9170_TX_PHY_TXCHAIN_1; switch (channel->band) { - case IEEE80211_BAND_2GHZ: + case NL80211_BAND_2GHZ: power = ar->power_2G_ofdm[0] & 0x3f; break; - case IEEE80211_BAND_5GHZ: + case NL80211_BAND_5GHZ: power = ar->power_5G_leg[0] & 0x3f; break; default: - BUG_ON(1); + BUG(); } power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 4a33c6e39ca2..a7a9345f3483 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -37,7 +37,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/etherdevice.h> @@ -49,11 +48,11 @@ #include "cmd.h" static bool modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); +module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); int modparam_noht; -module_param_named(noht, modparam_noht, int, S_IRUGO); +module_param_named(noht, modparam_noht, int, 0444); MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ @@ -308,8 +307,7 @@ static void carl9170_zap_queues(struct ar9170 *ar) for (i = 0; i < ar->hw->queues; i++) ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD; - for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++) - ar->mem_bitmap[i] = 0; + bitmap_zero(ar->mem_bitmap, ar->fw.mem_blocks); rcu_read_lock(); list_for_each_entry_rcu(cvif, &ar->vif_list, list) { @@ -441,7 +439,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar) cancel_work_sync(&ar->ampdu_work); } -static void carl9170_op_stop(struct ieee80211_hw *hw) +static void carl9170_op_stop(struct ieee80211_hw *hw, bool suspend) { struct ar9170 *ar = hw->priv; @@ -583,11 +581,10 @@ static int carl9170_init_interface(struct ar9170 *ar, ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && (vif->type != NL80211_IFTYPE_AP)); - /* While the driver supports HW offload in a single - * P2P client configuration, it doesn't support HW - * offload in the favourit, concurrent P2P GO+CLIENT - * configuration. Hence, HW offload will always be - * disabled for P2P. + /* The driver used to have P2P GO+CLIENT support, + * but since this was dropped and we don't know if + * there are any gremlins lurking in the shadows, + * so best we keep HW offload disabled for P2P. */ ar->disable_offload |= vif->p2p; @@ -640,18 +637,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_STATION) break; - /* P2P GO [master] use-case - * Because the P2P GO station is selected dynamically - * by all participating peers of a WIFI Direct network, - * the driver has be able to change the main interface - * operating mode on the fly. - */ - if (main_vif->p2p && vif->p2p && - vif->type == NL80211_IFTYPE_AP) { - old_main = main_vif; - break; - } - err = -EBUSY; rcu_read_unlock(); @@ -660,7 +645,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_AP: if ((vif->type == NL80211_IFTYPE_STATION) || - (vif->type == NL80211_IFTYPE_WDS) || (vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_MESH_POINT)) break; @@ -906,7 +890,7 @@ static void carl9170_stat_work(struct work_struct *work) round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK))); } -static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) +static int carl9170_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) { struct ar9170 *ar = hw->priv; int err = 0; @@ -1012,9 +996,8 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, if (multicast != ar->cur_mc_hash) WARN_ON(carl9170_update_multicast(ar, multicast)); - if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { - ar->sniffer_enabled = !!(*new_flags & - (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)); + if (changed_flags & FIF_OTHER_BSS) { + ar->sniffer_enabled = !!(*new_flags & FIF_OTHER_BSS); WARN_ON(carl9170_set_operating_mode(ar)); } @@ -1034,7 +1017,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, if (!(*new_flags & FIF_PSPOLL)) rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; - if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) { + if (!(*new_flags & FIF_OTHER_BSS)) { rx_filter |= CARL9170_RX_FILTER_OTHER_RA; rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; } @@ -1049,7 +1032,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, - u32 changed) + u64 changed) { struct ar9170 *ar = hw->priv; struct ath_common *common = &ar->common; @@ -1132,7 +1115,7 @@ static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ASSOC) { - ar->common.curaid = bss_conf->aid; + ar->common.curaid = vif->cfg.aid; err = carl9170_set_beacon_timers(ar); if (err) goto out; @@ -1323,8 +1306,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, atomic_set(&sta_info->pending_frames, 0); - if (sta->ht_cap.ht_supported) { - if (sta->ht_cap.ampdu_density > 6) { + if (sta->deflink.ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ampdu_density > 6) { /* * HW does support 16us AMPDU density. * No HT-Xmit for station. @@ -1336,7 +1319,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) RCU_INIT_POINTER(sta_info->agg[i], NULL); - sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); + sta_info->ampdu_max_len = 1 << (3 + sta->deflink.ht_cap.ampdu_factor); sta_info->ht_sta = true; } @@ -1352,7 +1335,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, unsigned int i; bool cleanup = false; - if (sta->ht_cap.ht_supported) { + if (sta->deflink.ht_cap.ht_supported) { sta_info->ht_sta = false; @@ -1382,20 +1365,16 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, } static int carl9170_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 queue, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *param) { struct ar9170 *ar = hw->priv; int ret; mutex_lock(&ar->mutex); - if (queue < ar->hw->queues) { - memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param)); - ret = carl9170_set_qos(ar); - } else { - ret = -EINVAL; - } - + memcpy(&ar->edcf[ar9170_qmap(queue)], param, sizeof(*param)); + ret = carl9170_set_qos(ar); mutex_unlock(&ar->mutex); return ret; } @@ -1415,10 +1394,12 @@ static void carl9170_ampdu_work(struct work_struct *work) static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, - u16 tid, u16 *ssn, u8 buf_size) + struct ieee80211_ampdu_params *params) { + struct ieee80211_sta *sta = params->sta; + enum ieee80211_ampdu_mlme_action action = params->action; + u16 tid = params->tid; + u16 *ssn = ¶ms->ssn; struct ar9170 *ar = hw->priv; struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; struct carl9170_sta_tid *tid_info; @@ -1431,18 +1412,10 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, if (!sta_info->ht_sta) return -EOPNOTSUPP; - rcu_read_lock(); - if (rcu_dereference(sta_info->agg[tid])) { - rcu_read_unlock(); - return -EBUSY; - } - tid_info = kzalloc(sizeof(struct carl9170_sta_tid), - GFP_ATOMIC); - if (!tid_info) { - rcu_read_unlock(); + GFP_KERNEL); + if (!tid_info) return -ENOMEM; - } tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); tid_info->state = CARL9170_TID_STATE_PROGRESS; @@ -1461,10 +1434,8 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); rcu_assign_pointer(sta_info->agg[tid], tid_info); spin_unlock_bh(&ar->tx_ampdu_list_lock); - rcu_read_unlock(); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: @@ -1524,7 +1495,7 @@ static int carl9170_register_wps_button(struct ar9170 *ar) if (!(ar->features & CARL9170_WPS_BUTTON)) return 0; - input = input_allocate_device(); + input = devm_input_allocate_device(&ar->udev->dev); if (!input) return -ENOMEM; @@ -1542,10 +1513,8 @@ static int carl9170_register_wps_button(struct ar9170 *ar) input_set_capability(input, EV_KEY, KEY_WPS_BUTTON); err = input_register_device(input); - if (err) { - input_free_device(input); + if (err) return err; - } ar->wps.pbc = input; return 0; @@ -1569,7 +1538,7 @@ static int carl9170_rng_get(struct ar9170 *ar) BUILD_BUG_ON(RB > CARL9170_MAX_CMD_PAYLOAD_LEN); - if (!IS_ACCEPTING_CMD(ar) || !ar->rng.initialized) + if (!IS_ACCEPTING_CMD(ar)) return -EAGAIN; count = ARRAY_SIZE(ar->rng.cache); @@ -1615,14 +1584,6 @@ static int carl9170_rng_read(struct hwrng *rng, u32 *data) return sizeof(u16); } -static void carl9170_unregister_hwrng(struct ar9170 *ar) -{ - if (ar->rng.initialized) { - hwrng_unregister(&ar->rng.rng); - ar->rng.initialized = false; - } -} - static int carl9170_register_hwrng(struct ar9170 *ar) { int err; @@ -1633,25 +1594,14 @@ static int carl9170_register_hwrng(struct ar9170 *ar) ar->rng.rng.data_read = carl9170_rng_read; ar->rng.rng.priv = (unsigned long)ar; - if (WARN_ON(ar->rng.initialized)) - return -EALREADY; - - err = hwrng_register(&ar->rng.rng); + err = devm_hwrng_register(&ar->udev->dev, &ar->rng.rng); if (err) { dev_err(&ar->udev->dev, "Failed to register the random " "number generator (%d)\n", err); return err; } - ar->rng.initialized = true; - - err = carl9170_rng_get(ar); - if (err) { - carl9170_unregister_hwrng(ar); - return err; - } - - return 0; + return carl9170_rng_get(ar); } #endif /* CONFIG_CARL9170_HWRNG */ @@ -1675,7 +1625,7 @@ static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, return err; } - for (b = 0; b < IEEE80211_NUM_BANDS; b++) { + for (b = 0; b < NUM_NL80211_BANDS; b++) { band = ar->hw->wiphy->bands[b]; if (!band) @@ -1700,15 +1650,17 @@ found: survey->filled |= SURVEY_INFO_IN_USE; if (ar->fw.hw_counters) { - survey->filled |= SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_TX; + survey->filled |= SURVEY_INFO_TIME | + SURVEY_INFO_TIME_BUSY | + SURVEY_INFO_TIME_TX; } return 0; } -static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) +static void carl9170_op_flush(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 queues, bool drop) { struct ar9170 *ar = hw->priv; unsigned int vid; @@ -1760,9 +1712,14 @@ static bool carl9170_tx_frames_pending(struct ieee80211_hw *hw) } static const struct ieee80211_ops carl9170_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, .start = carl9170_op_start, .stop = carl9170_op_stop, .tx = carl9170_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, .flush = carl9170_op_flush, .add_interface = carl9170_op_add_interface, .remove_interface = carl9170_op_remove_interface, @@ -1853,21 +1810,22 @@ void *carl9170_alloc(size_t priv_size) /* firmware decides which modes we support */ hw->wiphy->interface_modes = 0; - hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_MFP_CAPABLE | - IEEE80211_HW_REPORTS_TX_ACK_STATUS | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | - IEEE80211_HW_SUPPORTS_RC_TABLE | - IEEE80211_HW_SIGNAL_DBM; + ieee80211_hw_set(hw, RX_INCLUDES_FCS); + ieee80211_hw_set(hw, MFP_CAPABLE); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, PS_NULLFUNC_STACK); + ieee80211_hw_set(hw, NEED_DTIM_BEFORE_ASSOC); + ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); if (!modparam_noht) { /* * see the comment above, why we allow the user * to disable HT by a module parameter. */ - hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; + ieee80211_hw_set(hw, AMPDU_AGGREGATION); } hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe); @@ -1880,6 +1838,8 @@ void *carl9170_alloc(size_t priv_size) for (i = 0; i < ARRAY_SIZE(ar->noise); i++) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + return ar; err_nomem: @@ -1939,7 +1899,7 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) WARN_ON(!(tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)); - tx_params = (tx_streams - 1) << + tx_params |= (tx_streams - 1) << IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; @@ -1947,13 +1907,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) } if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = &carl9170_band_2GHz; chans += carl9170_band_2GHz.n_channels; bands++; } if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = &carl9170_band_5GHz; chans += carl9170_band_5GHz.n_channels; bands++; @@ -1962,23 +1922,12 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) if (!bands) return -EINVAL; - ar->survey = kzalloc(sizeof(struct survey_info) * chans, GFP_KERNEL); + ar->survey = devm_kcalloc(&ar->udev->dev, chans, + sizeof(struct survey_info), GFP_KERNEL); if (!ar->survey) return -ENOMEM; ar->num_channels = chans; - /* - * I measured this, a bandswitch takes roughly - * 135 ms and a frequency switch about 80. - * - * FIXME: measure these values again once EEPROM settings - * are used, that will influence them! - */ - if (bands == 2) - ar->hw->channel_change_time = 135 * 1000; - else - ar->hw->channel_change_time = 80 * 1000; - regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); /* second part of wiphy init */ @@ -2001,12 +1950,7 @@ int carl9170_register(struct ar9170 *ar) struct ath_regulatory *regulatory = &ar->common.regulatory; int err = 0, i; - if (WARN_ON(ar->mem_bitmap)) - return -EINVAL; - - ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) * - sizeof(unsigned long), GFP_KERNEL); - + ar->mem_bitmap = devm_bitmap_zalloc(&ar->udev->dev, ar->fw.mem_blocks, GFP_KERNEL); if (!ar->mem_bitmap) return -ENOMEM; @@ -2095,17 +2039,6 @@ void carl9170_unregister(struct ar9170 *ar) carl9170_debugfs_unregister(ar); #endif /* CONFIG_CARL9170_DEBUGFS */ -#ifdef CONFIG_CARL9170_WPC - if (ar->wps.pbc) { - input_unregister_device(ar->wps.pbc); - ar->wps.pbc = NULL; - } -#endif /* CONFIG_CARL9170_WPC */ - -#ifdef CONFIG_CARL9170_HWRNG - carl9170_unregister_hwrng(ar); -#endif /* CONFIG_CARL9170_HWRNG */ - carl9170_cancel_worker(ar); cancel_work_sync(&ar->restart_work); @@ -2120,12 +2053,6 @@ void carl9170_free(struct ar9170 *ar) kfree_skb(ar->rx_failover); ar->rx_failover = NULL; - kfree(ar->mem_bitmap); - ar->mem_bitmap = NULL; - - kfree(ar->survey); - ar->survey = NULL; - mutex_destroy(&ar->mutex); ieee80211_free_hw(ar->hw); diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index ab4ee7d39ad3..34d9fd77046e 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -540,11 +540,11 @@ static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, return carl9170_regwrite_result(); } -static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) +static int carl9170_init_phy(struct ar9170 *ar, enum nl80211_band band) { int i, err; u32 val; - bool is_2ghz = band == IEEE80211_BAND_2GHZ; + bool is_2ghz = band == NL80211_BAND_2GHZ; bool is_40mhz = conf_is_ht40(&ar->hw->conf); carl9170_regwrite_begin(ar); @@ -994,7 +994,7 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, refsel0 = 0; refsel1 = 1; } - chansel = byte_rev_table[chansel]; + chansel = bitrev8(chansel); } else { if (freq == 2484) { chansel = 10 + (freq - 2274) / 5; @@ -1002,7 +1002,7 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, } else chansel = 16 + (freq - 2272) / 5; chansel *= 4; - chansel = byte_rev_table[chansel]; + chansel = bitrev8(chansel); } d1 = chansel; @@ -1125,13 +1125,13 @@ static int carl9170_set_freq_cal_data(struct ar9170 *ar, u8 f, tmp; switch (channel->band) { - case IEEE80211_BAND_2GHZ: + case NL80211_BAND_2GHZ: f = channel->center_freq - 2300; cal_freq_pier = ar->eeprom.cal_freq_pier_2G; i = AR5416_NUM_2G_CAL_PIERS - 1; break; - case IEEE80211_BAND_5GHZ: + case NL80211_BAND_5GHZ: f = (channel->center_freq - 4800) / 5; cal_freq_pier = ar->eeprom.cal_freq_pier_5G; i = AR5416_NUM_5G_CAL_PIERS - 1; @@ -1139,7 +1139,6 @@ static int carl9170_set_freq_cal_data(struct ar9170 *ar, default: return -EINVAL; - break; } for (; i >= 0; i--) { @@ -1159,12 +1158,12 @@ static int carl9170_set_freq_cal_data(struct ar9170 *ar, int j; switch (channel->band) { - case IEEE80211_BAND_2GHZ: + case NL80211_BAND_2GHZ: cal_pier_data = &ar->eeprom. cal_pier_data_2G[chain][idx]; break; - case IEEE80211_BAND_5GHZ: + case NL80211_BAND_5GHZ: cal_pier_data = &ar->eeprom. cal_pier_data_5G[chain][idx]; break; @@ -1341,7 +1340,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ return; - if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { + if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) { modes = mode_list_2ghz; nr_modes = ARRAY_SIZE(mode_list_2ghz); } else { @@ -1608,7 +1607,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, return err; err = carl9170_init_rf_banks_0_7(ar, - channel->band == IEEE80211_BAND_5GHZ); + channel->band == NL80211_BAND_5GHZ); if (err) return err; @@ -1622,7 +1621,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, return err; err = carl9170_init_rf_bank4_pwr(ar, - channel->band == IEEE80211_BAND_5GHZ, + channel->band == NL80211_BAND_5GHZ, channel->center_freq, bw); if (err) return err; diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 4684dd989496..6833430130f4 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -37,7 +37,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/etherdevice.h> @@ -359,7 +358,7 @@ static int carl9170_rx_mac_status(struct ar9170 *ar, switch (mac->status & AR9170_RX_STATUS_MODULATION) { case AR9170_RX_STATUS_MODULATION_CCK: if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) - status->flag |= RX_FLAG_SHORTPRE; + status->enc_flags |= RX_ENC_FLAG_SHORTPRE; switch (head->plcp[0]) { case AR9170_RX_PHY_RATE_CCK_1M: status->rate_idx = 0; @@ -418,18 +417,18 @@ static int carl9170_rx_mac_status(struct ar9170 *ar, return -EINVAL; } - if (status->band == IEEE80211_BAND_2GHZ) + if (status->band == NL80211_BAND_2GHZ) status->rate_idx += 4; break; case AR9170_RX_STATUS_MODULATION_HT: if (head->plcp[3] & 0x80) - status->flag |= RX_FLAG_40MHZ; + status->bw = RATE_INFO_BW_40; if (head->plcp[6] & 0x80) - status->flag |= RX_FLAG_SHORT_GI; + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f); - status->flag |= RX_FLAG_HT; + status->rate_idx = clamp(head->plcp[3] & 0x7f, 0, 75); + status->encoding = RX_ENC_HT; break; default: @@ -454,7 +453,7 @@ static void carl9170_rx_phy_status(struct ar9170 *ar, /* post-process RSSI */ for (i = 0; i < 7; i++) if (phy->rssi[i] & 0x80) - phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; + phy->rssi[i] = ((~phy->rssi[i] & 0x7f) + 1) & 0x7f; /* TODO: we could do something with phy_errors */ status->signal = ar->noise[0] + phy->rssi_combined; @@ -482,7 +481,7 @@ static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len) skb = dev_alloc_skb(len + reserved); if (likely(skb)) { skb_reserve(skb, reserved); - memcpy(skb_put(skb, len), buf, len); + skb_put_data(skb, buf, len); } return skb; @@ -520,6 +519,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) { struct ieee80211_hdr *hdr = data; struct ieee80211_tim_ie *tim_ie; + struct ath_common *common = &ar->common; u8 *tim; u8 tim_len; bool cam; @@ -527,17 +527,13 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) return; - /* check if this really is a beacon */ - if (!ieee80211_is_beacon(hdr->frame_control)) - return; - /* min. beacon length + FCS_LEN */ if (len <= 40 + FCS_LEN) return; + /* check if this really is a beacon */ /* and only beacons from the associated BSSID, please */ - if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || - !ar->common.curaid) + if (!ath_is_mybeacon(common, hdr) || !common->curaid) return; ar->ps.last_beacon = jiffies; @@ -559,7 +555,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) /* Check whenever the PHY can be turned off again. */ /* 1. What about buffered unicast traffic for our AID? */ - cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); + cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid, false); /* 2. Maybe the AP wants to send multicast/broadcast data? */ cam |= !!(tim_ie->bitmap_ctrl & 0x01); @@ -576,7 +572,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) { - struct ieee80211_bar *bar = (void *) data; + struct ieee80211_bar *bar = data; struct carl9170_bar_list_entry *entry; unsigned int queue; @@ -602,8 +598,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) if (bar->start_seq_num == entry_bar->start_seq_num && TID_CHECK(bar->control, entry_bar->control) && - compare_ether_addr(bar->ra, entry_bar->ta) == 0 && - compare_ether_addr(bar->ta, entry_bar->ra) == 0) { + ether_addr_equal_64bits(bar->ra, entry_bar->ta) && + ether_addr_equal_64bits(bar->ta, entry_bar->ra)) { struct ieee80211_tx_info *tx_info; tx_info = IEEE80211_SKB_CB(entry_skb); @@ -770,6 +766,7 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) goto drop; } + fallthrough; case AR9170_RX_STATUS_MPDU_MIDDLE: /* These are just data + mac status */ @@ -798,7 +795,7 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) break; default: - BUG_ON(1); + BUG(); break; } @@ -920,7 +917,7 @@ static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) } } - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + skb_put_data(ar->rx_failover, tbuf, tlen); ar->rx_failover_missing -= tlen; if (ar->rx_failover_missing <= 0) { @@ -962,7 +959,7 @@ static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) * the rx - descriptor comes round again. */ - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + skb_put_data(ar->rx_failover, tbuf, tlen); ar->rx_failover_missing = clen - tlen; return; } diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index e3f696ee4d23..b7717f9e1e9b 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -37,7 +37,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/etherdevice.h> @@ -190,7 +189,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb) { - struct _carl9170_tx_superframe *super = (void *) skb->data; + struct _carl9170_tx_superframe *super; unsigned int chunks; int cookie = -1; @@ -247,8 +246,8 @@ static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb) * of available memory blocks, so the number can * never execeed the mem_blocks count. */ - if (unlikely(WARN_ON_ONCE(cookie == 0) || - WARN_ON_ONCE(cookie > ar->fw.mem_blocks))) + if (WARN_ON_ONCE(cookie == 0) || + WARN_ON_ONCE(cookie > ar->fw.mem_blocks)) return; atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size), @@ -276,12 +275,13 @@ static void carl9170_tx_release(struct kref *ref) if (WARN_ON_ONCE(!ar)) return; - BUILD_BUG_ON( - offsetof(struct ieee80211_tx_info, status.ack_signal) != 20); - - memset(&txinfo->status.ack_signal, 0, - sizeof(struct ieee80211_tx_info) - - offsetof(struct ieee80211_tx_info, status.ack_signal)); + /* + * This does not call ieee80211_tx_info_clear_status() because + * carl9170_tx_fill_rateinfo() has filled the rate information + * before we get to this point. + */ + memset(&txinfo->pad, 0, sizeof(txinfo->pad)); + memset(&txinfo->rate_driver_data, 0, sizeof(txinfo->rate_driver_data)); if (atomic_read(&ar->tx_total_queued)) ar->tx_schedule = true; @@ -366,8 +366,7 @@ static void carl9170_tx_shift_bm(struct ar9170 *ar, if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) return; - if (!bitmap_empty(tid_info->bitmap, off)) - off = find_first_bit(tid_info->bitmap, off); + off = min(off, find_first_bit(tid_info->bitmap, off)); tid_info->bsn += off; tid_info->bsn &= 0x0fff; @@ -395,7 +394,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, if (unlikely(!sta)) goto out_rcu; - tid = get_tid_h(hdr); + tid = ieee80211_get_tid(hdr); sta_info = (void *) sta->drv_priv; tid_info = rcu_dereference(sta_info->agg[tid]); @@ -664,7 +663,7 @@ static void __carl9170_tx_process_status(struct ar9170 *ar, unsigned int r, t, q; bool success = true; - q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE]; + q = ar9170_qmap(info & CARL9170_TX_STATUS_QUEUE); skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]); if (!skb) { @@ -721,12 +720,12 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, /* +1 dBm for HT40 */ *tpc += 2; - if (info->band == IEEE80211_BAND_2GHZ) + if (info->band == NL80211_BAND_2GHZ) txpower = ar->power_2G_ht40; else txpower = ar->power_5G_ht40; } else { - if (info->band == IEEE80211_BAND_2GHZ) + if (info->band == NL80211_BAND_2GHZ) txpower = ar->power_2G_ht20; else txpower = ar->power_5G_ht20; @@ -735,7 +734,7 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, *phyrate = txrate->idx; *tpc += txpower[idx & 7]; } else { - if (info->band == IEEE80211_BAND_2GHZ) { + if (info->band == NL80211_BAND_2GHZ) { if (idx < 4) txpower = ar->power_2G_cck; else @@ -798,7 +797,7 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar, * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); */ } else { - if (info->band == IEEE80211_BAND_2GHZ) { + if (info->band == NL80211_BAND_2GHZ) { if (txrate->idx <= AR9170_TX_PHY_RATE_CCK_11M) tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_CCK); else @@ -831,14 +830,17 @@ static bool carl9170_tx_rts_check(struct ar9170 *ar, case CARL9170_ERP_AUTO: if (ampdu) break; + fallthrough; case CARL9170_ERP_MAC80211: if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)) break; + fallthrough; case CARL9170_ERP_RTS: if (likely(!multi)) return true; + break; default: break; @@ -855,6 +857,7 @@ static bool carl9170_tx_cts_check(struct ar9170 *ar, case CARL9170_ERP_MAC80211: if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) break; + fallthrough; case CARL9170_ERP_CTS: return true; @@ -977,7 +980,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, ((CARL9170_TX_SUPER_MISC_VIF_ID >> CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); - hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)]; + hw_queue = ar9170_qmap(carl9170_get_queue(ar, skb)); hdr = (void *)skb->data; info = IEEE80211_SKB_CB(skb); @@ -992,7 +995,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, else cvif = NULL; - txc = (void *)skb_push(skb, sizeof(*txc)); + txc = skb_push(skb, sizeof(*txc)); memset(txc, 0, sizeof(*txc)); SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); @@ -1041,8 +1044,9 @@ static int carl9170_tx_prepare(struct ar9170 *ar, if (unlikely(!sta || !cvif)) goto err_out; - factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor); - density = sta->ht_cap.ampdu_density; + factor = min_t(unsigned int, 1u, + sta->deflink.ht_cap.ampdu_factor); + density = sta->deflink.ht_cap.ampdu_density; if (density) { /* @@ -1277,7 +1281,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) super = (void *)skb->data; SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q, - ar9170_qmap[carl9170_get_queue(ar, skb)]); + ar9170_qmap(carl9170_get_queue(ar, skb))); __carl9170_tx_process_status(ar, super->s.cookie, q); } @@ -1555,10 +1559,13 @@ static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar) goto out; } } while (ar->beacon_enabled && i--); + + /* no entry found in list */ + return NULL; } out: - rcu_assign_pointer(ar->beacon_iter, cvif); + RCU_INIT_POINTER(ar->beacon_iter, cvif); return cvif; } @@ -1621,7 +1628,7 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) goto out_unlock; skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), - NULL, NULL); + NULL, NULL, 0); if (!skb) { err = -ENOMEM; diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 307bc0ddff99..564ca6a61985 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -61,10 +61,10 @@ MODULE_ALIAS("arusb_lnx"); * Note: * * Always update our wiki's device list (located at: - * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), + * https://wireless.wiki.kernel.org/en/users/Drivers/ar9170/devices ), * whenever you add a new device. */ -static struct usb_device_id carl9170_usb_ids[] = { +static const struct usb_device_id carl9170_usb_ids[] = { /* Atheros 9170 */ { USB_DEVICE(0x0cf3, 0x9170) }, /* Atheros TG121N */ @@ -128,6 +128,8 @@ static struct usb_device_id carl9170_usb_ids[] = { }; MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); +static struct usb_driver carl9170_driver; + static void carl9170_usb_submit_data_urb(struct ar9170 *ar) { struct urb *urb; @@ -176,7 +178,7 @@ static void carl9170_usb_tx_data_complete(struct urb *urb) switch (urb->status) { /* everything is fine */ case 0: - carl9170_tx_callback(ar, (void *)urb->context); + carl9170_tx_callback(ar, urb->context); break; /* disconnect */ @@ -367,7 +369,7 @@ void carl9170_usb_handle_tx_err(struct ar9170 *ar) struct urb *urb; while ((urb = usb_get_from_anchor(&ar->tx_err))) { - struct sk_buff *skb = (void *)urb->context; + struct sk_buff *skb = urb->context; carl9170_tx_drop(ar, skb); carl9170_tx_callback(ar, skb); @@ -375,9 +377,9 @@ void carl9170_usb_handle_tx_err(struct ar9170 *ar) } } -static void carl9170_usb_tasklet(unsigned long data) +static void carl9170_usb_tasklet(struct tasklet_struct *t) { - struct ar9170 *ar = (struct ar9170 *) data; + struct ar9170 *ar = from_tasklet(ar, t, usb_tasklet); if (!IS_INITIALIZED(ar)) return; @@ -395,7 +397,7 @@ static void carl9170_usb_tasklet(unsigned long data) static void carl9170_usb_rx_complete(struct urb *urb) { - struct ar9170 *ar = (struct ar9170 *)urb->context; + struct ar9170 *ar = urb->context; int err; if (WARN_ON_ONCE(!ar)) @@ -436,14 +438,21 @@ static void carl9170_usb_rx_complete(struct urb *urb) if (atomic_read(&ar->rx_anch_urbs) == 0) { /* - * The system is too slow to cope with - * the enormous workload. We have simply - * run out of active rx urbs and this - * unfortunately leads to an unpredictable - * device. + * At this point, either the system is too slow to + * cope with the enormous workload (so we have simply + * run out of active rx urbs and this unfortunately + * leads to an unpredictable device), or the device + * is not fully functional after an unsuccessful + * firmware loading attempts (so it doesn't pass + * ieee80211_register_hw() and there is no internal + * workqueue at all). */ - ieee80211_queue_work(ar->hw, &ar->ping_work); + if (ar->registered) + ieee80211_queue_work(ar->hw, &ar->ping_work); + else + pr_warn_once("device %s is not registered\n", + dev_name(&ar->udev->dev)); } } else { /* @@ -557,7 +566,7 @@ static int carl9170_usb_flush(struct ar9170 *ar) int ret, err = 0; while ((urb = usb_get_from_anchor(&ar->tx_wait))) { - struct sk_buff *skb = (void *)urb->context; + struct sk_buff *skb = urb->context; carl9170_tx_drop(ar, skb); carl9170_tx_callback(ar, skb); usb_free_urb(urb); @@ -621,9 +630,16 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, goto err_free; } - usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, - AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, - carl9170_usb_cmd_complete, ar, 1); + if (ar->usb_ep_cmd_is_bulk) + usb_fill_bulk_urb(urb, ar->udev, + usb_sndbulkpipe(ar->udev, AR9170_USB_EP_CMD), + cmd, cmd->hdr.len + 4, + carl9170_usb_cmd_complete, ar); + else + usb_fill_int_urb(urb, ar->udev, + usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD), + cmd, cmd->hdr.len + 4, + carl9170_usb_cmd_complete, ar, 1); if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; @@ -644,6 +660,7 @@ int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, unsigned int plen, void *payload, unsigned int outlen, void *out) { int err = -ENOMEM; + unsigned long time_left; if (!IS_ACCEPTING_CMD(ar)) return -EIO; @@ -658,15 +675,16 @@ int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, memcpy(ar->cmd.data, payload, plen); spin_lock_bh(&ar->cmd_lock); - ar->readbuf = (u8 *)out; + ar->readbuf = out; ar->readlen = outlen; spin_unlock_bh(&ar->cmd_lock); + reinit_completion(&ar->cmd_wait); err = __carl9170_exec_cmd(ar, &ar->cmd, false); if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { - err = wait_for_completion_timeout(&ar->cmd_wait, HZ); - if (err == 0) { + time_left = wait_for_completion_timeout(&ar->cmd_wait, HZ); + if (time_left == 0) { err = -ETIMEDOUT; goto err_unbuf; } @@ -770,10 +788,7 @@ void carl9170_usb_stop(struct ar9170 *ar) spin_lock_bh(&ar->cmd_lock); ar->readlen = 0; spin_unlock_bh(&ar->cmd_lock); - complete_all(&ar->cmd_wait); - - /* This is required to prevent an early completion on _start */ - INIT_COMPLETION(ar->cmd_wait); + complete(&ar->cmd_wait); /* * Note: @@ -960,32 +975,28 @@ err_out: static void carl9170_usb_firmware_failed(struct ar9170 *ar) { - struct device *parent = ar->udev->dev.parent; - struct usb_device *udev; - - /* - * Store a copy of the usb_device pointer locally. - * This is because device_release_driver initiates - * carl9170_usb_disconnect, which in turn frees our - * driver context (ar). + /* Store a copies of the usb_interface and usb_device pointer locally. + * This is because release_driver initiates carl9170_usb_disconnect, + * which in turn frees our driver context (ar). */ - udev = ar->udev; + struct usb_interface *intf = ar->intf; + struct usb_device *udev = ar->udev; complete(&ar->fw_load_wait); + /* at this point 'ar' could be already freed. Don't use it anymore */ + ar = NULL; /* unbind anything failed */ - if (parent) - device_lock(parent); + usb_lock_device(udev); + usb_driver_release_interface(&carl9170_driver, intf); + usb_unlock_device(udev); - device_release_driver(&udev->dev); - if (parent) - device_unlock(parent); - - usb_put_dev(udev); + usb_put_intf(intf); } static void carl9170_usb_firmware_finish(struct ar9170 *ar) { + struct usb_interface *intf = ar->intf; int err; err = carl9170_parse_firmware(ar); @@ -1003,7 +1014,7 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar) goto err_unrx; complete(&ar->fw_load_wait); - usb_put_dev(ar->udev); + usb_put_intf(intf); return; err_unrx: @@ -1032,9 +1043,10 @@ static void carl9170_usb_firmware_step2(const struct firmware *fw, static int carl9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_endpoint_descriptor *ep; struct ar9170 *ar; struct usb_device *udev; - int err; + int i, err; err = usb_reset_device(interface_to_usbdev(intf)); if (err) @@ -1045,11 +1057,57 @@ static int carl9170_usb_probe(struct usb_interface *intf, return PTR_ERR(ar); udev = interface_to_usbdev(intf); - usb_get_dev(udev); ar->udev = udev; ar->intf = intf; ar->features = id->driver_info; + /* We need to remember the type of endpoint 4 because it differs + * between high- and full-speed configuration. The high-speed + * configuration specifies it as interrupt and the full-speed + * configuration as bulk endpoint. This information is required + * later when sending urbs to that endpoint. + */ + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; ++i) { + ep = &intf->cur_altsetting->endpoint[i].desc; + + if (usb_endpoint_num(ep) == AR9170_USB_EP_CMD && + usb_endpoint_dir_out(ep) && + usb_endpoint_type(ep) == USB_ENDPOINT_XFER_BULK) + ar->usb_ep_cmd_is_bulk = true; + } + + /* Verify that all expected endpoints are present */ + if (ar->usb_ep_cmd_is_bulk) { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } else { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } + + if (err) { + carl9170_free(ar); + return err; + } + usb_set_intfdata(intf, ar); SET_IEEE80211_DEV(ar->hw, &intf->dev); @@ -1063,8 +1121,7 @@ static int carl9170_usb_probe(struct usb_interface *intf, init_completion(&ar->cmd_wait); init_completion(&ar->fw_boot_wait); init_completion(&ar->fw_load_wait); - tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, - (unsigned long)ar); + tasklet_setup(&ar->usb_tasklet, carl9170_usb_tasklet); atomic_set(&ar->tx_cmd_urbs, 0); atomic_set(&ar->tx_anch_urbs, 0); @@ -1072,23 +1129,26 @@ static int carl9170_usb_probe(struct usb_interface *intf, atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); - usb_get_dev(ar->udev); + usb_get_intf(intf); carl9170_set_state(ar, CARL9170_STOPPED); - return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { + usb_put_intf(intf); + carl9170_free(ar); + } + return err; } static void carl9170_usb_disconnect(struct usb_interface *intf) { struct ar9170 *ar = usb_get_intfdata(intf); - struct usb_device *udev; if (WARN_ON(!ar)) return; - udev = ar->udev; wait_for_completion(&ar->fw_load_wait); if (IS_INITIALIZED(ar)) { @@ -1103,7 +1163,6 @@ static void carl9170_usb_disconnect(struct usb_interface *intf) carl9170_release_firmware(ar); carl9170_free(ar); - usb_put_dev(udev); } #ifdef CONFIG_PM diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index 2282847d4bb8..9a44d004c206 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H -#define CARL9170FW_VERSION_YEAR 12 -#define CARL9170FW_VERSION_MONTH 12 +#define CARL9170FW_VERSION_YEAR 16 +#define CARL9170FW_VERSION_MONTH 2 #define CARL9170FW_VERSION_DAY 15 -#define CARL9170FW_VERSION_GIT "1.9.7" +#define CARL9170FW_VERSION_GIT "1.9.9" #endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h index ea17995b32f4..ded2c6d0a759 100644 --- a/drivers/net/wireless/ath/carl9170/wlan.h +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -271,7 +271,7 @@ struct ar9170_tx_frame { union { struct ieee80211_hdr i3e; - u8 payload[0]; + DECLARE_FLEX_ARRAY(u8, payload); } data; } __packed; @@ -327,7 +327,7 @@ struct _carl9170_tx_superdesc { struct _carl9170_tx_superframe { struct _carl9170_tx_superdesc s; struct _ar9170_tx_hwdesc f; - u8 frame_data[0]; + u8 frame_data[]; } __packed __aligned(4); #define CARL9170_TX_SUPERDESC_LEN 24 @@ -367,27 +367,27 @@ struct ar9170_rx_macstatus { struct ar9170_rx_frame_single { struct ar9170_rx_head phy_head; - struct ieee80211_hdr i3e; + struct ieee80211_hdr i3e __packed __aligned(2); struct ar9170_rx_phystatus phy_tail; struct ar9170_rx_macstatus macstatus; -} __packed; +}; struct ar9170_rx_frame_head { struct ar9170_rx_head phy_head; - struct ieee80211_hdr i3e; + struct ieee80211_hdr i3e __packed __aligned(2); struct ar9170_rx_macstatus macstatus; -} __packed; +}; struct ar9170_rx_frame_middle { - struct ieee80211_hdr i3e; + struct ieee80211_hdr i3e __packed __aligned(2); struct ar9170_rx_macstatus macstatus; -} __packed; +}; struct ar9170_rx_frame_tail { - struct ieee80211_hdr i3e; + struct ieee80211_hdr i3e __packed __aligned(2); struct ar9170_rx_phystatus phy_tail; struct ar9170_rx_macstatus macstatus; -} __packed; +}; struct ar9170_rx_frame { union { @@ -395,8 +395,8 @@ struct ar9170_rx_frame { struct ar9170_rx_frame_head head; struct ar9170_rx_frame_middle middle; struct ar9170_rx_frame_tail tail; - } __packed; -} __packed; + }; +}; static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) { |
