diff options
Diffstat (limited to 'drivers/net/wireless/broadcom')
71 files changed, 867 insertions, 619 deletions
diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h index 67b4bac048e5..c0d8fc0b22fb 100644 --- a/drivers/net/wireless/broadcom/b43/b43.h +++ b/drivers/net/wireless/broadcom/b43/b43.h @@ -1082,6 +1082,22 @@ static inline bool b43_using_pio_transfers(struct b43_wldev *dev) return dev->__using_pio_transfers; } +static inline void b43_wake_queue(struct b43_wldev *dev, int queue_prio) +{ + if (dev->qos_enabled) + ieee80211_wake_queue(dev->wl->hw, queue_prio); + else + ieee80211_wake_queue(dev->wl->hw, 0); +} + +static inline void b43_stop_queue(struct b43_wldev *dev, int queue_prio) +{ + if (dev->qos_enabled) + ieee80211_stop_queue(dev->wl->hw, queue_prio); + else + ieee80211_stop_queue(dev->wl->hw, 0); +} + /* Message printing */ __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); diff --git a/drivers/net/wireless/broadcom/b43/debugfs.c b/drivers/net/wireless/broadcom/b43/debugfs.c index efa98444e3fb..5a49970afc8c 100644 --- a/drivers/net/wireless/broadcom/b43/debugfs.c +++ b/drivers/net/wireless/broadcom/b43/debugfs.c @@ -30,7 +30,6 @@ static struct dentry *rootdir; struct b43_debugfs_fops { ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize); int (*write)(struct b43_wldev *dev, const char *buf, size_t count); - struct file_operations fops; /* Offset of struct b43_dfs_file in struct b43_dfsentry */ size_t file_struct_offset; }; @@ -491,7 +490,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct b43_wldev *dev; - struct b43_debugfs_fops *dfops; + const struct b43_debugfs_fops *dfops; struct b43_dfs_file *dfile; ssize_t ret; char *buf; @@ -511,8 +510,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, goto out_unlock; } - dfops = container_of(debugfs_real_fops(file), - struct b43_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->read) { err = -ENOSYS; goto out_unlock; @@ -555,7 +553,7 @@ static ssize_t b43_debugfs_write(struct file *file, size_t count, loff_t *ppos) { struct b43_wldev *dev; - struct b43_debugfs_fops *dfops; + const struct b43_debugfs_fops *dfops; char *buf; int err = 0; @@ -573,8 +571,7 @@ static ssize_t b43_debugfs_write(struct file *file, goto out_unlock; } - dfops = container_of(debugfs_real_fops(file), - struct b43_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->write) { err = -ENOSYS; goto out_unlock; @@ -602,16 +599,16 @@ out_unlock: } +static struct debugfs_short_fops debugfs_ops = { + .read = b43_debugfs_read, + .write = b43_debugfs_write, + .llseek = generic_file_llseek, +}; + #define B43_DEBUGFS_FOPS(name, _read, _write) \ static struct b43_debugfs_fops fops_##name = { \ .read = _read, \ .write = _write, \ - .fops = { \ - .open = simple_open, \ - .read = b43_debugfs_read, \ - .write = b43_debugfs_write, \ - .llseek = generic_file_llseek, \ - }, \ .file_struct_offset = offsetof(struct b43_dfsentry, \ file_##name), \ } @@ -703,9 +700,9 @@ void b43_debugfs_add_device(struct b43_wldev *dev) #define ADD_FILE(name, mode) \ do { \ - debugfs_create_file(__stringify(name), \ + debugfs_create_file_aux(__stringify(name), \ mode, e->subdir, dev, \ - &fops_##name.fops); \ + &fops_##name, &debugfs_ops); \ } while (0) diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c index 760d1a28edc6..6ac7dcebfff9 100644 --- a/drivers/net/wireless/broadcom/b43/dma.c +++ b/drivers/net/wireless/broadcom/b43/dma.c @@ -1399,7 +1399,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) should_inject_overflow(ring)) { /* This TX ring is full. */ unsigned int skb_mapping = skb_get_queue_mapping(skb); - ieee80211_stop_queue(dev->wl->hw, skb_mapping); + b43_stop_queue(dev, skb_mapping); dev->wl->tx_queue_stopped[skb_mapping] = true; ring->stopped = true; if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { @@ -1570,7 +1570,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, } else { /* If the driver queue is running wake the corresponding * mac80211 queue. */ - ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); + b43_wake_queue(dev, ring->queue_prio); if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); } diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 92ca0b2ca286..25b4ef9d3c9a 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -30,7 +30,7 @@ #include <linux/io.h> #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "b43.h" #include "main.h" @@ -2587,7 +2587,8 @@ static void b43_request_firmware(struct work_struct *work) start_ieee80211: wl->hw->queues = B43_QOS_QUEUE_NUM; - if (!modparam_qos || dev->fw.opensource) + if (!modparam_qos || dev->fw.opensource || + dev->dev->chip_id == BCMA_CHIP_ID_BCM4331) wl->hw->queues = 1; err = ieee80211_register_hw(wl->hw); @@ -3603,7 +3604,7 @@ static void b43_tx_work(struct work_struct *work) err = b43_dma_tx(dev, skb); if (err == -ENOSPC) { wl->tx_queue_stopped[queue_num] = true; - ieee80211_stop_queue(wl->hw, queue_num); + b43_stop_queue(dev, queue_num); skb_queue_head(&wl->tx_queue[queue_num], skb); break; } @@ -3627,6 +3628,7 @@ static void b43_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct b43_wl *wl = hw_to_b43_wl(hw); + u16 skb_queue_mapping; if (unlikely(skb->len < 2 + 2 + 6)) { /* Too short, this can't be a valid frame. */ @@ -3635,12 +3637,12 @@ static void b43_op_tx(struct ieee80211_hw *hw, } B43_WARN_ON(skb_shinfo(skb)->nr_frags); - skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); - if (!wl->tx_queue_stopped[skb->queue_mapping]) { + skb_queue_mapping = skb_get_queue_mapping(skb); + skb_queue_tail(&wl->tx_queue[skb_queue_mapping], skb); + if (!wl->tx_queue_stopped[skb_queue_mapping]) ieee80211_queue_work(wl->hw, &wl->tx_work); - } else { - ieee80211_stop_queue(wl->hw, skb->queue_mapping); - } + else + b43_stop_queue(wl->current_dev, skb_queue_mapping); } static void b43_qos_params_upload(struct b43_wldev *dev, @@ -5076,7 +5078,7 @@ static int b43_op_start(struct ieee80211_hw *hw) return err; } -static void b43_op_stop(struct ieee80211_hw *hw) +static void b43_op_stop(struct ieee80211_hw *hw, bool suspend) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -5170,6 +5172,10 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx, } static const struct ieee80211_ops b43_hw_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, .tx = b43_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, .conf_tx = b43_op_conf_tx, diff --git a/drivers/net/wireless/broadcom/b43/phy_ht.c b/drivers/net/wireless/broadcom/b43/phy_ht.c index d050971d150a..26a226126bc4 100644 --- a/drivers/net/wireless/broadcom/b43/phy_ht.c +++ b/drivers/net/wireless/broadcom/b43/phy_ht.c @@ -322,8 +322,8 @@ static void b43_phy_ht_bphy_reset(struct b43_wldev *dev, bool reset) B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX); else b43_phy_mask(dev, B43_PHY_B_BBCFG, - (u16)~(B43_PHY_B_BBCFG_RSTCCA | - B43_PHY_B_BBCFG_RSTRX)); + 0xffff & ~(B43_PHY_B_BBCFG_RSTCCA | + B43_PHY_B_BBCFG_RSTRX)); b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp); } @@ -551,7 +551,7 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) phy_ht->tx_pwr_idx[i] = b43_phy_read(dev, status_regs[i]); } - b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); + b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0xffff & ~en_bits); } else { b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits); diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index 2c0c019a815d..4bb005b93f2c 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -6246,7 +6246,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4); /* Take BPHY out of the reset */ b43_phy_mask(dev, B43_PHY_B_BBCFG, - (u16)~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX)); + ~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX) & 0xffff); b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16); } @@ -6377,7 +6377,7 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, } else if (channel_type == NL80211_CHAN_HT40MINUS) { b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20); if (phy->rev >= 7) - b43_phy_mask(dev, 0x310, (u16)~0x8000); + b43_phy_mask(dev, 0x310, 0x7fff); } if (phy->rev >= 19) { diff --git a/drivers/net/wireless/broadcom/b43/pio.c b/drivers/net/wireless/broadcom/b43/pio.c index 0cf70fdb60a6..e41f2f5b4c26 100644 --- a/drivers/net/wireless/broadcom/b43/pio.c +++ b/drivers/net/wireless/broadcom/b43/pio.c @@ -525,7 +525,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) if (total_len > (q->buffer_size - q->buffer_used)) { /* Not enough memory on the queue. */ err = -EBUSY; - ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); + b43_stop_queue(dev, skb_get_queue_mapping(skb)); q->stopped = true; goto out; } @@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || (q->free_packet_slots == 0)) { /* The queue is full. */ - ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); + b43_stop_queue(dev, skb_get_queue_mapping(skb)); q->stopped = true; } @@ -587,7 +587,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, list_add(&pack->list, &q->packets_list); if (q->stopped) { - ieee80211_wake_queue(dev->wl->hw, q->queue_prio); + b43_wake_queue(dev, q->queue_prio); q->stopped = false; } } diff --git a/drivers/net/wireless/broadcom/b43/sysfs.c b/drivers/net/wireless/broadcom/b43/sysfs.c index 0679d132968f..261b2b746a9c 100644 --- a/drivers/net/wireless/broadcom/b43/sysfs.c +++ b/drivers/net/wireless/broadcom/b43/sysfs.c @@ -53,19 +53,14 @@ static ssize_t b43_attr_interfmode_show(struct device *dev, switch (wldev->phy.g->interfmode) { case B43_INTERFMODE_NONE: - count = - snprintf(buf, PAGE_SIZE, - "0 (No Interference Mitigation)\n"); + count = sysfs_emit(buf, "0 (No Interference Mitigation)\n"); break; case B43_INTERFMODE_NONWLAN: - count = - snprintf(buf, PAGE_SIZE, - "1 (Non-WLAN Interference Mitigation)\n"); + count = sysfs_emit(buf, + "1 (Non-WLAN Interference Mitigation)\n"); break; case B43_INTERFMODE_MANUALWLAN: - count = - snprintf(buf, PAGE_SIZE, - "2 (WLAN Interference Mitigation)\n"); + count = sysfs_emit(buf, "2 (WLAN Interference Mitigation)\n"); break; default: B43_WARN_ON(1); diff --git a/drivers/net/wireless/broadcom/b43/tables_lpphy.c b/drivers/net/wireless/broadcom/b43/tables_lpphy.c index 71a7cd8dc787..fb70a1e3544b 100644 --- a/drivers/net/wireless/broadcom/b43/tables_lpphy.c +++ b/drivers/net/wireless/broadcom/b43/tables_lpphy.c @@ -1066,7 +1066,7 @@ static const u32 lpphy_papd_mult_table[] = { 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28, }; -static struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = { { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, }, { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, }, { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, }, @@ -1197,7 +1197,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = { { .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = { { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, }, { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, }, { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, }, @@ -1328,7 +1328,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = { { .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 72, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = { { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, }, { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, }, { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, }, @@ -1459,7 +1459,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = { { .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = { { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, }, { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, }, { .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, }, @@ -1599,7 +1599,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = { { .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = { { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, }, { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, }, { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, }, @@ -1730,7 +1730,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = { { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = { { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, }, { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, }, { .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, }, @@ -1861,7 +1861,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = { { .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = { { .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 152, }, { .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 147, }, { .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 143, }, @@ -1992,7 +1992,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = { { .gm = 255, .pga = 111, .pad = 29, .dac = 0, .bb_mult = 64, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = { { .gm = 7, .pga = 99, .pad = 255, .dac = 0, .bb_mult = 64, }, { .gm = 7, .pga = 96, .pad = 255, .dac = 0, .bb_mult = 64, }, { .gm = 7, .pga = 93, .pad = 255, .dac = 0, .bb_mult = 64, }, @@ -2123,7 +2123,7 @@ static struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = { { .gm = 7, .pga = 13, .pad = 52, .dac = 0, .bb_mult = 64, }, }; -static struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = { +static const struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = { { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 152, }, { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 147, }, { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 143, }, @@ -2392,7 +2392,7 @@ void lpphy_write_gain_table(struct b43_wldev *dev, int offset, } void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, - struct lpphy_tx_gain_table_entry *table) + const struct lpphy_tx_gain_table_entry *table) { int i; diff --git a/drivers/net/wireless/broadcom/b43/tables_lpphy.h b/drivers/net/wireless/broadcom/b43/tables_lpphy.h index 62002098bbda..1971ccccabf8 100644 --- a/drivers/net/wireless/broadcom/b43/tables_lpphy.h +++ b/drivers/net/wireless/broadcom/b43/tables_lpphy.h @@ -36,7 +36,7 @@ struct lpphy_tx_gain_table_entry { void lpphy_write_gain_table(struct b43_wldev *dev, int offset, struct lpphy_tx_gain_table_entry data); void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, - struct lpphy_tx_gain_table_entry *table); + const struct lpphy_tx_gain_table_entry *table); void lpphy_rev0_1_table_init(struct b43_wldev *dev); void lpphy_rev2plus_table_init(struct b43_wldev *dev); diff --git a/drivers/net/wireless/broadcom/b43legacy/debugfs.c b/drivers/net/wireless/broadcom/b43legacy/debugfs.c index 6b0e8d117061..5d04bcc216e5 100644 --- a/drivers/net/wireless/broadcom/b43legacy/debugfs.c +++ b/drivers/net/wireless/broadcom/b43legacy/debugfs.c @@ -31,7 +31,6 @@ static struct dentry *rootdir; struct b43legacy_debugfs_fops { ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize); int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count); - struct file_operations fops; /* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */ size_t file_struct_offset; /* Take wl->irq_lock before calling read/write? */ @@ -188,7 +187,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct b43legacy_wldev *dev; - struct b43legacy_debugfs_fops *dfops; + const struct b43legacy_debugfs_fops *dfops; struct b43legacy_dfs_file *dfile; ssize_t ret; char *buf; @@ -208,8 +207,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, goto out_unlock; } - dfops = container_of(debugfs_real_fops(file), - struct b43legacy_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->read) { err = -ENOSYS; goto out_unlock; @@ -257,7 +255,7 @@ static ssize_t b43legacy_debugfs_write(struct file *file, size_t count, loff_t *ppos) { struct b43legacy_wldev *dev; - struct b43legacy_debugfs_fops *dfops; + const struct b43legacy_debugfs_fops *dfops; char *buf; int err = 0; @@ -275,8 +273,7 @@ static ssize_t b43legacy_debugfs_write(struct file *file, goto out_unlock; } - dfops = container_of(debugfs_real_fops(file), - struct b43legacy_debugfs_fops, fops); + dfops = debugfs_get_aux(file); if (!dfops->write) { err = -ENOSYS; goto out_unlock; @@ -308,17 +305,16 @@ out_unlock: return err ? err : count; } +static struct debugfs_short_fops debugfs_ops = { + .read = b43legacy_debugfs_read, + .write = b43legacy_debugfs_write, + .llseek = generic_file_llseek +}; #define B43legacy_DEBUGFS_FOPS(name, _read, _write, _take_irqlock) \ static struct b43legacy_debugfs_fops fops_##name = { \ .read = _read, \ .write = _write, \ - .fops = { \ - .open = simple_open, \ - .read = b43legacy_debugfs_read, \ - .write = b43legacy_debugfs_write, \ - .llseek = generic_file_llseek, \ - }, \ .file_struct_offset = offsetof(struct b43legacy_dfsentry, \ file_##name), \ .take_irqlock = _take_irqlock, \ @@ -386,9 +382,9 @@ void b43legacy_debugfs_add_device(struct b43legacy_wldev *dev) #define ADD_FILE(name, mode) \ do { \ - debugfs_create_file(__stringify(name), mode, \ + debugfs_create_file_aux(__stringify(name), mode, \ e->subdir, dev, \ - &fops_##name.fops); \ + &fops_##name, &debugfs_ops); \ } while (0) diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index 760136638a95..2370a2e6a2e3 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -27,7 +27,7 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #include <net/dst.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "b43legacy.h" #include "main.h" @@ -3485,7 +3485,7 @@ out_mutex_unlock: return err; } -static void b43legacy_op_stop(struct ieee80211_hw *hw) +static void b43legacy_op_stop(struct ieee80211_hw *hw, bool suspend) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3531,6 +3531,10 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, } static const struct ieee80211_ops b43legacy_hw_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, .tx = b43legacy_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, .conf_tx = b43legacy_op_conf_tx, diff --git a/drivers/net/wireless/broadcom/b43legacy/sysfs.c b/drivers/net/wireless/broadcom/b43legacy/sysfs.c index eec087ca30e6..d988fe541bf7 100644 --- a/drivers/net/wireless/broadcom/b43legacy/sysfs.c +++ b/drivers/net/wireless/broadcom/b43legacy/sysfs.c @@ -75,16 +75,14 @@ static ssize_t b43legacy_attr_interfmode_show(struct device *dev, switch (wldev->phy.interfmode) { case B43legacy_INTERFMODE_NONE: - count = snprintf(buf, PAGE_SIZE, "0 (No Interference" - " Mitigation)\n"); + count = sysfs_emit(buf, "0 (No Interference Mitigation)\n"); break; case B43legacy_INTERFMODE_NONWLAN: - count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference" - " Mitigation)\n"); + count = sysfs_emit(buf, + "1 (Non-WLAN Interference Mitigation)\n"); break; case B43legacy_INTERFMODE_MANUALWLAN: - count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference" - " Mitigation)\n"); + count = sysfs_emit(buf, "2 (WLAN Interference Mitigation)\n"); break; default: B43legacy_WARN_ON(1); @@ -155,11 +153,9 @@ static ssize_t b43legacy_attr_preamble_show(struct device *dev, mutex_lock(&wldev->wl->mutex); if (wldev->short_preamble) - count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble" - " enabled)\n"); + count = sysfs_emit(buf, "1 (Short Preamble enabled)\n"); else - count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble" - " disabled)\n"); + count = sysfs_emit(buf, "0 (Short Preamble disabled)\n"); mutex_unlock(&wldev->wl->mutex); diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig index 3a1a35b5672f..19d0c003f626 100644 --- a/drivers/net/wireless/broadcom/brcm80211/Kconfig +++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig @@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig" config BRCM_TRACING bool "Broadcom device tracing" depends on BRCMSMAC || BRCMFMAC + depends on TRACING help If you say Y here, the Broadcom wireless drivers will register with ftrace to dump event information into the trace ringbuffer. diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile index dc6d27a36faa..e5ca0f511822 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile @@ -6,8 +6,8 @@ # ccflags-y += \ - -I $(srctree)/$(src) \ - -I $(srctree)/$(src)/../include + -I $(src) \ + -I $(src)/../include obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += \ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/Makefile index 46098705e236..5e37c638f966 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/Makefile @@ -3,9 +3,9 @@ # Copyright (c) 2022 Broadcom Corporation ccflags-y += \ - -I $(srctree)/$(src) \ - -I $(srctree)/$(src)/.. \ - -I $(srctree)/$(src)/../../include + -I $(src) \ + -I $(src)/.. \ + -I $(src)/../../include obj-m += brcmfmac-bca.o brcmfmac-bca-objs += \ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c index ac3a36fa3640..f471c962104a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c @@ -7,21 +7,33 @@ #include <core.h> #include <bus.h> #include <fwvid.h> +#include <feature.h> #include "vops.h" -static int brcmf_bca_attach(struct brcmf_pub *drvr) +#define BRCMF_BCA_E_LAST 212 + +static void brcmf_bca_feat_attach(struct brcmf_if *ifp) { - pr_err("%s: executing\n", __func__); - return 0; + /* SAE support not confirmed so disabling for now */ + ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_SAE); } -static void brcmf_bca_detach(struct brcmf_pub *drvr) +static int brcmf_bca_alloc_fweh_info(struct brcmf_pub *drvr) { - pr_err("%s: executing\n", __func__); + struct brcmf_fweh_info *fweh; + + fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_BCA_E_LAST), + GFP_KERNEL); + if (!fweh) + return -ENOMEM; + + fweh->num_event_codes = BRCMF_BCA_E_LAST; + drvr->fweh = fweh; + return 0; } const struct brcmf_fwvid_ops brcmf_bca_ops = { - .attach = brcmf_bca_attach, - .detach = brcmf_bca_detach, + .feat_attach = brcmf_bca_feat_attach, + .alloc_fweh_info = brcmf_bca_alloc_fweh_info, }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c index 4f0c1e1a8e60..1e1c79b18c5b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_bca_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom AP chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_bca_init); module_exit(brcmf_bca_exit); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 00679a990e3d..6bc107476a2a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -455,6 +455,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, if (sg_data_sz > max_req_sz - req_sz) sg_data_sz = max_req_sz - req_sz; + if (!sgl) { + /* out of (pre-allocated) scatterlist entries */ + ret = -ENOMEM; + goto exit; + } sg_set_buf(sgl, pkt_data, sg_data_sz); sg_cnt++; @@ -770,7 +775,7 @@ void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev) nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, sdiodev->settings->bus.sdio.txglomsz); - nents += (nents >> 4) + 1; + nents *= 2; WARN_ON(nents > sdiodev->max_segment_count); @@ -947,8 +952,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) /* try to attach to the target device */ sdiodev->bus = brcmf_sdio_probe(sdiodev); - if (!sdiodev->bus) { - ret = -ENODEV; + if (IS_ERR(sdiodev->bus)) { + ret = PTR_ERR(sdiodev->bus); goto out; } brcmf_sdiod_host_fixup(sdiodev->func2->card->host); @@ -1061,10 +1066,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, if (func->num != 2) return -ENODEV; - bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); + bus_if = kzalloc(sizeof(*bus_if), GFP_KERNEL); if (!bus_if) return -ENOMEM; - sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); + sdiodev = kzalloc(sizeof(*sdiodev), GFP_KERNEL); if (!sdiodev) { kfree(bus_if); return -ENOMEM; @@ -1167,6 +1172,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev) struct brcmf_bus *bus_if; struct brcmf_sdio_dev *sdiodev; mmc_pm_flag_t sdio_flags; + bool cap_power_off; int ret = 0; func = container_of(dev, struct sdio_func, dev); @@ -1174,19 +1180,23 @@ static int brcmf_ops_sdio_suspend(struct device *dev) if (func->num != 1) return 0; + cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD); bus_if = dev_get_drvdata(dev); sdiodev = bus_if->bus_priv.sdio; - if (sdiodev->wowl_enabled) { + if (sdiodev->wowl_enabled || !cap_power_off) { brcmf_sdiod_freezer_on(sdiodev); brcmf_sdio_wd_timer(sdiodev->bus, 0); sdio_flags = MMC_PM_KEEP_POWER; - if (sdiodev->settings->bus.sdio.oob_irq_supported) - enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); - else - sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + + if (sdiodev->wowl_enabled) { + if (sdiodev->settings->bus.sdio.oob_irq_supported) + enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); + else + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags)) brcmf_err("Failed to set pm_flags %x\n", sdio_flags); @@ -1208,18 +1218,19 @@ static int brcmf_ops_sdio_resume(struct device *dev) struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct sdio_func *func = container_of(dev, struct sdio_func, dev); int ret = 0; + bool cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD); brcmf_dbg(SDIO, "Enter: F%d\n", func->num); if (func->num != 2) return 0; - if (!sdiodev->wowl_enabled) { + if (!sdiodev->wowl_enabled && cap_power_off) { /* bus was powered off and device removed, probe again */ ret = brcmf_sdiod_probe(sdiodev); if (ret) brcmf_err("Failed to probe device on resume\n"); } else { - if (sdiodev->settings->bus.sdio.oob_irq_supported) + if (sdiodev->wowl_enabled && sdiodev->settings->bus.sdio.oob_irq_supported) disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); brcmf_sdiod_freezer_off(sdiodev); @@ -1238,7 +1249,6 @@ static struct sdio_driver brcmf_sdmmc_driver = { .name = KBUILD_MODNAME, .id_table = brcmf_sdmmc_ids, .drv = { - .owner = THIS_MODULE, .pm = pm_sleep_ptr(&brcmf_sdio_pm_ops), .coredump = brcmf_dev_coredump, }, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c index 7ea2631b8069..1e8495f50c16 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c @@ -123,7 +123,7 @@ static s32 brcmf_btcoex_params_read(struct brcmf_if *ifp, u32 addr, u32 *data) { *data = addr; - return brcmf_fil_iovar_int_get(ifp, "btc_params", data); + return brcmf_fil_iovar_int_query(ifp, "btc_params", data); } /** @@ -358,10 +358,10 @@ idle: */ int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg) { - struct brcmf_btcoex_info *btci = NULL; + struct brcmf_btcoex_info *btci; brcmf_dbg(TRACE, "enter\n"); - btci = kmalloc(sizeof(struct brcmf_btcoex_info), GFP_KERNEL); + btci = kmalloc(sizeof(*btci), GFP_KERNEL); if (!btci) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 28d6a30cc010..4b70845e1a26 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -32,6 +32,7 @@ #include "vendor.h" #include "bus.h" #include "common.h" +#include "fwvid.h" #define BRCMF_SCAN_IE_LEN_MAX 2048 @@ -662,8 +663,8 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr) /* interface_create version 3+ */ /* get supported version from firmware side */ iface_create_ver = 0; - err = brcmf_fil_bsscfg_int_get(ifp, "interface_create", - &iface_create_ver); + err = brcmf_fil_bsscfg_int_query(ifp, "interface_create", + &iface_create_ver); if (err) { brcmf_err("fail to get supported version, err=%d\n", err); return -EOPNOTSUPP; @@ -755,8 +756,8 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) /* interface_create version 3+ */ /* get supported version from firmware side */ iface_create_ver = 0; - err = brcmf_fil_bsscfg_int_get(ifp, "interface_create", - &iface_create_ver); + err = brcmf_fil_bsscfg_int_query(ifp, "interface_create", + &iface_create_ver); if (err) { brcmf_err("fail to get supported version, err=%d\n", err); return -EOPNOTSUPP; @@ -813,6 +814,8 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) * @name: name of the new interface. * @params: contains mac address for AP or STA device. * @type: interface type. + * + * Return: pointer to new vif on success, ERR_PTR(-errno) if not */ static struct wireless_dev *brcmf_apsta_add_vif(struct wiphy *wiphy, const char *name, @@ -899,6 +902,8 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif) * * @wiphy: wiphy device of new interface. * @name: name of the new interface. + * + * Return: pointer to new vif on success, ERR_PTR(-errno) if not */ static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy, const char *name) @@ -1134,7 +1139,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) + n_channels * sizeof(u16); offset = roundup(offset, sizeof(u32)); - length += sizeof(ssid_le) * n_ssids, + length += sizeof(ssid_le) * n_ssids; ptr = (char *)params_le + offset; for (i = 0; i < n_ssids; i++) { memset(&ssid_le, 0, sizeof(ssid_le)); @@ -1179,8 +1184,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, scan_request = cfg->scan_request; cfg->scan_request = NULL; - if (timer_pending(&cfg->escan_timeout)) - del_timer_sync(&cfg->escan_timeout); + timer_delete_sync(&cfg->escan_timeout); if (fw_abort) { /* Do a scan abort to stop the driver's scan engine */ @@ -1687,52 +1691,39 @@ static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e) return reason; } -static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) +int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 flags) { struct brcmf_pub *drvr = ifp->drvr; struct brcmf_wsec_pmk_le pmk; int err; + if (key_len > sizeof(pmk.key)) { + bphy_err(drvr, "key must be less than %zu bytes\n", + sizeof(pmk.key)); + return -EINVAL; + } + memset(&pmk, 0, sizeof(pmk)); - /* pass pmk directly */ - pmk.key_len = cpu_to_le16(pmk_len); - pmk.flags = cpu_to_le16(0); - memcpy(pmk.key, pmk_data, pmk_len); + /* pass key material directly */ + pmk.key_len = cpu_to_le16(key_len); + pmk.flags = cpu_to_le16(flags); + memcpy(pmk.key, key, key_len); - /* store psk in firmware */ + /* store key material in firmware */ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, &pmk, sizeof(pmk)); if (err < 0) bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n", - pmk_len); + key_len); return err; } +BRCMF_EXPORT_SYMBOL_GPL(brcmf_set_wsec); -static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data, - u16 pwd_len) +static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) { - struct brcmf_pub *drvr = ifp->drvr; - struct brcmf_wsec_sae_pwd_le sae_pwd; - int err; - - if (pwd_len > BRCMF_WSEC_MAX_SAE_PASSWORD_LEN) { - bphy_err(drvr, "sae_password must be less than %d\n", - BRCMF_WSEC_MAX_SAE_PASSWORD_LEN); - return -EINVAL; - } - - sae_pwd.key_len = cpu_to_le16(pwd_len); - memcpy(sae_pwd.key, pwd_data, pwd_len); - - err = brcmf_fil_iovar_data_set(ifp, "sae_password", &sae_pwd, - sizeof(sae_pwd)); - if (err < 0) - bphy_err(drvr, "failed to set SAE password in firmware (len=%u)\n", - pwd_len); - - return err; + return brcmf_set_wsec(ifp, pmk_data, pmk_len, 0); } static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason, @@ -2114,7 +2105,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) if (!sme->crypto.n_akm_suites) return 0; - err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val); + err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), + "wpa_auth", &val); if (err) { bphy_err(drvr, "could not get wpa_auth (%d)\n", err); return err; @@ -2503,8 +2495,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, bphy_err(drvr, "failed to clean up user-space RSNE\n"); goto done; } - err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd, - sme->crypto.sae_pwd_len); + err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto); if (!err && sme->crypto.psk) err = brcmf_set_pmk(ifp, sme->crypto.psk, BRCMF_WSEC_MAX_PSK_LEN); @@ -2689,12 +2680,12 @@ done: static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - s32 *dbm) + unsigned int link_id, s32 *dbm) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); struct brcmf_pub *drvr = cfg->pub; - s32 qdbm = 0; + s32 qdbm; s32 err; brcmf_dbg(TRACE, "Enter\n"); @@ -4085,7 +4076,7 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp) struct cfg80211_wowlan_wakeup *wakeup; u32 wakeind; s32 err; - int timeout; + long time_left; err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le, sizeof(wake_ind_le)); @@ -4127,10 +4118,10 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp) } if (wakeind & BRCMF_WOWL_PFN_FOUND) { brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n"); - timeout = wait_event_timeout(cfg->wowl.nd_data_wait, - cfg->wowl.nd_data_completed, - BRCMF_ND_INFO_TIMEOUT); - if (!timeout) + time_left = wait_event_timeout(cfg->wowl.nd_data_wait, + cfg->wowl.nd_data_completed, + BRCMF_ND_INFO_TIMEOUT); + if (!time_left) bphy_err(drvr, "No result for wowl net detect\n"); else wakeup_data.net_detect = cfg->wowl.nd_info; @@ -4322,6 +4313,9 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa, int ret; pmk_op = kzalloc(sizeof(*pmk_op), GFP_KERNEL); + if (!pmk_op) + return -ENOMEM; + pmk_op->version = cpu_to_le16(BRCMF_PMKSA_VER_3); if (!pmksa) { @@ -4331,9 +4325,16 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa, /* Single PMK operation */ pmk_op->count = cpu_to_le16(1); length += sizeof(struct brcmf_pmksa_v3); - memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN); - memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN); - pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN; + if (pmksa->bssid) + memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN); + if (pmksa->pmkid) { + memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN); + pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN; + } + if (pmksa->ssid && pmksa->ssid_len) { + memcpy(pmk_op->pmk[0].ssid.SSID, pmksa->ssid, pmksa->ssid_len); + pmk_op->pmk[0].ssid.SSID_len = pmksa->ssid_len; + } pmk_op->pmk[0].time_left = cpu_to_le32(alive ? BRCMF_PMKSA_NO_EXPIRY : 0); } @@ -4560,7 +4561,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp, if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { err = -EINVAL; - bphy_err(drvr, "ivalid OUI\n"); + bphy_err(drvr, "invalid OUI\n"); goto exit; } offset += TLV_OUI_LEN; @@ -4599,7 +4600,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp, for (i = 0; i < count; i++) { if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { err = -EINVAL; - bphy_err(drvr, "ivalid OUI\n"); + bphy_err(drvr, "invalid OUI\n"); goto exit; } offset += TLV_OUI_LEN; @@ -4633,7 +4634,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp, for (i = 0; i < count; i++) { if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { err = -EINVAL; - bphy_err(drvr, "ivalid OUI\n"); + bphy_err(drvr, "invalid OUI\n"); goto exit; } offset += TLV_OUI_LEN; @@ -5002,12 +5003,16 @@ exit: s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif) { static const s32 pktflags[] = { - BRCMF_VNDR_IE_PRBREQ_FLAG, BRCMF_VNDR_IE_PRBRSP_FLAG, BRCMF_VNDR_IE_BEACON_FLAG }; int i; + if (vif->wdev.iftype == NL80211_IFTYPE_AP) + brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG, NULL, 0); + else + brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, NULL, 0); + for (i = 0; i < ARRAY_SIZE(pktflags); i++) brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0); @@ -5115,6 +5120,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, bool mbss; int is_11d; bool supports_11d; + bool closednet; brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", settings->chandef.chan->hw_value, @@ -5254,8 +5260,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, if (crypto->sae_pwd) { brcmf_dbg(INFO, "using SAE offload\n"); profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_SAE); - err = brcmf_set_sae_password(ifp, crypto->sae_pwd, - crypto->sae_pwd_len); + err = brcmf_fwvid_set_sae_password(ifp, crypto); if (err < 0) goto exit; } @@ -5285,12 +5290,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, goto exit; } - err = brcmf_fil_iovar_int_set(ifp, "closednet", - settings->hidden_ssid); + closednet = + (settings->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); + err = brcmf_fil_iovar_int_set(ifp, "closednet", closednet); if (err) { bphy_err(drvr, "%s closednet error (%d)\n", - settings->hidden_ssid ? - "enabled" : "disabled", + (closednet ? "enabled" : "disabled"), err); goto exit; } @@ -5362,10 +5367,12 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev, msleep(400); if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) { + struct cfg80211_crypto_settings crypto = {}; + if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK)) brcmf_set_pmk(ifp, NULL, 0); if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE)) - brcmf_set_sae_password(ifp, NULL, 0); + brcmf_fwvid_set_sae_password(ifp, &crypto); profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE); } @@ -7048,8 +7055,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, ch.bw = BRCMU_CHAN_BW_20; cfg->d11inf.encchspec(&ch); chaninfo = ch.chspec; - err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info", - &chaninfo); + err = brcmf_fil_bsscfg_int_query(ifp, "per_chan_info", + &chaninfo); if (!err) { if (chaninfo & WL_CHAN_RADAR) channel->flags |= @@ -7083,7 +7090,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) /* verify support for bw_cap command */ val = WLC_BAND_5G; - err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val); + err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &val); if (!err) { /* only set 2G bandwidth using bw_cap command */ @@ -7159,11 +7166,11 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) int err; band = WLC_BAND_2G; - err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band); if (!err) { bw_cap[NL80211_BAND_2GHZ] = band; band = WLC_BAND_5G; - err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band); if (!err) { bw_cap[NL80211_BAND_5GHZ] = band; return; @@ -7172,7 +7179,6 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) return; } brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n"); - mimo_bwcap = 0; err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap); if (err) /* assume 20MHz if firmware does not give a clue */ @@ -7268,7 +7274,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) struct brcmf_pub *drvr = cfg->pub; struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); struct wiphy *wiphy = cfg_to_wiphy(cfg); - u32 nmode = 0; + u32 nmode; u32 vhtmode = 0; u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; u32 rxchain; @@ -7410,6 +7416,8 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { * p2p, rsdb, and no mbss: * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2, * channels = 2, 4 total + * + * Return: 0 on success, negative errno on failure */ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) { @@ -7822,13 +7830,6 @@ s32 brcmf_cfg80211_down(struct net_device *ndev) return err; } -enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp) -{ - struct wireless_dev *wdev = &ifp->vif->wdev; - - return wdev->iftype; -} - bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state) { @@ -8437,6 +8438,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) brcmf_btcoex_detach(cfg); wiphy_unregister(cfg->wiphy); wl_deinit_priv(cfg); + cancel_work_sync(&cfg->escan_timeout_work); brcmf_free_wiphy(cfg->wiphy); kfree(cfg); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index 0e1fa3f0dea2..2abae8894614 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -443,7 +443,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); s32 brcmf_cfg80211_up(struct net_device *ndev); s32 brcmf_cfg80211_down(struct net_device *ndev); struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings); -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); @@ -468,4 +467,6 @@ void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); void brcmf_cfg80211_free_netdev(struct net_device *ndev); +int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 flags); + #endif /* BRCMFMAC_CFG80211_H */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index b6d458e022fa..cfcf01eb0daa 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -266,7 +266,7 @@ static int brcmf_c_process_cal_blob(struct brcmf_if *ifp) int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) { struct brcmf_pub *drvr = ifp->drvr; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + struct brcmf_fweh_info *fweh = drvr->fweh; u8 buf[BRCMF_DCMD_SMLEN]; struct brcmf_bus *bus; struct brcmf_rev_info_le revinfo; @@ -413,15 +413,21 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) brcmf_c_set_joinpref_default(ifp); /* Setup event_msgs, enable E_IF */ - err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, - BRCMF_EVENTING_MASK_LEN); + err = brcmf_fil_iovar_data_get(ifp, "event_msgs", fweh->event_mask, + fweh->event_mask_len); if (err) { bphy_err(drvr, "Get event_msgs error (%d)\n", err); goto done; } - setbit(eventmask, BRCMF_E_IF); - err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, - BRCMF_EVENTING_MASK_LEN); + /* + * BRCMF_E_IF can safely be used to set the appropriate bit + * in the event_mask as the firmware event code is guaranteed + * to match the value of BRCMF_E_IF because it is old cruft + * that all vendors have. + */ + setbit(fweh->event_mask, BRCMF_E_IF); + err = brcmf_fil_iovar_data_set(ifp, "event_msgs", fweh->event_mask, + fweh->event_mask_len); if (err) { bphy_err(drvr, "Set event_msgs error (%d)\n", err); goto done; @@ -555,7 +561,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, if (!found) { /* No platform data for this device, try OF and DMI data */ brcmf_dmi_probe(settings, chip, chiprev); - brcmf_of_probe(dev, bus_type, settings); + if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER) + return ERR_PTR(-EPROBE_DEFER); brcmf_acpi_probe(dev, bus_type, settings); } return settings; @@ -587,7 +594,7 @@ static void brcmf_common_pd_remove(struct platform_device *pdev) } static struct platform_driver brcmf_pd = { - .remove_new = brcmf_common_pd_remove, + .remove = brcmf_common_pd_remove, .driver = { .name = BRCMFMAC_PDATA_NAME, } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index f599d5f896e8..3d63010ae079 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -327,8 +327,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); - brcmf_dbg(INFO, "%s: insufficient headroom (%d)\n", - brcmf_ifname(ifp), head_delta); + brcmf_dbg(INFO, "%s: %s headroom\n", brcmf_ifname(ifp), + head_delta ? "insufficient" : "unmodifiable"); atomic_inc(&drvr->bus_if->stats.pktcowed); ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0, GFP_ATOMIC); @@ -540,6 +540,11 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) struct ethhdr *eh; u16 type; + if (!ifp) { + brcmu_pkt_buf_free_skb(txp); + return; + } + eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); @@ -1184,7 +1189,6 @@ static ssize_t bus_reset_write(struct file *file, const char __user *user_buf, static const struct file_operations bus_reset_fops = { .open = simple_open, - .llseek = no_llseek, .write = bus_reset_write, }; @@ -1348,13 +1352,17 @@ int brcmf_attach(struct device *dev) goto fail; } + /* attach firmware event handler */ + ret = brcmf_fweh_attach(drvr); + if (ret != 0) { + bphy_err(drvr, "brcmf_fweh_attach failed\n"); + goto fail; + } + /* Attach to events important for core code */ brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, brcmf_psm_watchdog_notify); - /* attach firmware event handler */ - brcmf_fweh_attach(drvr); - ret = brcmf_bus_started(drvr, drvr->ops); if (ret != 0) { bphy_err(drvr, "dongle is not responding: err=%d\n", ret); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index e4f911dd414b..d53839f855d7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -14,7 +14,7 @@ #include "fweh.h" #if IS_MODULE(CONFIG_BRCMFMAC) -#define BRCMF_EXPORT_SYMBOL_GPL(__sym) EXPORT_SYMBOL_NS_GPL(__sym, BRCMFMAC) +#define BRCMF_EXPORT_SYMBOL_GPL(__sym) EXPORT_SYMBOL_NS_GPL(__sym, "BRCMFMAC") #else #define BRCMF_EXPORT_SYMBOL_GPL(__sym) #endif @@ -48,20 +48,20 @@ /** * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info * - * @pktslots: dynamic allocated array for ordering AMPDU packets. * @flow_id: AMPDU flow identifier. * @cur_idx: last AMPDU index from firmware. * @exp_idx: expected next AMPDU index. * @max_idx: maximum amount of packets per AMPDU. * @pend_pkts: number of packets currently in @pktslots. + * @pktslots: array for ordering AMPDU packets. */ struct brcmf_ampdu_rx_reorder { - struct sk_buff **pktslots; u8 flow_id; u8 cur_idx; u8 exp_idx; u8 max_idx; u8 pend_pkts; + struct sk_buff *pktslots[]; }; /* Forward decls for struct brcmf_pub (see below) */ @@ -122,7 +122,7 @@ struct brcmf_pub { struct mutex proto_block; unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; - struct brcmf_fweh_info fweh; + struct brcmf_fweh_info *fweh; struct brcmf_ampdu_rx_reorder *reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS]; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/Makefile index 5e1fddaff79e..33e86724ba14 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/Makefile @@ -3,9 +3,9 @@ # Copyright (c) 2022 Broadcom Corporation ccflags-y += \ - -I $(srctree)/$(src) \ - -I $(srctree)/$(src)/.. \ - -I $(srctree)/$(src)/../../include + -I $(src) \ + -I $(src)/.. \ + -I $(src)/../../include obj-m += brcmfmac-cyw.o brcmfmac-cyw-objs += \ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c index b75652ba9359..9a4837881486 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c @@ -7,21 +7,53 @@ #include <core.h> #include <bus.h> #include <fwvid.h> +#include <fwil.h> #include "vops.h" -static int brcmf_cyw_attach(struct brcmf_pub *drvr) +#define BRCMF_CYW_E_LAST 197 + +static int brcmf_cyw_set_sae_pwd(struct brcmf_if *ifp, + struct cfg80211_crypto_settings *crypto) { - pr_err("%s: executing\n", __func__); - return 0; + struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_wsec_sae_pwd_le sae_pwd; + u16 pwd_len = crypto->sae_pwd_len; + int err; + + if (pwd_len > BRCMF_WSEC_MAX_SAE_PASSWORD_LEN) { + bphy_err(drvr, "sae_password must be less than %d\n", + BRCMF_WSEC_MAX_SAE_PASSWORD_LEN); + return -EINVAL; + } + + sae_pwd.key_len = cpu_to_le16(pwd_len); + memcpy(sae_pwd.key, crypto->sae_pwd, pwd_len); + + err = brcmf_fil_iovar_data_set(ifp, "sae_password", &sae_pwd, + sizeof(sae_pwd)); + if (err < 0) + bphy_err(drvr, "failed to set SAE password in firmware (len=%u)\n", + pwd_len); + + return err; } -static void brcmf_cyw_detach(struct brcmf_pub *drvr) +static int brcmf_cyw_alloc_fweh_info(struct brcmf_pub *drvr) { - pr_err("%s: executing\n", __func__); + struct brcmf_fweh_info *fweh; + + fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_CYW_E_LAST), + GFP_KERNEL); + if (!fweh) + return -ENOMEM; + + fweh->num_event_codes = BRCMF_CYW_E_LAST; + drvr->fweh = fweh; + return 0; } const struct brcmf_fwvid_ops brcmf_cyw_ops = { - .attach = brcmf_cyw_attach, - .detach = brcmf_cyw_detach, + .set_sae_password = brcmf_cyw_set_sae_pwd, + .alloc_fweh_info = brcmf_cyw_alloc_fweh_info, }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c index 90d06cda03a2..ce5fcfd42a7e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_cyw_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Cypress/Infineon chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_cyw_init); module_exit(brcmf_cyw_exit); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c index 86ff174936a9..c3a602197662 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c @@ -83,6 +83,15 @@ static const struct dmi_system_id dmi_platform_data[] = { .driver_data = (void *)&acepc_t8_data, }, { + /* ACEPC W5 Pro Cherry Trail Z8350 HDMI stick, same wifi as the T8 */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), + DMI_MATCH(DMI_CHASSIS_TYPE, "3"), + DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), + }, + .driver_data = (void *)&acepc_t8_data, + }, + { /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ .matches = { DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Hampoo"), diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index 6d10c9efbe93..0d9ae197fa1e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -13,6 +13,7 @@ #include "debug.h" #include "fwil.h" #include "fwil_types.h" +#include "fwvid.h" #include "feature.h" #include "common.h" @@ -339,6 +340,11 @@ void brcmf_feat_attach(struct brcmf_pub *drvr) brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_SCAN_V2, "scan_ver"); + brcmf_feat_wlc_version_overrides(drvr); + brcmf_feat_firmware_overrides(drvr); + + brcmf_fwvid_feat_attach(ifp); + if (drvr->settings->feature_disable) { brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n", ifp->drvr->feat_flags, @@ -346,9 +352,6 @@ void brcmf_feat_attach(struct brcmf_pub *drvr) ifp->drvr->feat_flags &= ~drvr->settings->feature_disable; } - brcmf_feat_wlc_version_overrides(drvr); - brcmf_feat_firmware_overrides(drvr); - /* set chip related quirks */ switch (drvr->bus_if->chip) { case BRCM_CC_43236_CHIP_ID: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c index 68960ae98987..f0b6a7607f16 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c @@ -14,7 +14,8 @@ #include "fweh.h" #include "fwil.h" #include "proto.h" - +#include "bus.h" +#include "fwvid.h" /** * struct brcmf_fweh_queue_item - event item on event queue. * @@ -28,7 +29,7 @@ */ struct brcmf_fweh_queue_item { struct list_head q; - enum brcmf_fweh_event_code code; + u32 code; u8 ifidx; u8 ifaddr[ETH_ALEN]; struct brcmf_event_msg_be emsg; @@ -94,7 +95,7 @@ static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh, static int brcmf_fweh_call_event_handler(struct brcmf_pub *drvr, struct brcmf_if *ifp, - enum brcmf_fweh_event_code code, + u32 fwcode, struct brcmf_event_msg *emsg, void *data) { @@ -102,13 +103,13 @@ static int brcmf_fweh_call_event_handler(struct brcmf_pub *drvr, int err = -EINVAL; if (ifp) { - fweh = &ifp->drvr->fweh; + fweh = ifp->drvr->fweh; /* handle the event if valid interface and handler */ - if (fweh->evt_handler[code]) - err = fweh->evt_handler[code](ifp, emsg, data); + if (fweh->evt_handler[fwcode]) + err = fweh->evt_handler[fwcode](ifp, emsg, data); else - bphy_err(drvr, "unhandled event %d ignored\n", code); + bphy_err(drvr, "unhandled fwevt %d ignored\n", fwcode); } else { bphy_err(drvr, "no interface object\n"); } @@ -142,7 +143,7 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, is_p2pdev = ((ifevent->flags & BRCMF_E_IF_FLAG_NOIF) && (ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT || ((ifevent->role == BRCMF_E_IF_ROLE_STA) && - (drvr->fweh.p2pdev_setup_ongoing)))); + (drvr->fweh->p2pdev_setup_ongoing)))); if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { brcmf_dbg(EVENT, "event can be ignored\n"); return; @@ -163,7 +164,7 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, return; if (!is_p2pdev) brcmf_proto_add_if(drvr, ifp); - if (!drvr->fweh.evt_handler[BRCMF_E_IF]) + if (!drvr->fweh->evt_handler[BRCMF_E_IF]) if (brcmf_net_attach(ifp, false) < 0) return; } @@ -183,6 +184,45 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, } } +static void brcmf_fweh_map_event_code(struct brcmf_fweh_info *fweh, + enum brcmf_fweh_event_code code, + u32 *fw_code) +{ + int i; + + if (WARN_ON(!fw_code)) + return; + + *fw_code = code; + if (fweh->event_map) { + for (i = 0; i < fweh->event_map->n_items; i++) { + if (fweh->event_map->items[i].code == code) { + *fw_code = fweh->event_map->items[i].fwevt_code; + break; + } + } + } +} + +static void brcmf_fweh_map_fwevt_code(struct brcmf_fweh_info *fweh, u32 fw_code, + enum brcmf_fweh_event_code *code) +{ + int i; + + if (WARN_ON(!code)) + return; + + *code = fw_code; + if (fweh->event_map) { + for (i = 0; i < fweh->event_map->n_items; i++) { + if (fweh->event_map->items[i].fwevt_code == fw_code) { + *code = fweh->event_map->items[i].code; + break; + } + } + } +} + /** * brcmf_fweh_dequeue_event() - get event from the queue. * @@ -221,15 +261,19 @@ static void brcmf_fweh_event_worker(struct work_struct *work) struct brcmf_event_msg emsg; fweh = container_of(work, struct brcmf_fweh_info, event_work); - drvr = container_of(fweh, struct brcmf_pub, fweh); + drvr = fweh->drvr; while ((event = brcmf_fweh_dequeue_event(fweh))) { - brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n", - brcmf_fweh_event_name(event->code), event->code, + enum brcmf_fweh_event_code code; + + brcmf_fweh_map_fwevt_code(fweh, event->code, &code); + brcmf_dbg(EVENT, "event %s (%u:%u) ifidx %u bsscfg %u addr %pM\n", + brcmf_fweh_event_name(code), code, event->code, event->emsg.ifidx, event->emsg.bsscfgidx, event->emsg.addr); if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { - bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx); + bphy_err(drvr, "invalid bsscfg index: %u\n", + event->emsg.bsscfgidx); goto event_free; } @@ -237,7 +281,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work) emsg_be = &event->emsg; emsg.version = be16_to_cpu(emsg_be->version); emsg.flags = be16_to_cpu(emsg_be->flags); - emsg.event_code = event->code; + emsg.event_code = code; emsg.status = be32_to_cpu(emsg_be->status); emsg.reason = be32_to_cpu(emsg_be->reason); emsg.auth_type = be32_to_cpu(emsg_be->auth_type); @@ -283,7 +327,7 @@ event_free: */ void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing) { - ifp->drvr->fweh.p2pdev_setup_ongoing = ongoing; + ifp->drvr->fweh->p2pdev_setup_ongoing = ongoing; } /** @@ -291,12 +335,27 @@ void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing) * * @drvr: driver information object. */ -void brcmf_fweh_attach(struct brcmf_pub *drvr) +int brcmf_fweh_attach(struct brcmf_pub *drvr) { - struct brcmf_fweh_info *fweh = &drvr->fweh; + struct brcmf_fweh_info *fweh; + int err; + + err = brcmf_fwvid_alloc_fweh_info(drvr); + if (err < 0) + return err; + + fweh = drvr->fweh; + fweh->drvr = drvr; + + fweh->event_mask_len = DIV_ROUND_UP(fweh->num_event_codes, 8); + fweh->event_mask = kzalloc(fweh->event_mask_len, GFP_KERNEL); + if (!fweh->event_mask) + return -ENOMEM; + INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); spin_lock_init(&fweh->evt_q_lock); INIT_LIST_HEAD(&fweh->event_q); + return 0; } /** @@ -306,14 +365,19 @@ void brcmf_fweh_attach(struct brcmf_pub *drvr) */ void brcmf_fweh_detach(struct brcmf_pub *drvr) { - struct brcmf_fweh_info *fweh = &drvr->fweh; + struct brcmf_fweh_info *fweh = drvr->fweh; + + if (!fweh) + return; /* cancel the worker if initialized */ if (fweh->event_work.func) { cancel_work_sync(&fweh->event_work); WARN_ON(!list_empty(&fweh->event_q)); - memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); } + drvr->fweh = NULL; + kfree(fweh->event_mask); + kfree(fweh); } /** @@ -326,11 +390,17 @@ void brcmf_fweh_detach(struct brcmf_pub *drvr) int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, brcmf_fweh_handler_t handler) { - if (drvr->fweh.evt_handler[code]) { + struct brcmf_fweh_info *fweh = drvr->fweh; + u32 evt_handler_idx; + + brcmf_fweh_map_event_code(fweh, code, &evt_handler_idx); + + if (fweh->evt_handler[evt_handler_idx]) { bphy_err(drvr, "event code %d already registered\n", code); return -ENOSPC; } - drvr->fweh.evt_handler[code] = handler; + + fweh->evt_handler[evt_handler_idx] = handler; brcmf_dbg(TRACE, "event handler registered for %s\n", brcmf_fweh_event_name(code)); return 0; @@ -345,9 +415,12 @@ int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, void brcmf_fweh_unregister(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code) { + u32 evt_handler_idx; + brcmf_dbg(TRACE, "event handler cleared for %s\n", brcmf_fweh_event_name(code)); - drvr->fweh.evt_handler[code] = NULL; + brcmf_fweh_map_event_code(drvr->fweh, code, &evt_handler_idx); + drvr->fweh->evt_handler[evt_handler_idx] = NULL; } /** @@ -357,27 +430,28 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr, */ int brcmf_fweh_activate_events(struct brcmf_if *ifp) { - struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_fweh_info *fweh = ifp->drvr->fweh; + enum brcmf_fweh_event_code code; int i, err; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - memset(eventmask, 0, sizeof(eventmask)); - for (i = 0; i < BRCMF_E_LAST; i++) { - if (ifp->drvr->fweh.evt_handler[i]) { + memset(fweh->event_mask, 0, fweh->event_mask_len); + for (i = 0; i < fweh->num_event_codes; i++) { + if (fweh->evt_handler[i]) { + brcmf_fweh_map_fwevt_code(fweh, i, &code); brcmf_dbg(EVENT, "enable event %s\n", - brcmf_fweh_event_name(i)); - setbit(eventmask, i); + brcmf_fweh_event_name(code)); + setbit(fweh->event_mask, i); } } /* want to handle IF event as well */ brcmf_dbg(EVENT, "enable event IF\n"); - setbit(eventmask, BRCMF_E_IF); + setbit(fweh->event_mask, BRCMF_E_IF); - err = brcmf_fil_iovar_data_set(ifp, "event_msgs", - eventmask, BRCMF_EVENTING_MASK_LEN); + err = brcmf_fil_iovar_data_set(ifp, "event_msgs", fweh->event_mask, + fweh->event_mask_len); if (err) - bphy_err(drvr, "Set event_msgs error (%d)\n", err); + bphy_err(fweh->drvr, "Set event_msgs error (%d)\n", err); return err; } @@ -397,21 +471,21 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, struct brcmf_event *event_packet, u32 packet_len, gfp_t gfp) { - enum brcmf_fweh_event_code code; - struct brcmf_fweh_info *fweh = &drvr->fweh; + u32 fwevt_idx; + struct brcmf_fweh_info *fweh = drvr->fweh; struct brcmf_fweh_queue_item *event; void *data; u32 datalen; /* get event info */ - code = get_unaligned_be32(&event_packet->msg.event_type); + fwevt_idx = get_unaligned_be32(&event_packet->msg.event_type); datalen = get_unaligned_be32(&event_packet->msg.datalen); data = &event_packet[1]; - if (code >= BRCMF_E_LAST) + if (fwevt_idx >= fweh->num_event_codes) return; - if (code != BRCMF_E_IF && !fweh->evt_handler[code]) + if (fwevt_idx != BRCMF_E_IF && !fweh->evt_handler[fwevt_idx]) return; if (datalen > BRCMF_DCMD_MAXLEN || @@ -422,8 +496,8 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, if (!event) return; + event->code = fwevt_idx; event->datalen = datalen; - event->code = code; event->ifidx = event_packet->msg.ifidx; /* use memcpy to get aligned event message */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h index 48414e8b9389..eed439b84010 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h @@ -7,7 +7,7 @@ #ifndef FWEH_H_ #define FWEH_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/skbuff.h> #include <linux/if_ether.h> #include <linux/if.h> @@ -17,6 +17,10 @@ struct brcmf_pub; struct brcmf_if; struct brcmf_cfg80211_info; +#define BRCMF_ABSTRACT_EVENT_BIT BIT(31) +#define BRCMF_ABSTRACT_ENUM_DEF(_id, _val) \ + BRCMF_ENUM_DEF(_id, (BRCMF_ABSTRACT_EVENT_BIT | (_val))) + /* list of firmware events */ #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ BRCMF_ENUM_DEF(SET_SSID, 0) \ @@ -98,16 +102,9 @@ struct brcmf_cfg80211_info; /* firmware event codes sent by the dongle */ enum brcmf_fweh_event_code { BRCMF_FWEH_EVENT_ENUM_DEFLIST - /* this determines event mask length which must match - * minimum length check in device firmware so it is - * hard-coded here. - */ - BRCMF_E_LAST = 139 }; #undef BRCMF_ENUM_DEF -#define BRCMF_EVENTING_MASK_LEN DIV_ROUND_UP(BRCMF_E_LAST, 8) - /* flags field values in struct brcmf_event_msg */ #define BRCMF_EVENT_MSG_LINK 0x01 #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 @@ -288,27 +285,66 @@ typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, void *data); /** + * struct brcmf_fweh_event_map_item - fweh event and firmware event pair. + * + * @code: fweh event code as used by higher layers. + * @fwevt_code: firmware event code as used by firmware. + * + * This mapping is needed when a functionally identical event has a + * different numerical definition between vendors. When such mapping + * is needed the higher layer event code should not collide with the + * firmware event. + */ +struct brcmf_fweh_event_map_item { + enum brcmf_fweh_event_code code; + u32 fwevt_code; +}; + +/** + * struct brcmf_fweh_event_map - mapping between firmware event and fweh event. + * + * @n_items: number of mapping items. + * @items: array of fweh event and firmware event pairs. + */ +struct brcmf_fweh_event_map { + u32 n_items; + const struct brcmf_fweh_event_map_item items[] __counted_by(n_items); +}; + +/** * struct brcmf_fweh_info - firmware event handling information. * * @p2pdev_setup_ongoing: P2P device creation in progress. * @event_work: event worker. * @evt_q_lock: lock for event queue protection. * @event_q: event queue. - * @evt_handler: registered event handlers. + * @event_mask_len: length of @event_mask used to enable firmware events. + * @event_mask: byte array used in 'event_msgs' iovar command. + * @event_map: mapping between fweh event and firmware event which + * may be provided by vendor-specific module for events that need + * mapping. + * @num_event_codes: number of firmware events supported by firmware which + * does a minimum length check for the @event_mask. This value is to + * be provided by vendor-specific module determining @event_mask_len + * and consequently the allocation size for @event_mask. + * @evt_handler: event handler registry indexed by firmware event code. */ struct brcmf_fweh_info { + struct brcmf_pub *drvr; bool p2pdev_setup_ongoing; struct work_struct event_work; spinlock_t evt_q_lock; struct list_head event_q; - int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data); + uint event_mask_len; + u8 *event_mask; + struct brcmf_fweh_event_map *event_map; + uint num_event_codes; + brcmf_fweh_handler_t evt_handler[] __counted_by(num_event_codes); }; const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code); -void brcmf_fweh_attach(struct brcmf_pub *drvr); +int brcmf_fweh_attach(struct brcmf_pub *drvr); void brcmf_fweh_detach(struct brcmf_pub *drvr); int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, int (*handler)(struct brcmf_if *ifp, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c index 72fe8bce6eaf..6385a7db7f7d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c @@ -142,6 +142,7 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) return err; } +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_cmd_data_set); s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) @@ -160,36 +161,7 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) return err; } - - -s32 -brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data) -{ - s32 err; - __le32 data_le = cpu_to_le32(data); - - mutex_lock(&ifp->drvr->proto_block); - brcmf_dbg(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, data); - err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true); - mutex_unlock(&ifp->drvr->proto_block); - - return err; -} - -s32 -brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data) -{ - s32 err; - __le32 data_le = cpu_to_le32(*data); - - mutex_lock(&ifp->drvr->proto_block); - err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false); - mutex_unlock(&ifp->drvr->proto_block); - *data = le32_to_cpu(data_le); - brcmf_dbg(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, *data); - - return err; -} +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_cmd_data_get); static u32 brcmf_create_iovar(const char *name, const char *data, u32 datalen, @@ -239,6 +211,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, const char *name, const void *dat mutex_unlock(&drvr->proto_block); return err; } +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_iovar_data_set); s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, const char *name, void *data, @@ -270,26 +243,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, const char *name, void *data, mutex_unlock(&drvr->proto_block); return err; } - -s32 -brcmf_fil_iovar_int_set(struct brcmf_if *ifp, const char *name, u32 data) -{ - __le32 data_le = cpu_to_le32(data); - - return brcmf_fil_iovar_data_set(ifp, name, &data_le, sizeof(data_le)); -} - -s32 -brcmf_fil_iovar_int_get(struct brcmf_if *ifp, const char *name, u32 *data) -{ - __le32 data_le = cpu_to_le32(*data); - s32 err; - - err = brcmf_fil_iovar_data_get(ifp, name, &data_le, sizeof(data_le)); - if (err == 0) - *data = le32_to_cpu(data_le); - return err; -} +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_iovar_data_get); static u32 brcmf_create_bsscfg(s32 bsscfgidx, const char *name, char *data, u32 datalen, @@ -364,6 +318,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, const char *name, mutex_unlock(&drvr->proto_block); return err; } +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_bsscfg_data_set); s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, const char *name, @@ -394,28 +349,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, const char *name, mutex_unlock(&drvr->proto_block); return err; } - -s32 -brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, const char *name, u32 data) -{ - __le32 data_le = cpu_to_le32(data); - - return brcmf_fil_bsscfg_data_set(ifp, name, &data_le, - sizeof(data_le)); -} - -s32 -brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, const char *name, u32 *data) -{ - __le32 data_le = cpu_to_le32(*data); - s32 err; - - err = brcmf_fil_bsscfg_data_get(ifp, name, &data_le, - sizeof(data_le)); - if (err == 0) - *data = le32_to_cpu(data_le); - return err; -} +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_bsscfg_data_get); static u32 brcmf_create_xtlv(const char *name, u16 id, char *data, u32 len, char *buf, u32 buflen) @@ -465,6 +399,7 @@ s32 brcmf_fil_xtlv_data_set(struct brcmf_if *ifp, const char *name, u16 id, mutex_unlock(&drvr->proto_block); return err; } +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_xtlv_data_set); s32 brcmf_fil_xtlv_data_get(struct brcmf_if *ifp, const char *name, u16 id, void *data, u32 len) @@ -494,39 +429,4 @@ s32 brcmf_fil_xtlv_data_get(struct brcmf_if *ifp, const char *name, u16 id, mutex_unlock(&drvr->proto_block); return err; } - -s32 brcmf_fil_xtlv_int_set(struct brcmf_if *ifp, const char *name, u16 id, u32 data) -{ - __le32 data_le = cpu_to_le32(data); - - return brcmf_fil_xtlv_data_set(ifp, name, id, &data_le, - sizeof(data_le)); -} - -s32 brcmf_fil_xtlv_int_get(struct brcmf_if *ifp, const char *name, u16 id, u32 *data) -{ - __le32 data_le = cpu_to_le32(*data); - s32 err; - - err = brcmf_fil_xtlv_data_get(ifp, name, id, &data_le, sizeof(data_le)); - if (err == 0) - *data = le32_to_cpu(data_le); - return err; -} - -s32 brcmf_fil_xtlv_int8_get(struct brcmf_if *ifp, const char *name, u16 id, u8 *data) -{ - return brcmf_fil_xtlv_data_get(ifp, name, id, data, sizeof(*data)); -} - -s32 brcmf_fil_xtlv_int16_get(struct brcmf_if *ifp, const char *name, u16 id, u16 *data) -{ - __le16 data_le = cpu_to_le16(*data); - s32 err; - - err = brcmf_fil_xtlv_data_get(ifp, name, id, &data_le, sizeof(data_le)); - if (err == 0) - *data = le16_to_cpu(data_le); - return err; -} - +BRCMF_EXPORT_SYMBOL_GPL(brcmf_fil_xtlv_data_get); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h index bc693157c4b1..ab3d6cfcb02b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h @@ -6,6 +6,8 @@ #ifndef _fwil_h_ #define _fwil_h_ +#include "debug.h" + /******************************************************************************* * Dongle command codes that are interpreted by firmware ******************************************************************************/ @@ -81,29 +83,142 @@ s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); -s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); -s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data); +static inline +s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data) +{ + s32 err; + __le32 data_le = cpu_to_le32(data); -s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, const char *name, const void *data, - u32 len); + brcmf_dbg(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, data); + err = brcmf_fil_cmd_data_set(ifp, cmd, &data_le, sizeof(data_le)); + + return err; +} +static inline +s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data) +{ + s32 err; + + err = brcmf_fil_cmd_data_get(ifp, cmd, data, sizeof(*data)); + if (err == 0) + *data = le32_to_cpu(*(__le32 *)data); + brcmf_dbg(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, *data); + + return err; +} +static inline +s32 brcmf_fil_cmd_int_query(struct brcmf_if *ifp, u32 cmd, u32 *data) +{ + __le32 *data_le = (__le32 *)data; + + *data_le = cpu_to_le32(*data); + return brcmf_fil_cmd_int_get(ifp, cmd, data); +} + +s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, const char *name, + const void *data, u32 len); s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, const char *name, void *data, u32 len); -s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, const char *name, u32 data); -s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, const char *name, u32 *data); - -s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, const char *name, void *data, - u32 len); -s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, const char *name, void *data, - u32 len); -s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, const char *name, u32 data); -s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, const char *name, u32 *data); +static inline +s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, const char *name, u32 data) +{ + __le32 data_le = cpu_to_le32(data); + + return brcmf_fil_iovar_data_set(ifp, name, &data_le, sizeof(data_le)); +} +static inline +s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, const char *name, u32 *data) +{ + s32 err; + + err = brcmf_fil_iovar_data_get(ifp, name, data, sizeof(*data)); + if (err == 0) + *data = le32_to_cpu(*(__le32 *)data); + return err; +} +static inline +s32 brcmf_fil_iovar_int_query(struct brcmf_if *ifp, const char *name, u32 *data) +{ + __le32 *data_le = (__le32 *)data; + + *data_le = cpu_to_le32(*data); + return brcmf_fil_iovar_int_get(ifp, name, data); +} + + +s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, const char *name, + void *data, u32 len); +s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, const char *name, + void *data, u32 len); +static inline +s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, const char *name, u32 data) +{ + __le32 data_le = cpu_to_le32(data); + + return brcmf_fil_bsscfg_data_set(ifp, name, &data_le, + sizeof(data_le)); +} +static inline +s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, const char *name, u32 *data) +{ + s32 err; + + err = brcmf_fil_bsscfg_data_get(ifp, name, data, sizeof(*data)); + if (err == 0) + *data = le32_to_cpu(*(__le32 *)data); + return err; +} +static inline +s32 brcmf_fil_bsscfg_int_query(struct brcmf_if *ifp, const char *name, u32 *data) +{ + __le32 *data_le = (__le32 *)data; + + *data_le = cpu_to_le32(*data); + return brcmf_fil_bsscfg_int_get(ifp, name, data); +} + s32 brcmf_fil_xtlv_data_set(struct brcmf_if *ifp, const char *name, u16 id, void *data, u32 len); s32 brcmf_fil_xtlv_data_get(struct brcmf_if *ifp, const char *name, u16 id, void *data, u32 len); -s32 brcmf_fil_xtlv_int_set(struct brcmf_if *ifp, const char *name, u16 id, u32 data); -s32 brcmf_fil_xtlv_int_get(struct brcmf_if *ifp, const char *name, u16 id, u32 *data); -s32 brcmf_fil_xtlv_int8_get(struct brcmf_if *ifp, const char *name, u16 id, u8 *data); -s32 brcmf_fil_xtlv_int16_get(struct brcmf_if *ifp, const char *name, u16 id, u16 *data); +static inline +s32 brcmf_fil_xtlv_int_set(struct brcmf_if *ifp, const char *name, u16 id, + u32 data) +{ + __le32 data_le = cpu_to_le32(data); + + return brcmf_fil_xtlv_data_set(ifp, name, id, &data_le, + sizeof(data_le)); +} +static inline +s32 brcmf_fil_xtlv_int_get(struct brcmf_if *ifp, const char *name, u16 id, + u32 *data) +{ + __le32 data_le = cpu_to_le32(*data); + s32 err; + + err = brcmf_fil_xtlv_data_get(ifp, name, id, &data_le, sizeof(data_le)); + if (err == 0) + *data = le32_to_cpu(data_le); + return err; +} +static inline +s32 brcmf_fil_xtlv_int8_get(struct brcmf_if *ifp, const char *name, u16 id, + u8 *data) +{ + return brcmf_fil_xtlv_data_get(ifp, name, id, data, sizeof(*data)); +} +static inline +s32 brcmf_fil_xtlv_int16_get(struct brcmf_if *ifp, const char *name, u16 id, + u16 *data) +{ + __le16 data_le = cpu_to_le16(*data); + s32 err; + + err = brcmf_fil_xtlv_data_get(ifp, name, id, &data_le, sizeof(data_le)); + if (err == 0) + *data = le16_to_cpu(data_le); + return err; +} #endif /* _fwil_h_ */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index 9d248ba1c0b2..e74a23e11830 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -584,7 +584,7 @@ struct brcmf_wsec_key_le { struct brcmf_wsec_pmk_le { __le16 key_len; __le16 flags; - u8 key[2 * BRCMF_WSEC_MAX_PSK_LEN + 1]; + u8 key[BRCMF_WSEC_MAX_SAE_PASSWORD_LEN]; }; /** diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 36af81975855..b70d20128f98 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -1673,7 +1673,6 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) struct sk_buff_head reorder_list; struct sk_buff *pnext; u8 flags; - u32 buf_size; reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder; flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET]; @@ -1708,15 +1707,13 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) } /* from here on we need a flow reorder instance */ if (rfi == NULL) { - buf_size = sizeof(*rfi); max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; - buf_size += (max_idx + 1) * sizeof(pkt); - /* allocate space for flow reorder info */ brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", flow_id, max_idx); - rfi = kzalloc(buf_size, GFP_ATOMIC); + rfi = kzalloc(struct_size(rfi, pktslots, max_idx + 1), + GFP_ATOMIC); if (rfi == NULL) { bphy_err(drvr, "failed to alloc buffer\n"); brcmf_netif_rx(ifp, pkt); @@ -1724,7 +1721,6 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) } ifp->drvr->reorder_flows[flow_id] = rfi; - rfi->pktslots = (struct sk_buff **)(rfi + 1); rfi->max_idx = max_idx; } if (flags & BRCMF_RXREORDER_NEW_HOLE) { @@ -1814,7 +1810,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) rfi->cur_idx = cur_idx; } } else { - /* explicity window move updating the expected index */ + /* explicitly window move updating the expected index */ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n", diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.c index 86eafdb40541..41eafcda77f7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.c @@ -90,7 +90,7 @@ int brcmf_fwvid_register_vendor(enum brcmf_fwvendor fwvid, struct module *vmod, return -ERANGE; if (WARN_ON(!vmod) || WARN_ON(!vops) || - WARN_ON(!vops->attach) || WARN_ON(!vops->detach)) + WARN_ON(!vops->alloc_fweh_info)) return -EINVAL; if (WARN_ON(fwvid_list[fwvid].vmod)) @@ -150,7 +150,7 @@ static inline int brcmf_fwvid_request_module(enum brcmf_fwvendor fwvid) } #endif -int brcmf_fwvid_attach_ops(struct brcmf_pub *drvr) +int brcmf_fwvid_attach(struct brcmf_pub *drvr) { enum brcmf_fwvendor fwvid = drvr->bus_if->fwvid; int ret; @@ -175,7 +175,7 @@ int brcmf_fwvid_attach_ops(struct brcmf_pub *drvr) return ret; } -void brcmf_fwvid_detach_ops(struct brcmf_pub *drvr) +void brcmf_fwvid_detach(struct brcmf_pub *drvr) { enum brcmf_fwvendor fwvid = drvr->bus_if->fwvid; @@ -187,9 +187,10 @@ void brcmf_fwvid_detach_ops(struct brcmf_pub *drvr) mutex_lock(&fwvid_list_lock); - drvr->vops = NULL; - list_del(&drvr->bus_if->list); - + if (drvr->vops) { + drvr->vops = NULL; + list_del(&drvr->bus_if->list); + } mutex_unlock(&fwvid_list_lock); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h index 43df58bb70ad..e6ac9fc341bc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h @@ -6,12 +6,15 @@ #define FWVID_H_ #include "firmware.h" +#include "cfg80211.h" struct brcmf_pub; +struct brcmf_if; struct brcmf_fwvid_ops { - int (*attach)(struct brcmf_pub *drvr); - void (*detach)(struct brcmf_pub *drvr); + void (*feat_attach)(struct brcmf_if *ifp); + int (*set_sae_password)(struct brcmf_if *ifp, struct cfg80211_crypto_settings *crypto); + int (*alloc_fweh_info)(struct brcmf_pub *drvr); }; /* exported functions */ @@ -20,28 +23,37 @@ int brcmf_fwvid_register_vendor(enum brcmf_fwvendor fwvid, struct module *mod, int brcmf_fwvid_unregister_vendor(enum brcmf_fwvendor fwvid, struct module *mod); /* core driver functions */ -int brcmf_fwvid_attach_ops(struct brcmf_pub *drvr); -void brcmf_fwvid_detach_ops(struct brcmf_pub *drvr); +int brcmf_fwvid_attach(struct brcmf_pub *drvr); +void brcmf_fwvid_detach(struct brcmf_pub *drvr); const char *brcmf_fwvid_vendor_name(struct brcmf_pub *drvr); -static inline int brcmf_fwvid_attach(struct brcmf_pub *drvr) +static inline void brcmf_fwvid_feat_attach(struct brcmf_if *ifp) { - int ret; + const struct brcmf_fwvid_ops *vops = ifp->drvr->vops; - ret = brcmf_fwvid_attach_ops(drvr); - if (ret) - return ret; + if (!vops->feat_attach) + return; - return drvr->vops->attach(drvr); + vops->feat_attach(ifp); } -static inline void brcmf_fwvid_detach(struct brcmf_pub *drvr) +static inline int brcmf_fwvid_set_sae_password(struct brcmf_if *ifp, + struct cfg80211_crypto_settings *crypto) +{ + const struct brcmf_fwvid_ops *vops = ifp->drvr->vops; + + if (!vops || !vops->set_sae_password) + return -EOPNOTSUPP; + + return vops->set_sae_password(ifp, crypto); +} + +static inline int brcmf_fwvid_alloc_fweh_info(struct brcmf_pub *drvr) { if (!drvr->vops) - return; + return -EIO; - drvr->vops->detach(drvr); - brcmf_fwvid_detach_ops(drvr); + return drvr->vops->alloc_fweh_info(drvr); } #endif /* FWVID_H_ */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index e406e11481a6..1681ad00f82e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -6,6 +6,7 @@ #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_net.h> +#include <linux/clk.h> #include <defs.h> #include "debug.h" @@ -65,11 +66,13 @@ static int brcmf_of_get_country_codes(struct device *dev, return 0; } -void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings) +int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; struct device_node *root, *np = dev->of_node; + struct of_phandle_args oirq; + struct clk *clk; const char *prop; int irq; int err; @@ -96,25 +99,30 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, /* Set board-type to the first string of the machine compatible prop */ root = of_find_node_by_path("/"); if (root && err) { - char *board_type; + char *board_type = NULL; const char *tmp; - of_property_read_string_index(root, "compatible", 0, &tmp); - /* get rid of '/' in the compatible string to be able to find the FW */ - board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); + if (!of_property_read_string_index(root, "compatible", 0, &tmp)) + board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); + if (!board_type) { of_node_put(root); - return; + return 0; } strreplace(board_type, '/', '-'); settings->board_type = board_type; - - of_node_put(root); } + of_node_put(root); + + clk = devm_clk_get_optional_enabled_with_rate(dev, "lpo", 32768); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no"); if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) - return; + return 0; err = brcmf_of_get_country_codes(dev, settings); if (err) @@ -123,23 +131,25 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, of_get_mac_address(np, settings->mac); if (bus_type != BRCMF_BUSTYPE_SDIO) - return; + return 0; if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) sdio->drive_strength = val; /* make sure there are interrupts defined in the node */ - if (!of_property_present(np, "interrupts")) - return; + if (of_irq_parse_one(np, 0, &oirq)) + return 0; - irq = irq_of_parse_and_map(np, 0); + irq = irq_create_of_mapping(&oirq); if (!irq) { brcmf_err("interrupt could not be mapped\n"); - return; + return 0; } - irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); + irqf = irq_get_trigger_type(irq); sdio->oob_irq_supported = true; sdio->oob_irq_nr = irq; sdio->oob_irq_flags = irqf; + + return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h index 10bf52253337..ae124c73fc3b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h @@ -3,11 +3,12 @@ * Copyright (c) 2014 Broadcom Corporation */ #ifdef CONFIG_OF -void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings); +int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings); #else -static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings) +static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { + return 0; } #endif /* CONFIG_OF */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index d7fb88bb6ae1..d2caa80e9412 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -16,7 +16,7 @@ #include <linux/kthread.h> #include <linux/io.h> #include <linux/random.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <soc.h> #include <chipcommon.h> @@ -66,6 +66,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); +BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-pcie"); BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie"); BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie"); BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie"); @@ -104,6 +105,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C), BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), + BRCMF_FW_ENTRY(BRCM_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752), BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */ @@ -313,11 +315,6 @@ struct brcmf_pcie_shared_info { u8 version; }; -struct brcmf_pcie_core_info { - u32 base; - u32 wrapbase; -}; - #define BRCMF_OTP_MAX_PARAM_LEN 16 struct brcmf_otp_params { @@ -358,6 +355,7 @@ struct brcmf_pciedev_info { u16 value); struct brcmf_mp_device *settings; struct brcmf_otp_params otp; + bool fwseed; #ifdef DEBUG u32 console_interval; bool console_active; @@ -1675,6 +1673,15 @@ struct brcmf_random_seed_footer { #define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de #define BRCMF_RANDOM_SEED_LENGTH 0x100 +static noinline_for_stack void +brcmf_pcie_provide_random_bytes(struct brcmf_pciedev_info *devinfo, u32 address) +{ + u8 randbuf[BRCMF_RANDOM_SEED_LENGTH]; + + get_random_bytes(randbuf, BRCMF_RANDOM_SEED_LENGTH); + memcpy_toio(devinfo->tcm + address, randbuf, BRCMF_RANDOM_SEED_LENGTH); +} + static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, const struct firmware *fw, void *nvram, u32 nvram_len) @@ -1711,15 +1718,14 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, memcpy_toio(devinfo->tcm + address, nvram, nvram_len); brcmf_fw_nvram_free(nvram); - if (devinfo->otp.valid) { + if (devinfo->fwseed) { size_t rand_len = BRCMF_RANDOM_SEED_LENGTH; struct brcmf_random_seed_footer footer = { .length = cpu_to_le32(rand_len), .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), }; - void *randbuf; - /* Some Apple chips/firmwares expect a buffer of random + /* Some chips/firmwares expect a buffer of random * data to be present before NVRAM */ brcmf_dbg(PCIE, "Download random seed\n"); @@ -1729,10 +1735,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, sizeof(footer)); address -= rand_len; - randbuf = kzalloc(rand_len, GFP_KERNEL); - get_random_bytes(randbuf, rand_len); - memcpy_toio(devinfo->tcm + address, randbuf, rand_len); - kfree(randbuf); + brcmf_pcie_provide_random_bytes(devinfo, address); } } else { brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", @@ -2394,6 +2397,37 @@ static void brcmf_pcie_debugfs_create(struct device *dev) } #endif +struct brcmf_pcie_drvdata { + enum brcmf_fwvendor vendor; + bool fw_seed; +}; + +enum { + BRCMF_DRVDATA_CYW, + BRCMF_DRVDATA_BCA, + BRCMF_DRVDATA_WCC, + BRCMF_DRVDATA_WCC_SEED, +}; + +static const struct brcmf_pcie_drvdata drvdata[] = { + [BRCMF_DRVDATA_CYW] = { + .vendor = BRCMF_FWVENDOR_CYW, + .fw_seed = false, + }, + [BRCMF_DRVDATA_BCA] = { + .vendor = BRCMF_FWVENDOR_BCA, + .fw_seed = false, + }, + [BRCMF_DRVDATA_WCC] = { + .vendor = BRCMF_FWVENDOR_WCC, + .fw_seed = false, + }, + [BRCMF_DRVDATA_WCC_SEED] = { + .vendor = BRCMF_FWVENDOR_WCC, + .fw_seed = true, + }, +}; + /* Forward declaration for pci_match_id() call */ static const struct pci_device_id brcmf_pcie_devid_table[]; @@ -2452,6 +2486,9 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = -ENOMEM; goto fail; } + ret = PTR_ERR_OR_ZERO(devinfo->settings); + if (ret < 0) + goto fail; bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (!bus) { @@ -2472,9 +2509,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) bus->bus_priv.pcie = pcie_bus_dev; bus->ops = &brcmf_pcie_bus_ops; bus->proto_type = BRCMF_PROTO_MSGBUF; - bus->fwvid = id->driver_data; bus->chip = devinfo->coreid; bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); + bus->fwvid = drvdata[id->driver_data].vendor; + devinfo->fwseed = drvdata[id->driver_data].fw_seed; dev_set_drvdata(&pdev->dev, bus); ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); @@ -2660,21 +2698,21 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = { BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ PCI_ANY_ID, PCI_ANY_ID, \ PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ - BRCMF_FWVENDOR_ ## fw_vend \ + BRCMF_DRVDATA_ ## fw_vend \ } #define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev, fw_vend) \ { \ BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ (subvend), (subdev), \ PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ - BRCMF_FWVENDOR_ ## fw_vend \ + BRCMF_DRVDATA_ ## fw_vend \ } static const struct pci_device_id brcmf_pcie_devid_table[] = { BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4355_DEVICE_ID, WCC), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4355_DEVICE_ID, WCC_SEED), BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID, WCC), @@ -2685,7 +2723,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4364_DEVICE_ID, WCC), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4364_DEVICE_ID, WCC_SEED), BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID, BCA), BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID, BCA), BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID, BCA), @@ -2695,9 +2733,10 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA), BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC_SEED), { /* end: all zeroes */ } }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 6b38d9de71af..b1727f35217b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -23,7 +23,7 @@ #include <linux/bcma/bcma.h> #include <linux/debugfs.h> #include <linux/vmalloc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <defs.h> #include <brcmu_wifi.h> #include <brcmu_utils.h> @@ -3943,7 +3943,7 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { .write32 = brcmf_sdio_buscore_write32, }; -static bool +static int brcmf_sdio_probe_attach(struct brcmf_sdio *bus) { struct brcmf_sdio_dev *sdiodev; @@ -3953,6 +3953,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) u32 reg_val; u32 drivestrength; u32 enum_base; + int ret = -EBADE; sdiodev = bus->sdiodev; sdio_claim_host(sdiodev->func1); @@ -4001,8 +4002,9 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) BRCMF_BUSTYPE_SDIO, bus->ci->chip, bus->ci->chiprev); - if (!sdiodev->settings) { + if (IS_ERR_OR_NULL(sdiodev->settings)) { brcmf_err("Failed to get device parameters\n"); + ret = PTR_ERR_OR_ZERO(sdiodev->settings); goto fail; } /* platform specific configuration: @@ -4071,7 +4073,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) /* allocate header buffer */ bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL); if (!bus->hdrbuf) - return false; + return -ENOMEM; /* Locate an appropriately-aligned portion of hdrbuf */ bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], bus->head_align); @@ -4082,11 +4084,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) if (bus->poll) bus->pollrate = 1; - return true; + return 0; fail: sdio_release_host(sdiodev->func1); - return false; + return ret; } static int @@ -4450,9 +4452,11 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) brcmf_dbg(TRACE, "Enter\n"); /* Allocate private bus interface state */ - bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC); - if (!bus) + bus = kzalloc(sizeof(*bus), GFP_ATOMIC); + if (!bus) { + ret = -ENOMEM; goto fail; + } bus->sdiodev = sdiodev; sdiodev->bus = bus; @@ -4467,6 +4471,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) dev_name(&sdiodev->func1->dev)); if (!wq) { brcmf_err("insufficient memory to create txworkqueue\n"); + ret = -ENOMEM; goto fail; } brcmf_sdiod_freezer_count(sdiodev); @@ -4474,7 +4479,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) bus->brcmf_wq = wq; /* attempt to attach to the dongle */ - if (!(brcmf_sdio_probe_attach(bus))) { + ret = brcmf_sdio_probe_attach(bus); + if (ret < 0) { brcmf_err("brcmf_sdio_probe_attach failed\n"); goto fail; } @@ -4546,7 +4552,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) fail: brcmf_sdio_remove(bus); - return NULL; + return ERR_PTR(ret); } /* Detach and free everything */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h index 5d66e94c806d..96032322b165 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h @@ -41,7 +41,7 @@ TRACE_EVENT(brcmf_err, __vstring(msg, vaf->fmt, vaf->va) ), TP_fast_assign( - __assign_str(func, func); + __assign_str(func); __assign_vstr(msg, vaf->fmt, vaf->va); ), TP_printk("%s: %s", __get_str(func), __get_str(msg)) @@ -57,7 +57,7 @@ TRACE_EVENT(brcmf_dbg, ), TP_fast_assign( __entry->level = level; - __assign_str(func, func); + __assign_str(func); __assign_vstr(msg, vaf->fmt, vaf->va); ), TP_printk("%s: %s", __get_str(func), __get_str(msg)) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 0ccf735316c2..2821c27f317e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -117,13 +117,6 @@ struct bootrom_id_le { __le32 boardrev; /* Board revision */ }; -struct brcmf_usb_image { - struct list_head list; - s8 *fwname; - u8 *image; - int image_len; -}; - struct brcmf_usbdev_info { struct brcmf_usbdev bus_pub; /* MUST BE FIRST */ spinlock_t qlock; @@ -1243,8 +1236,8 @@ brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo) static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, enum brcmf_fwvendor fwvid) { - struct brcmf_bus *bus = NULL; - struct brcmf_usbdev *bus_pub = NULL; + struct brcmf_bus *bus; + struct brcmf_usbdev *bus_pub; struct device *dev = devinfo->dev; struct brcmf_fw_request *fwreq; int ret; @@ -1254,7 +1247,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, if (!bus_pub) return -ENODEV; - bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); + bus = kzalloc(sizeof(*bus), GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; @@ -1279,6 +1272,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, ret = -ENOMEM; goto fail; } + ret = PTR_ERR_OR_ZERO(devinfo->settings); + if (ret < 0) + goto fail; if (!brcmf_usb_dlneeded(devinfo)) { ret = brcmf_alloc(devinfo->dev, devinfo->settings); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/Makefile index 7f455a19a2b1..3db4cce44f42 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/Makefile @@ -3,9 +3,9 @@ # Copyright (c) 2022 Broadcom Corporation ccflags-y += \ - -I $(srctree)/$(src) \ - -I $(srctree)/$(src)/.. \ - -I $(srctree)/$(src)/../../include + -I $(src) \ + -I $(src)/.. \ + -I $(src)/../../include obj-m += brcmfmac-wcc.o brcmfmac-wcc-objs += \ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c index 5573a47766ad..05d7c2a4fba5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c @@ -7,21 +7,34 @@ #include <core.h> #include <bus.h> #include <fwvid.h> +#include <cfg80211.h> #include "vops.h" -static int brcmf_wcc_attach(struct brcmf_pub *drvr) +#define BRCMF_WCC_E_LAST 213 + +static int brcmf_wcc_set_sae_pwd(struct brcmf_if *ifp, + struct cfg80211_crypto_settings *crypto) { - pr_debug("%s: executing\n", __func__); - return 0; + return brcmf_set_wsec(ifp, crypto->sae_pwd, crypto->sae_pwd_len, + BRCMF_WSEC_PASSPHRASE); } -static void brcmf_wcc_detach(struct brcmf_pub *drvr) +static int brcmf_wcc_alloc_fweh_info(struct brcmf_pub *drvr) { - pr_debug("%s: executing\n", __func__); + struct brcmf_fweh_info *fweh; + + fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_WCC_E_LAST), + GFP_KERNEL); + if (!fweh) + return -ENOMEM; + + fweh->num_event_codes = BRCMF_WCC_E_LAST; + drvr->fweh = fweh; + return 0; } const struct brcmf_fwvid_ops brcmf_wcc_ops = { - .attach = brcmf_wcc_attach, - .detach = brcmf_wcc_detach, + .set_sae_password = brcmf_wcc_set_sae_pwd, + .alloc_fweh_info = brcmf_wcc_alloc_fweh_info, }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c index b66135e3cff4..cfe01ca63ba6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_wcc_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom mobility chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_wcc_init); module_exit(brcmf_wcc_exit); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c index 2f8908074303..08841b9a5b81 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c @@ -3,7 +3,7 @@ * Copyright (c) 2019 Broadcom */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/math.h> #include <linux/string.h> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile index 090757730ba6..ffdd17eabe1d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile @@ -16,9 +16,9 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ccflags-y := \ - -I $(srctree)/$(src) \ - -I $(srctree)/$(src)/phy \ - -I $(srctree)/$(src)/../include + -I $(src) \ + -I $(src)/phy \ + -I $(src)/../include brcmsmac-y := \ mac80211_if.o \ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c index 2084b506a450..50d817485cf9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c @@ -512,7 +512,7 @@ ai_attach(struct bcma_bus *pbus) struct si_info *sii; /* alloc struct si_info */ - sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC); + sii = kzalloc(sizeof(*sii), GFP_ATOMIC); if (sii == NULL) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c index e859075db716..a767cbb79185 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c @@ -143,12 +143,6 @@ struct ampdu_info { struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO]; }; -/* used for flushing ampdu packets */ -struct cb_del_ampdu_pars { - struct ieee80211_sta *sta; - u16 tid; -}; - static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) { u32 rate, mcs; @@ -225,7 +219,7 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) struct ampdu_info *ampdu; int i; - ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); + ampdu = kzalloc(sizeof(*ampdu), GFP_ATOMIC); if (!ampdu) return NULL; @@ -357,9 +351,7 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) { struct ampdu_info *ampdu = wlc->ampdu; u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false); - u32 txunfl_ratio; u8 max_mpdu; - u32 current_ampdu_cnt = 0; u16 max_pld_size; u32 new_txunfl; struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid); @@ -395,26 +387,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); - - /* - compute the current ratio of tx unfl per ampdu. - When the current ampdu count becomes too - big while the ratio remains small, we reset - the current count in order to not - introduce too big of a latency in detecting a - large amount of tx underflows later. - */ + brcms_dbg_ht(wlc->hw->d11core, "tx_underflows %d\n", fifo->accum_txfunfl); - txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; - - if (txunfl_ratio > ampdu->tx_max_funl) { - if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) - fifo->accum_txfunfl = 0; - - return 0; - } max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c index 54c616919590..f411bc6d795d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c @@ -111,7 +111,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) struct antsel_info *asi; struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; - asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); + asi = kzalloc(sizeof(*asi), GFP_ATOMIC); if (!asi) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h index a0da3248b942..53b3dba50737 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h @@ -81,7 +81,7 @@ TRACE_EVENT(brcms_macintstatus, __field(u32, mask) ), TP_fast_assign( - __assign_str(dev, dev_name(dev)); + __assign_str(dev); __entry->in_isr = in_isr; __entry->macintstatus = macintstatus; __entry->mask = mask; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h index 42b0a91656c4..908ce3c864fe 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h @@ -71,7 +71,7 @@ TRACE_EVENT(brcms_dbg, ), TP_fast_assign( __entry->level = level; - __assign_str(func, func); + __assign_str(func); __assign_vstr(msg, vaf->fmt, vaf->va); ), TP_printk("%s: %s", __get_str(func), __get_str(msg)) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h index cf2cc070f1e5..24ac34fa0207 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h @@ -31,7 +31,7 @@ TRACE_EVENT(brcms_txdesc, __dynamic_array(u8, txh, txh_len) ), TP_fast_assign( - __assign_str(dev, dev_name(dev)); + __assign_str(dev); memcpy(__get_dynamic_array(txh), txh, txh_len); ), TP_printk("[%s] txdesc", __get_str(dev)) @@ -54,7 +54,7 @@ TRACE_EVENT(brcms_txstatus, __field(u16, ackphyrxsh) ), TP_fast_assign( - __assign_str(dev, dev_name(dev)); + __assign_str(dev); __entry->framelen = framelen; __entry->frameid = frameid; __entry->status = status; @@ -85,7 +85,7 @@ TRACE_EVENT(brcms_ampdu_session, __field(u16, dma_len) ), TP_fast_assign( - __assign_str(dev, dev_name(dev)); + __assign_str(dev); __entry->max_ampdu_len = max_ampdu_len; __entry->max_ampdu_frames = max_ampdu_frames; __entry->ampdu_len = ampdu_len; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c index f6962e558d7c..d1b9a18d0374 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c @@ -331,7 +331,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) const char *ccode = sprom->alpha2; int ccode_len = sizeof(sprom->alpha2); - wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); + wlc_cm = kzalloc(sizeof(*wlc_cm), GFP_ATOMIC); if (wlc_cm == NULL) return NULL; wlc_cm->pub = pub; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c index 6d776ef6ff54..81df41c7fbb5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c @@ -56,11 +56,6 @@ void brcms_debugfs_detach(struct brcms_pub *drvr) debugfs_remove_recursive(drvr->dbgfs_dir); } -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) -{ - return drvr->dbgfs_dir; -} - static int brcms_debugfs_hardware_read(struct seq_file *s, void *data) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h index 56898e6d789d..d30a9fa30f1b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h @@ -70,7 +70,6 @@ void brcms_debugfs_init(void); void brcms_debugfs_exit(void); void brcms_debugfs_attach(struct brcms_pub *drvr); void brcms_debugfs_detach(struct brcms_pub *drvr); -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr); void brcms_debugfs_create_files(struct brcms_pub *drvr); #endif /* _BRCMS_DEBUG_H_ */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c index 3d5c1ef8f7f2..80c35027787a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c @@ -558,7 +558,7 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, struct si_info *sii = container_of(sih, struct si_info, pub); /* allocate private info structure */ - di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC); + di = kzalloc(sizeof(*di), GFP_ATOMIC); if (di == NULL) return NULL; @@ -1426,15 +1426,6 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, return -ENOSPC; } -void dma_txflush(struct dma_pub *pub) -{ - struct dma_info *di = container_of(pub, struct dma_info, dma); - struct brcms_ampdu_session *session = &di->ampdu_session; - - if (!skb_queue_empty(&session->skb_list)) - ampdu_finalize(di); -} - int dma_txpending(struct dma_pub *pub) { struct dma_info *di = container_of(pub, struct dma_info, dma); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h index ff5b80b09046..7905fd081721 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.h @@ -88,7 +88,6 @@ bool dma_txreset(struct dma_pub *pub); void dma_txinit(struct dma_pub *pub); int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, struct sk_buff *p0); -void dma_txflush(struct dma_pub *pub); int dma_txpending(struct dma_pub *pub); void dma_kick_tx(struct dma_pub *pub); void dma_txsuspend(struct dma_pub *pub); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c index 89c8829528c2..9540a05247c2 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <net/mac80211.h> #include <linux/bcma/bcma_driver_chipcommon.h> -#include <linux/gpio.h> #include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/gpio/consumer.h> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index 543e93ec49d2..5b1d35601bbd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -457,7 +457,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw) return err; } -static void brcms_ops_stop(struct ieee80211_hw *hw) +static void brcms_ops_stop(struct ieee80211_hw *hw, bool suspend) { struct brcms_info *wl = hw->priv; int status; @@ -959,6 +959,10 @@ static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw, } static const struct ieee80211_ops brcms_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, .tx = brcms_ops_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, .start = brcms_ops_start, @@ -1086,6 +1090,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(hw, SIGNAL_DBM); ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, MFP_CAPABLE); hw->extra_tx_headroom = brcms_c_get_header_len(); hw->queues = N_TX_QUEUES; @@ -1492,7 +1497,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, { struct brcms_timer *t; - t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC); + t = kzalloc(sizeof(*t), GFP_ATOMIC); if (!t) return NULL; @@ -1606,10 +1611,9 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) if (le32_to_cpu(hdr->idx) == idx) { pdata = wl->fw.fw_bin[i]->data + le32_to_cpu(hdr->offset); - *pbuf = kvmalloc(len, GFP_KERNEL); + *pbuf = kvmemdup(pdata, len, GFP_KERNEL); if (*pbuf == NULL) - goto fail; - memcpy(*pbuf, pdata, len); + return -ENOMEM; return 0; } } @@ -1617,7 +1621,6 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) brcms_err(wl->wlc->hw->d11core, "ERROR: ucode buf tag:%d can not be found!\n", idx); *pbuf = NULL; -fail: return -ENODATA; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c index 34460b5815d0..2738d4d6c60a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c @@ -234,12 +234,6 @@ /* max # tx status to process in wlc_txstatus() */ #define TXSBND 8 -/* brcmu_format_flags() bit description structure */ -struct brcms_c_bit_desc { - u32 bit; - const char *name; -}; - /* * The following table lists the buffer memory allocated to xmt fifos in HW. * the size is in units of 256bytes(one block), total size is HW dependent @@ -463,11 +457,11 @@ static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit) { struct brcms_bss_cfg *cfg; - cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC); + cfg = kzalloc(sizeof(*cfg), GFP_ATOMIC); if (cfg == NULL) goto fail; - cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); + cfg->current_bss = kzalloc(sizeof(*cfg->current_bss), GFP_ATOMIC); if (cfg->current_bss == NULL) goto fail; @@ -483,14 +477,14 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) { struct brcms_c_info *wlc; - wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC); + wlc = kzalloc(sizeof(*wlc), GFP_ATOMIC); if (wlc == NULL) { *err = 1002; goto fail; } /* allocate struct brcms_c_pub state structure */ - wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC); + wlc->pub = kzalloc(sizeof(*wlc->pub), GFP_ATOMIC); if (wlc->pub == NULL) { *err = 1003; goto fail; @@ -499,7 +493,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) /* allocate struct brcms_hardware state structure */ - wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC); + wlc->hw = kzalloc(sizeof(*wlc->hw), GFP_ATOMIC); if (wlc->hw == NULL) { *err = 1005; goto fail; @@ -528,7 +522,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) goto fail; } - wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); + wlc->default_bss = kzalloc(sizeof(*wlc->default_bss), GFP_ATOMIC); if (wlc->default_bss == NULL) { *err = 1010; goto fail; @@ -540,21 +534,20 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) goto fail; } - wlc->protection = kzalloc(sizeof(struct brcms_protection), - GFP_ATOMIC); + wlc->protection = kzalloc(sizeof(*wlc->protection), GFP_ATOMIC); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC); + wlc->stf = kzalloc(sizeof(*wlc->stf), GFP_ATOMIC); if (wlc->stf == NULL) { *err = 1017; goto fail; } wlc->bandstate[0] = - kcalloc(MAXBANDS, sizeof(struct brcms_band), GFP_ATOMIC); + kcalloc(MAXBANDS, sizeof(*wlc->bandstate[0]), GFP_ATOMIC); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; @@ -567,14 +560,14 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) + (sizeof(struct brcms_band)*i)); } - wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC); + wlc->corestate = kzalloc(sizeof(*wlc->corestate), GFP_ATOMIC); if (wlc->corestate == NULL) { *err = 1026; goto fail; } wlc->corestate->macstat_snapshot = - kzalloc(sizeof(struct macstat), GFP_ATOMIC); + kzalloc(sizeof(*wlc->corestate->macstat_snapshot), GFP_ATOMIC); if (wlc->corestate->macstat_snapshot == NULL) { *err = 1027; goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c index ccc621b8ed9f..c3d7aa570b4e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c @@ -355,7 +355,7 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) { struct shared_phy *sh; - sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC); + sh = kzalloc(sizeof(*sh), GFP_ATOMIC); if (sh == NULL) return NULL; @@ -383,8 +383,9 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) return sh; } -static void wlc_phy_timercb_phycal(struct brcms_phy *pi) +static void wlc_phy_timercb_phycal(void *ptr) { + struct brcms_phy *pi = ptr; uint delay = 5; if (PHY_PERICAL_MPHASE_PENDING(pi)) { @@ -441,7 +442,7 @@ wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core, return &pi->pubpi_ro; } - pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC); + pi = kzalloc(sizeof(*pi), GFP_ATOMIC); if (pi == NULL) return NULL; pi->wiphy = wiphy; @@ -551,8 +552,7 @@ wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core, if (!pi->phycal_timer) goto err; - if (!wlc_phy_attach_nphy(pi)) - goto err; + wlc_phy_attach_nphy(pi); } else if (ISLCNPHY(pi)) { if (!wlc_phy_attach_lcnphy(pi)) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h index 8668fa5558a2..70a9ec050717 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_int.h @@ -941,7 +941,7 @@ void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag); void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); -bool wlc_phy_attach_nphy(struct brcms_phy *pi); +void wlc_phy_attach_nphy(struct brcms_phy *pi); bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); void wlc_phy_detach_lcnphy(struct brcms_phy *pi); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c index 7717eb85a1db..d0faba240561 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c @@ -2567,7 +2567,6 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, struct lcnphy_txgains cal_gains, temp_gains; u16 hash; - u8 band_idx; int j; u16 ncorr_override[5]; u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -2599,6 +2598,9 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, u16 *values_to_save; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + if (WARN_ON(CHSPEC_IS5G(pi->radio_chanspec))) + return; + values_to_save = kmalloc_array(20, sizeof(u16), GFP_ATOMIC); if (NULL == values_to_save) return; @@ -2662,20 +2664,18 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, hash = (target_gains->gm_gain << 8) | (target_gains->pga_gain << 4) | (target_gains->pad_gain); - band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); - cal_gains = *target_gains; memset(ncorr_override, 0, sizeof(ncorr_override)); - for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { - if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { + for (j = 0; j < iqcal_gainparams_numgains_lcnphy[0]; j++) { + if (hash == tbl_iqcal_gainparams_lcnphy[0][j][0]) { cal_gains.gm_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; + tbl_iqcal_gainparams_lcnphy[0][j][1]; cal_gains.pga_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; + tbl_iqcal_gainparams_lcnphy[0][j][2]; cal_gains.pad_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; + tbl_iqcal_gainparams_lcnphy[0][j][3]; memcpy(ncorr_override, - &tbl_iqcal_gainparams_lcnphy[band_idx][j][3], + &tbl_iqcal_gainparams_lcnphy[0][j][3], sizeof(ncorr_override)); break; } @@ -3299,7 +3299,7 @@ wlc_lcnphy_run_samples(struct brcms_phy *pi, if (iqcalmode) { - and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15)); + and_phy_reg(pi, 0x453, 0xffff & ~(0x1 << 15)); or_phy_reg(pi, 0x453, (0x1 << 15)); } else { write_phy_reg(pi, 0x63f, 1); @@ -4968,11 +4968,11 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) { struct brcms_phy_lcnphy *pi_lcn; - pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC); - if (pi->u.pi_lcnphy == NULL) + pi_lcn = kzalloc(sizeof(*pi_lcn), GFP_ATOMIC); + if (!pi_lcn) return false; - pi_lcn = pi->u.pi_lcnphy; + pi->u.pi_lcnphy = pi_lcn; if (0 == (pi->sh->boardflags & BFL_NOPA)) { pi->hwpwrctrl = true; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index 8580a2754789..d362c4337616 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -14546,7 +14546,7 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) wlc_phy_txpwr_apply_nphy(pi); } -static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) +static void wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) { struct ssb_sprom *sprom = &pi->d11core->bus->sprom; @@ -14595,11 +14595,9 @@ static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) pi->phycal_tempdelta = 0; wlc_phy_txpwr_srom_read_ppr_nphy(pi); - - return true; } -bool wlc_phy_attach_nphy(struct brcms_phy *pi) +void wlc_phy_attach_nphy(struct brcms_phy *pi) { uint i; @@ -14645,10 +14643,7 @@ bool wlc_phy_attach_nphy(struct brcms_phy *pi) pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy; pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy; - if (!wlc_phy_txpwr_srom_read_nphy(pi)) - return false; - - return true; + wlc_phy_txpwr_srom_read_nphy(pi); } static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn) @@ -17587,7 +17582,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) or_phy_reg(pi, 0x122, (0x1 << 0)); if (NREV_GE(pi->pubpi.phy_rev, 3)) - and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15))); + and_phy_reg(pi, 0x1e7, 0x7fff); else or_phy_reg(pi, 0x1e7, (0x1 << 15)); @@ -18086,7 +18081,7 @@ wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value, (0x1 << 10)); and_phy_reg(pi, 0x2ff, (u16) - ~(0x3 << 14)); + 0xffff & ~(0x3 << 14)); or_phy_reg(pi, 0x2ff, (0x1 << 13)); or_phy_reg(pi, 0x2ff, (0x1 << 0)); } else { @@ -21053,7 +21048,7 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec, (val | MAC_PHY_FORCE_CLK)); and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), - (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX))); + 0xffff & ~(BBCFG_RESETCCA | BBCFG_RESETRX)); bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val); } @@ -21287,7 +21282,8 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) bcma_set16(pi->d11core, D11REGOFFS(psm_gpio_oe), mask); - bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), ~mask); + bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), + 0xffff & ~mask); if (lut_init) { write_phy_reg(pi, 0xf8, 0x02d8); @@ -23197,7 +23193,7 @@ void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP); else if (playback_status & 0x2) and_phy_reg(pi, 0xc2, - (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN); + 0xffff & ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN); and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2)); @@ -23427,6 +23423,9 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, break; } + if (WARN_ON(k == NPHY_IQCAL_NUMGAINS)) + return; + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; @@ -28202,8 +28201,9 @@ void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) if (NREV_GE(pi->pubpi.phy_rev, 3)) and_phy_reg(pi, 0x1e7, - (u16) (~((0x1 << 15) | - (0x1 << 14) | (0x1 << 13)))); + 0xffff & ~((0x1 << 15) | + (0x1 << 14) | + (0x1 << 13))); else and_phy_reg(pi, 0x1e7, (u16) (~((0x1 << 14) | (0x1 << 13)))); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c index a0de5db0cd64..8b852581c4e4 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c @@ -38,9 +38,9 @@ struct phy_shim_info { struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, struct brcms_info *wl, struct brcms_c_info *wlc) { - struct phy_shim_info *physhim = NULL; + struct phy_shim_info *physhim; - physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC); + physhim = kzalloc(sizeof(*physhim), GFP_ATOMIC); if (!physhim) return NULL; @@ -57,12 +57,11 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim) } struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn)(struct brcms_phy *pi), + void (*fn)(void *pi), void *arg, const char *name) { return (struct wlapi_timer *) - brcms_init_timer(physhim->wl, (void (*)(void *))fn, - arg, name); + brcms_init_timer(physhim->wl, fn, arg, name); } void wlapi_free_timer(struct wlapi_timer *t) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h index dd8774717ade..27d0934e600e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h @@ -131,7 +131,7 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim); /* PHY to WL utility functions */ struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn)(struct brcms_phy *pi), + void (*fn)(void *pi), void *arg, const char *name); void wlapi_free_timer(struct wlapi_timer *t); void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmutil/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmutil/Makefile index 7a82d615ba2a..f9b40cab766c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/Makefile @@ -4,7 +4,7 @@ # # Copyright (c) 2011 Broadcom Corporation # -ccflags-y := -I $(srctree)/$(src)/../include +ccflags-y := -I $(src)/../include obj-$(CONFIG_BRCMUTIL) += brcmutil.o brcmutil-objs = utils.o d11.o diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h index 44684bf1b9ac..c1e22c589d85 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h @@ -52,6 +52,7 @@ #define BRCM_CC_43664_CHIP_ID 43664 #define BRCM_CC_43666_CHIP_ID 43666 #define BRCM_CC_4371_CHIP_ID 0x4371 +#define BRCM_CC_43752_CHIP_ID 43752 #define BRCM_CC_4377_CHIP_ID 0x4377 #define BRCM_CC_4378_CHIP_ID 0x4378 #define BRCM_CC_4387_CHIP_ID 0x4387 @@ -94,6 +95,7 @@ #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 #define BRCM_PCIE_4371_DEVICE_ID 0x440d #define BRCM_PCIE_43596_DEVICE_ID 0x4415 +#define BRCM_PCIE_43752_DEVICE_ID 0x449d #define BRCM_PCIE_4377_DEVICE_ID 0x4488 #define BRCM_PCIE_4378_DEVICE_ID 0x4425 #define BRCM_PCIE_4387_DEVICE_ID 0x4433 |