mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
wireless-next patches for v6.13
The first -next "new features" pull request for v6.13. This is a big one as we have not been able to send one earlier. We have also some patches affecting other subsystems: in staging we deleted the rtl8192e driver and in debugfs added a new interface to save struct file_operations memory; both were acked by GregKH. Because of the lib80211/libipw move there were quite a lot of conflicts and to solve those we decided to merge net-next into wireless-next. Currently there's one conflict in Documentation/networking/net_cachelines/net_device.rst. To fix that just remove the iw_public_data line: https://lore.kernel.org/all/20241011121014.674661a0@canb.auug.org.au/ And when net is merged to net-next there will be another simple conflict in in net/mac80211/cfg.c: https://lore.kernel.org/all/20241024115523.4cd35dde@canb.auug.org.au/ Major changes: cfg80211/mac80211 * stop exporting wext symbols * new mac80211 op to indicate that a new interface is to be added * support radio separation of multi-band devices Wireless Extensions * move wext spy implementation to libiw * remove iw_public_data from struct net_device brcmfmac * optional LPO clock support ipw2x00 * move remaining lib80211 code into libiw wilc1000 * WILC3000 support rtw89 * RTL8852BE and RTL8852BE-VT BT-coexistence improvements -----BEGIN PGP SIGNATURE----- iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmcbz9YRHGt2YWxvQGtl cm5lbC5vcmcACgkQbhckVSbrbZsabQf8CWJ/kyonw/Z8hRxgfE/7D6Jiqoq7R+ML 8W8lbc6F5wra4eCBq/oo6UVV36Ss6mxQYcRcmLq+nCkXa4qdMpg/z55QECMHxx5Z YnIBbD2vBrIj7W21gfCKH1WJ+b5IQFZl3zuxuCgXjxD9TJM2CjUfOkvrhrqqzrPn clfUx5f01vfv2jdvClPR5977gFE5One/ANeRQNs7uDS0TeeD2P+61DEB1//htIJo 7GwwCyUJCeOcfWRMzQwhpoppWKcPAV70kSVJrl/fRstS68vQGSQbcx9yiNeWkSFw JXjQGdc8eYLPzLqECwS0KwFkta6AXbafAYYXe1wdlAzr+kmJ9x5oqA== =x+mr -----END PGP SIGNATURE----- Merge tag 'wireless-next-2024-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next Kalle Valo says: ==================== wireless-next patches for v6.13 The first -next "new features" pull request for v6.13. This is a big one as we have not been able to send one earlier. We have also some patches affecting other subsystems: in staging we deleted the rtl8192e driver and in debugfs added a new interface to save struct file_operations memory; both were acked by GregKH. Because of the lib80211/libipw move there were quite a lot of conflicts and to solve those we decided to merge net-next into wireless-next. Major changes: cfg80211/mac80211 * stop exporting wext symbols * new mac80211 op to indicate that a new interface is to be added * support radio separation of multi-band devices Wireless Extensions * move wext spy implementation to libiw * remove iw_public_data from struct net_device brcmfmac * optional LPO clock support ipw2x00 * move remaining lib80211 code into libiw wilc1000 * WILC3000 support rtw89 * RTL8852BE and RTL8852BE-VT BT-coexistence improvements * tag 'wireless-next-2024-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (126 commits) mac80211: Remove NOP call to ieee80211_hw_config wifi: iwlwifi: work around -Wenum-compare-conditional warning wifi: mac80211: re-order assigning channel in activate links wifi: mac80211: convert debugfs files to short fops debugfs: add small file operations for most files wifi: mac80211: remove misleading j_0 construction parts wifi: mac80211_hwsim: use hrtimer_active() wifi: mac80211: refactor BW limitation check for CSA parsing wifi: mac80211: filter on monitor interfaces based on configured channel wifi: mac80211: refactor ieee80211_rx_monitor wifi: mac80211: add support for the monitor SKIP_TX flag wifi: cfg80211: add monitor SKIP_TX flag wifi: mac80211: add flag to opt out of virtual monitor support wifi: cfg80211: pass net_device to .set_monitor_channel wifi: mac80211: remove status->ampdu_delimiter_crc wifi: cfg80211: report per wiphy radio antenna mask wifi: mac80211: use vif radio mask to limit creating chanctx wifi: mac80211: use vif radio mask to limit ibss scan frequencies wifi: cfg80211: add option for vif allowed radios wifi: iwlwifi: allow IWL_FW_CHECK() with just a string ... ==================== Link: https://patch.msgid.link/20241025170705.5F6B2C4CEC3@smtp.kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
71e0ad3451
|
|
@ -53,6 +53,7 @@ properties:
|
|||
- pci14e4,4488 # BCM4377
|
||||
- pci14e4,4425 # BCM4378
|
||||
- pci14e4,4433 # BCM4387
|
||||
- pci14e4,449d # BCM43752
|
||||
|
||||
reg:
|
||||
description: SDIO function number for the device (for most cases
|
||||
|
|
@ -121,6 +122,14 @@ properties:
|
|||
NVRAM. This would normally be filled in by the bootloader from platform
|
||||
configuration data.
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External Low Power Clock input (32.768KHz)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: lpo
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,wilc1000
|
||||
oneOf:
|
||||
- items:
|
||||
- const: microchip,wilc3000
|
||||
- const: microchip,wilc1000
|
||||
- const: microchip,wilc1000
|
||||
|
||||
reg: true
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ struct net_device_core_stats* core_stats
|
|||
atomic_t carrier_up_count
|
||||
atomic_t carrier_down_count
|
||||
struct iw_handler_def* wireless_handlers
|
||||
struct iw_public_data* wireless_data
|
||||
struct ethtool_ops* ethtool_ops
|
||||
struct l3mdev_ops* l3mdev_ops
|
||||
struct ndisc_ops* ndisc_ops
|
||||
|
|
|
|||
|
|
@ -2566,7 +2566,6 @@ static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
|
|||
|
||||
netdev->ethtool_ops = &gelic_wl_ethtool_ops;
|
||||
netdev->netdev_ops = &gelic_wl_netdevice_ops;
|
||||
netdev->wireless_data = &wl->wireless_data;
|
||||
netdev->wireless_handlers = &gelic_wl_wext_handler_def;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -276,7 +276,6 @@ struct gelic_wl_info {
|
|||
u8 active_bssid[ETH_ALEN]; /* associated bssid */
|
||||
unsigned int essid_len;
|
||||
|
||||
struct iw_public_data wireless_data;
|
||||
struct iw_statistics iwstat;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8507,9 +8507,10 @@ static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
|
|||
|
||||
static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
|
|
@ -9450,7 +9451,7 @@ static const struct ieee80211_ops ath10k_ops = {
|
|||
.reconfig_complete = ath10k_reconfig_complete,
|
||||
.get_survey = ath10k_get_survey,
|
||||
.set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
|
||||
.sta_rc_update = ath10k_sta_rc_update,
|
||||
.link_sta_rc_update = ath10k_sta_rc_update,
|
||||
.offset_tsf = ath10k_offset_tsf,
|
||||
.ampdu_action = ath10k_ampdu_action,
|
||||
.get_et_sset_count = ath10k_debug_get_et_sset_count,
|
||||
|
|
|
|||
|
|
@ -5079,9 +5079,10 @@ static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,
|
|||
|
||||
static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct ath11k *ar = hw->priv;
|
||||
struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
|
||||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
|
|
@ -9708,7 +9709,7 @@ static const struct ieee80211_ops ath11k_ops = {
|
|||
.sta_state = ath11k_mac_op_sta_state,
|
||||
.sta_set_4addr = ath11k_mac_op_sta_set_4addr,
|
||||
.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,
|
||||
.sta_rc_update = ath11k_mac_op_sta_rc_update,
|
||||
.link_sta_rc_update = ath11k_mac_op_sta_rc_update,
|
||||
.conf_tx = ath11k_mac_op_conf_tx,
|
||||
.set_antenna = ath11k_mac_op_set_antenna,
|
||||
.get_antenna = ath11k_mac_op_get_antenna,
|
||||
|
|
|
|||
|
|
@ -4737,9 +4737,10 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw,
|
|||
|
||||
static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta);
|
||||
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
|
||||
|
|
@ -8681,7 +8682,7 @@ static const struct ieee80211_ops ath12k_ops = {
|
|||
.set_rekey_data = ath12k_mac_op_set_rekey_data,
|
||||
.sta_state = ath12k_mac_op_sta_state,
|
||||
.sta_set_txpwr = ath12k_mac_op_sta_set_txpwr,
|
||||
.sta_rc_update = ath12k_mac_op_sta_rc_update,
|
||||
.link_sta_rc_update = ath12k_mac_op_sta_rc_update,
|
||||
.conf_tx = ath12k_mac_op_conf_tx,
|
||||
.set_antenna = ath12k_mac_op_set_antenna,
|
||||
.get_antenna = ath12k_mac_op_get_antenna,
|
||||
|
|
|
|||
|
|
@ -1357,8 +1357,10 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
|
|||
|
||||
static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u32 changed)
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||
|
||||
if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
|
||||
|
|
@ -1883,7 +1885,7 @@ struct ieee80211_ops ath9k_htc_ops = {
|
|||
.sta_add = ath9k_htc_sta_add,
|
||||
.sta_remove = ath9k_htc_sta_remove,
|
||||
.conf_tx = ath9k_htc_conf_tx,
|
||||
.sta_rc_update = ath9k_htc_sta_rc_update,
|
||||
.link_sta_rc_update = ath9k_htc_sta_rc_update,
|
||||
.bss_info_changed = ath9k_htc_bss_info_changed,
|
||||
.set_key = ath9k_htc_set_key,
|
||||
.get_tsf = ath9k_htc_get_tsf,
|
||||
|
|
|
|||
|
|
@ -1493,6 +1493,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
}
|
||||
|
||||
static int wil_cfg80211_set_channel(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
|
|
|||
|
|
@ -947,8 +947,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);
|
||||
|
|
|
|||
|
|
@ -7820,13 +7820,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -561,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;
|
||||
|
|
|
|||
|
|
@ -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,12 +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;
|
||||
|
|
@ -106,7 +108,7 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
|||
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;
|
||||
|
|
@ -114,8 +116,14 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
|||
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)
|
||||
|
|
@ -124,23 +132,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_irq_parse_one(np, 0, &oirq))
|
||||
return;
|
||||
return 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -353,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;
|
||||
|
|
@ -1715,14 +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),
|
||||
};
|
||||
|
||||
/* 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");
|
||||
|
|
@ -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,14 +2698,14 @@ 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[] = {
|
||||
|
|
@ -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 */ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -4451,8 +4453,10 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
|
||||
/* Allocate private bus interface state */
|
||||
bus = kzalloc(sizeof(*bus), GFP_ATOMIC);
|
||||
if (!bus)
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -1272,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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ config IPW2100
|
|||
tristate "Intel PRO/Wireless 2100 Network Connection"
|
||||
depends on PCI && CFG80211
|
||||
select WIRELESS_EXT
|
||||
select WEXT_SPY
|
||||
select WEXT_PRIV
|
||||
select FW_LOADER
|
||||
select LIB80211
|
||||
select LIBIPW
|
||||
help
|
||||
A driver for the Intel PRO/Wireless 2100 Network
|
||||
|
|
@ -67,12 +65,9 @@ config IPW2100_DEBUG
|
|||
config IPW2200
|
||||
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
|
||||
depends on PCI && CFG80211
|
||||
select CFG80211_WEXT_EXPORT
|
||||
select WIRELESS_EXT
|
||||
select WEXT_SPY
|
||||
select WEXT_PRIV
|
||||
select FW_LOADER
|
||||
select LIB80211
|
||||
select LIBIPW
|
||||
help
|
||||
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
|
||||
|
|
@ -158,14 +153,10 @@ config LIBIPW
|
|||
tristate
|
||||
depends on PCI && CFG80211
|
||||
select WIRELESS_EXT
|
||||
select WEXT_SPY
|
||||
select CRYPTO
|
||||
select CRYPTO_MICHAEL_MIC
|
||||
select CRYPTO_LIB_ARC4
|
||||
select CRC32
|
||||
select LIB80211
|
||||
select LIB80211_CRYPT_WEP
|
||||
select LIB80211_CRYPT_TKIP
|
||||
select LIB80211_CRYPT_CCMP
|
||||
help
|
||||
This option enables the hardware independent IEEE 802.11
|
||||
networking stack. This component is deprecated in favor of the
|
||||
|
|
|
|||
|
|
@ -12,4 +12,9 @@ libipw-objs := \
|
|||
libipw_tx.o \
|
||||
libipw_rx.o \
|
||||
libipw_wx.o \
|
||||
libipw_geo.o
|
||||
libipw_geo.o \
|
||||
libipw_spy.o \
|
||||
libipw_crypto.o \
|
||||
libipw_crypto_ccmp.o \
|
||||
libipw_crypto_tkip.o \
|
||||
libipw_crypto_wep.o
|
||||
|
|
|
|||
|
|
@ -148,9 +148,6 @@ that only one external action is invoked at a time.
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/pm_qos.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "ipw2100.h"
|
||||
#include "ipw.h"
|
||||
|
||||
|
|
@ -6025,8 +6022,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
|
|||
dev->netdev_ops = &ipw2100_netdev_ops;
|
||||
dev->ethtool_ops = &ipw2100_ethtool_ops;
|
||||
dev->wireless_handlers = &ipw2100_wx_handler_def;
|
||||
priv->wireless_data.libipw = priv->ieee;
|
||||
dev->wireless_data = &priv->wireless_data;
|
||||
dev->watchdog_timeo = 3 * HZ;
|
||||
dev->irq = 0;
|
||||
dev->min_mtu = 68;
|
||||
|
|
@ -7571,7 +7566,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
|
|||
struct ipw2100_priv *priv = libipw_priv(dev);
|
||||
struct libipw_device *ieee = priv->ieee;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct libipw_crypt_data *crypt;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -7663,7 +7658,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
|
|||
{
|
||||
struct ipw2100_priv *priv = libipw_priv(dev);
|
||||
struct libipw_device *ieee = priv->ieee;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct libipw_crypt_data *crypt;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
|
||||
switch (param->flags & IW_AUTH_INDEX) {
|
||||
|
|
|
|||
|
|
@ -554,8 +554,6 @@ struct ipw2100_priv {
|
|||
struct net_device *net_dev;
|
||||
struct iw_statistics wstats;
|
||||
|
||||
struct iw_public_data wireless_data;
|
||||
|
||||
struct tasklet_struct irq_tasklet;
|
||||
|
||||
struct delayed_work reset_work;
|
||||
|
|
|
|||
|
|
@ -6463,6 +6463,14 @@ static int ipw_set_rsn_capa(struct ipw_priv *priv,
|
|||
* WE-18 support
|
||||
*/
|
||||
|
||||
static int ipw_wx_get_name(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
strcpy(wrqu->name, "IEEE 802.11");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SIOCSIWGENIE */
|
||||
static int ipw_wx_set_genie(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
|
|
@ -6549,7 +6557,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
|
|||
struct ipw_priv *priv = libipw_priv(dev);
|
||||
struct libipw_device *ieee = priv->ieee;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct libipw_crypt_data *crypt;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -6648,7 +6656,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
|
|||
{
|
||||
struct ipw_priv *priv = libipw_priv(dev);
|
||||
struct libipw_device *ieee = priv->ieee;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct libipw_crypt_data *crypt;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
|
||||
switch (param->flags & IW_AUTH_INDEX) {
|
||||
|
|
@ -9826,7 +9834,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
|
|||
|
||||
/* Rebase the WE IOCTLs to zero for the handler array */
|
||||
static iw_handler ipw_wx_handlers[] = {
|
||||
IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname),
|
||||
IW_HANDLER(SIOCGIWNAME, ipw_wx_get_name),
|
||||
IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
|
||||
IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
|
||||
IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
|
||||
|
|
@ -9856,10 +9864,10 @@ static iw_handler ipw_wx_handlers[] = {
|
|||
IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
|
||||
IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
|
||||
IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
|
||||
IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
|
||||
IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
|
||||
IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
|
||||
IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
|
||||
IW_HANDLER(SIOCSIWSPY, ipw_wx_set_spy),
|
||||
IW_HANDLER(SIOCGIWSPY, ipw_wx_get_spy),
|
||||
IW_HANDLER(SIOCSIWTHRSPY, ipw_wx_set_thrspy),
|
||||
IW_HANDLER(SIOCGIWTHRSPY, ipw_wx_get_thrspy),
|
||||
IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
|
||||
IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
|
||||
IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
|
||||
|
|
@ -11636,8 +11644,7 @@ static int ipw_pci_probe(struct pci_dev *pdev,
|
|||
priv->ieee->worst_rssi = -85;
|
||||
|
||||
net_dev->netdev_ops = &ipw_netdev_ops;
|
||||
priv->wireless_data.spy_data = &priv->ieee->spy_data;
|
||||
net_dev->wireless_data = &priv->wireless_data;
|
||||
priv->ieee->spy_enabled = true;
|
||||
net_dev->wireless_handlers = &ipw_wx_handler_def;
|
||||
net_dev->ethtool_ops = &ipw_ethtool_ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@
|
|||
#include <linux/wireless.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
#define DRV_NAME "ipw2200"
|
||||
|
|
@ -1276,8 +1274,6 @@ struct ipw_priv {
|
|||
|
||||
struct iw_statistics wstats;
|
||||
|
||||
struct iw_public_data wireless_data;
|
||||
|
||||
int user_requested_scan;
|
||||
u8 direct_scan_ssid[IW_ESSID_MAX_SIZE];
|
||||
u8 direct_scan_ssid_len;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include <linux/kernel.h> /* ARRAY_SIZE */
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#define LIBIPW_VERSION "git-1.1.13"
|
||||
|
|
@ -699,6 +697,76 @@ struct libipw_geo {
|
|||
struct libipw_channel a[LIBIPW_52GHZ_CHANNELS];
|
||||
};
|
||||
|
||||
#define NUM_WEP_KEYS 4
|
||||
|
||||
enum {
|
||||
IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
|
||||
};
|
||||
|
||||
struct module;
|
||||
|
||||
struct libipw_crypto_ops {
|
||||
const char *name;
|
||||
struct list_head list;
|
||||
|
||||
/* init new crypto context (e.g., allocate private data space,
|
||||
* select IV, etc.); returns NULL on failure or pointer to allocated
|
||||
* private data on success */
|
||||
void *(*init) (int keyidx);
|
||||
|
||||
/* deinitialize crypto context and free allocated private data */
|
||||
void (*deinit) (void *priv);
|
||||
|
||||
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
|
||||
* value from decrypt_mpdu is passed as the keyidx value for
|
||||
* decrypt_msdu. skb must have enough head and tail room for the
|
||||
* encryption; if not, error will be returned; these functions are
|
||||
* called for all MPDUs (i.e., fragments).
|
||||
*/
|
||||
int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
|
||||
int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
|
||||
|
||||
/* These functions are called for full MSDUs, i.e. full frames.
|
||||
* These can be NULL if full MSDU operations are not needed. */
|
||||
int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
|
||||
int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
|
||||
void *priv);
|
||||
|
||||
int (*set_key) (void *key, int len, u8 * seq, void *priv);
|
||||
int (*get_key) (void *key, int len, u8 * seq, void *priv);
|
||||
|
||||
/* procfs handler for printing out key information and possible
|
||||
* statistics */
|
||||
void (*print_stats) (struct seq_file *m, void *priv);
|
||||
|
||||
/* Crypto specific flag get/set for configuration settings */
|
||||
unsigned long (*get_flags) (void *priv);
|
||||
unsigned long (*set_flags) (unsigned long flags, void *priv);
|
||||
|
||||
/* maximum number of bytes added by encryption; encrypt buf is
|
||||
* allocated with extra_prefix_len bytes, copy of in_buf, and
|
||||
* extra_postfix_len; encrypt need not use all this space, but
|
||||
* the result must start at the beginning of the buffer and correct
|
||||
* length must be returned */
|
||||
int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
|
||||
int extra_msdu_prefix_len, extra_msdu_postfix_len;
|
||||
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
struct libipw_crypt_info {
|
||||
char *name;
|
||||
/* Most clients will already have a lock,
|
||||
so just point to that. */
|
||||
spinlock_t *lock;
|
||||
|
||||
struct libipw_crypt_data *crypt[NUM_WEP_KEYS];
|
||||
int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
|
||||
struct list_head crypt_deinit_list;
|
||||
struct timer_list crypt_deinit_timer;
|
||||
int crypt_quiesced;
|
||||
};
|
||||
|
||||
struct libipw_device {
|
||||
struct net_device *dev;
|
||||
struct wireless_dev wdev;
|
||||
|
|
@ -720,6 +788,7 @@ struct libipw_device {
|
|||
|
||||
int iw_mode; /* operating mode (IW_MODE_*) */
|
||||
struct iw_spy_data spy_data; /* iwspy support */
|
||||
bool spy_enabled;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
|
|
@ -751,7 +820,7 @@ struct libipw_device {
|
|||
size_t wpa_ie_len;
|
||||
u8 *wpa_ie;
|
||||
|
||||
struct lib80211_crypt_info crypt_info;
|
||||
struct libipw_crypt_info crypt_info;
|
||||
|
||||
int bcrx_sta_key; /* use individual keys to override default keys even
|
||||
* with RX of broad/multicast frames */
|
||||
|
|
@ -988,4 +1057,43 @@ static inline int libipw_get_scans(struct libipw_device *ieee)
|
|||
return ieee->scans;
|
||||
}
|
||||
|
||||
struct libipw_crypt_data {
|
||||
struct list_head list; /* delayed deletion list */
|
||||
const struct libipw_crypto_ops *ops;
|
||||
void *priv;
|
||||
atomic_t refcnt;
|
||||
};
|
||||
|
||||
int libipw_crypt_info_init(struct libipw_crypt_info *info, char *name,
|
||||
spinlock_t *lock);
|
||||
void libipw_crypt_info_free(struct libipw_crypt_info *info);
|
||||
int libipw_register_crypto_ops(const struct libipw_crypto_ops *ops);
|
||||
int libipw_unregister_crypto_ops(const struct libipw_crypto_ops *ops);
|
||||
const struct libipw_crypto_ops *libipw_get_crypto_ops(const char *name);
|
||||
void libipw_crypt_delayed_deinit(struct libipw_crypt_info *info,
|
||||
struct libipw_crypt_data **crypt);
|
||||
|
||||
/* must be called in the listed order */
|
||||
int libipw_crypto_init(void);
|
||||
int libipw_crypto_ccmp_init(void);
|
||||
int libipw_crypto_tkip_init(void);
|
||||
int libipw_crypto_wep_init(void);
|
||||
|
||||
void libipw_crypto_wep_exit(void);
|
||||
void libipw_crypto_tkip_exit(void);
|
||||
void libipw_crypto_ccmp_exit(void);
|
||||
void libipw_crypto_exit(void);
|
||||
|
||||
|
||||
int ipw_wx_set_spy(struct net_device *dev, struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra);
|
||||
int ipw_wx_get_spy(struct net_device *dev, struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra);
|
||||
int ipw_wx_set_thrspy(struct net_device *dev, struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra);
|
||||
int ipw_wx_get_thrspy(struct net_device *dev, struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra);
|
||||
void libipw_spy_update(struct net_device *dev, unsigned char *address,
|
||||
struct iw_quality *wstats);
|
||||
|
||||
#endif /* LIBIPW_H */
|
||||
|
|
|
|||
246
drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
Normal file
246
drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* libipw -- common bits for IPW drivers
|
||||
*
|
||||
* Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
|
||||
*
|
||||
* Portions copied from old ieee80211 component, w/ original copyright
|
||||
* notices below:
|
||||
*
|
||||
* Host AP crypto routines
|
||||
*
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
|
||||
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include "libipw.h"
|
||||
|
||||
struct libipw_crypto_alg {
|
||||
struct list_head list;
|
||||
const struct libipw_crypto_ops *ops;
|
||||
};
|
||||
|
||||
static LIST_HEAD(libipw_crypto_algs);
|
||||
static DEFINE_SPINLOCK(libipw_crypto_lock);
|
||||
|
||||
static void libipw_crypt_deinit_entries(struct libipw_crypt_info *info,
|
||||
int force);
|
||||
static void libipw_crypt_quiescing(struct libipw_crypt_info *info);
|
||||
static void libipw_crypt_deinit_handler(struct timer_list *t);
|
||||
|
||||
int libipw_crypt_info_init(struct libipw_crypt_info *info, char *name,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->name = name;
|
||||
info->lock = lock;
|
||||
|
||||
INIT_LIST_HEAD(&info->crypt_deinit_list);
|
||||
timer_setup(&info->crypt_deinit_timer, libipw_crypt_deinit_handler,
|
||||
0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_crypt_info_init);
|
||||
|
||||
void libipw_crypt_info_free(struct libipw_crypt_info *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
libipw_crypt_quiescing(info);
|
||||
del_timer_sync(&info->crypt_deinit_timer);
|
||||
libipw_crypt_deinit_entries(info, 1);
|
||||
|
||||
for (i = 0; i < NUM_WEP_KEYS; i++) {
|
||||
struct libipw_crypt_data *crypt = info->crypt[i];
|
||||
if (crypt) {
|
||||
if (crypt->ops) {
|
||||
crypt->ops->deinit(crypt->priv);
|
||||
module_put(crypt->ops->owner);
|
||||
}
|
||||
kfree(crypt);
|
||||
info->crypt[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_crypt_info_free);
|
||||
|
||||
static void libipw_crypt_deinit_entries(struct libipw_crypt_info *info,
|
||||
int force)
|
||||
{
|
||||
struct libipw_crypt_data *entry, *next;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(info->lock, flags);
|
||||
list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) {
|
||||
if (atomic_read(&entry->refcnt) != 0 && !force)
|
||||
continue;
|
||||
|
||||
list_del(&entry->list);
|
||||
|
||||
if (entry->ops) {
|
||||
entry->ops->deinit(entry->priv);
|
||||
module_put(entry->ops->owner);
|
||||
}
|
||||
kfree(entry);
|
||||
}
|
||||
spin_unlock_irqrestore(info->lock, flags);
|
||||
}
|
||||
|
||||
/* After this, crypt_deinit_list won't accept new members */
|
||||
static void libipw_crypt_quiescing(struct libipw_crypt_info *info)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(info->lock, flags);
|
||||
info->crypt_quiesced = 1;
|
||||
spin_unlock_irqrestore(info->lock, flags);
|
||||
}
|
||||
|
||||
static void libipw_crypt_deinit_handler(struct timer_list *t)
|
||||
{
|
||||
struct libipw_crypt_info *info = from_timer(info, t,
|
||||
crypt_deinit_timer);
|
||||
unsigned long flags;
|
||||
|
||||
libipw_crypt_deinit_entries(info, 0);
|
||||
|
||||
spin_lock_irqsave(info->lock, flags);
|
||||
if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) {
|
||||
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
|
||||
"deletion list\n", info->name);
|
||||
info->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&info->crypt_deinit_timer);
|
||||
}
|
||||
spin_unlock_irqrestore(info->lock, flags);
|
||||
}
|
||||
|
||||
void libipw_crypt_delayed_deinit(struct libipw_crypt_info *info,
|
||||
struct libipw_crypt_data **crypt)
|
||||
{
|
||||
struct libipw_crypt_data *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
if (*crypt == NULL)
|
||||
return;
|
||||
|
||||
tmp = *crypt;
|
||||
*crypt = NULL;
|
||||
|
||||
/* must not run ops->deinit() while there may be pending encrypt or
|
||||
* decrypt operations. Use a list of delayed deinits to avoid needing
|
||||
* locking. */
|
||||
|
||||
spin_lock_irqsave(info->lock, flags);
|
||||
if (!info->crypt_quiesced) {
|
||||
list_add(&tmp->list, &info->crypt_deinit_list);
|
||||
if (!timer_pending(&info->crypt_deinit_timer)) {
|
||||
info->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&info->crypt_deinit_timer);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(info->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_crypt_delayed_deinit);
|
||||
|
||||
int libipw_register_crypto_ops(const struct libipw_crypto_ops *ops)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct libipw_crypto_alg *alg;
|
||||
|
||||
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
|
||||
if (alg == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
alg->ops = ops;
|
||||
|
||||
spin_lock_irqsave(&libipw_crypto_lock, flags);
|
||||
list_add(&alg->list, &libipw_crypto_algs);
|
||||
spin_unlock_irqrestore(&libipw_crypto_lock, flags);
|
||||
|
||||
printk(KERN_DEBUG "libipw_crypt: registered algorithm '%s'\n",
|
||||
ops->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_register_crypto_ops);
|
||||
|
||||
int libipw_unregister_crypto_ops(const struct libipw_crypto_ops *ops)
|
||||
{
|
||||
struct libipw_crypto_alg *alg;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&libipw_crypto_lock, flags);
|
||||
list_for_each_entry(alg, &libipw_crypto_algs, list) {
|
||||
if (alg->ops == ops)
|
||||
goto found;
|
||||
}
|
||||
spin_unlock_irqrestore(&libipw_crypto_lock, flags);
|
||||
return -EINVAL;
|
||||
|
||||
found:
|
||||
printk(KERN_DEBUG "libipw_crypt: unregistered algorithm '%s'\n",
|
||||
ops->name);
|
||||
list_del(&alg->list);
|
||||
spin_unlock_irqrestore(&libipw_crypto_lock, flags);
|
||||
kfree(alg);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_unregister_crypto_ops);
|
||||
|
||||
const struct libipw_crypto_ops *libipw_get_crypto_ops(const char *name)
|
||||
{
|
||||
struct libipw_crypto_alg *alg;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&libipw_crypto_lock, flags);
|
||||
list_for_each_entry(alg, &libipw_crypto_algs, list) {
|
||||
if (strcmp(alg->ops->name, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
spin_unlock_irqrestore(&libipw_crypto_lock, flags);
|
||||
return NULL;
|
||||
|
||||
found:
|
||||
spin_unlock_irqrestore(&libipw_crypto_lock, flags);
|
||||
return alg->ops;
|
||||
}
|
||||
EXPORT_SYMBOL(libipw_get_crypto_ops);
|
||||
|
||||
static void *libipw_crypt_null_init(int keyidx)
|
||||
{
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
static void libipw_crypt_null_deinit(void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct libipw_crypto_ops libipw_crypt_null = {
|
||||
.name = "NULL",
|
||||
.init = libipw_crypt_null_init,
|
||||
.deinit = libipw_crypt_null_deinit,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int __init libipw_crypto_init(void)
|
||||
{
|
||||
return libipw_register_crypto_ops(&libipw_crypt_null);
|
||||
}
|
||||
|
||||
void libipw_crypto_exit(void)
|
||||
{
|
||||
libipw_unregister_crypto_ops(&libipw_crypt_null);
|
||||
BUG_ON(!list_empty(&libipw_crypto_algs));
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* lib80211 crypt: host-based CCMP encryption implementation for lib80211
|
||||
* libipw crypt: host-based CCMP encryption implementation for libipw
|
||||
*
|
||||
* Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
|
||||
|
|
@ -18,17 +18,10 @@
|
|||
#include <linux/if_arp.h>
|
||||
#include <asm/string.h>
|
||||
#include <linux/wireless.h>
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/aead.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Host AP crypt: CCMP");
|
||||
MODULE_LICENSE("GPL");
|
||||
#include "libipw.h"
|
||||
|
||||
#define AES_BLOCK_LEN 16
|
||||
#define CCMP_HDR_LEN 8
|
||||
|
|
@ -36,7 +29,7 @@ MODULE_LICENSE("GPL");
|
|||
#define CCMP_TK_LEN 16
|
||||
#define CCMP_PN_LEN 6
|
||||
|
||||
struct lib80211_ccmp_data {
|
||||
struct libipw_ccmp_data {
|
||||
u8 key[CCMP_TK_LEN];
|
||||
int key_set;
|
||||
|
||||
|
|
@ -56,9 +49,9 @@ struct lib80211_ccmp_data {
|
|||
u8 rx_aad[2 * AES_BLOCK_LEN];
|
||||
};
|
||||
|
||||
static void *lib80211_ccmp_init(int key_idx)
|
||||
static void *libipw_ccmp_init(int key_idx)
|
||||
{
|
||||
struct lib80211_ccmp_data *priv;
|
||||
struct libipw_ccmp_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
|
|
@ -83,9 +76,9 @@ static void *lib80211_ccmp_init(int key_idx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void lib80211_ccmp_deinit(void *priv)
|
||||
static void libipw_ccmp_deinit(void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *_priv = priv;
|
||||
struct libipw_ccmp_data *_priv = priv;
|
||||
if (_priv && _priv->tfm)
|
||||
crypto_free_aead(_priv->tfm);
|
||||
kfree(priv);
|
||||
|
|
@ -150,10 +143,10 @@ static int ccmp_init_iv_and_aad(const struct ieee80211_hdr *hdr,
|
|||
return aad_len;
|
||||
}
|
||||
|
||||
static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
|
||||
static int libipw_ccmp_hdr(struct sk_buff *skb, int hdr_len,
|
||||
u8 *aeskey, int keylen, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *key = priv;
|
||||
struct libipw_ccmp_data *key = priv;
|
||||
int i;
|
||||
u8 *pos;
|
||||
|
||||
|
|
@ -187,9 +180,9 @@ static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
|
|||
return CCMP_HDR_LEN;
|
||||
}
|
||||
|
||||
static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *key = priv;
|
||||
struct libipw_ccmp_data *key = priv;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct aead_request *req;
|
||||
struct scatterlist sg[2];
|
||||
|
|
@ -202,7 +195,7 @@ static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
return -1;
|
||||
|
||||
data_len = skb->len - hdr_len;
|
||||
len = lib80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
|
||||
len = libipw_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
|
|
@ -251,9 +244,9 @@ static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *key = priv;
|
||||
struct libipw_ccmp_data *key = priv;
|
||||
u8 keyidx, *pos;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct aead_request *req;
|
||||
|
|
@ -299,7 +292,7 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
pos += 8;
|
||||
|
||||
if (ccmp_replay_check(pn, key->rx_pn)) {
|
||||
#ifdef CONFIG_LIB80211_DEBUG
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
net_dbg_ratelimited("CCMP: replay detected: STA=%pM previous PN %02x%02x%02x%02x%02x%02x received PN %02x%02x%02x%02x%02x%02x\n",
|
||||
hdr->addr2,
|
||||
key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
|
||||
|
|
@ -344,9 +337,9 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
return keyidx;
|
||||
}
|
||||
|
||||
static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *data = priv;
|
||||
struct libipw_ccmp_data *data = priv;
|
||||
int keyidx;
|
||||
struct crypto_aead *tfm = data->tfm;
|
||||
|
||||
|
|
@ -376,9 +369,9 @@ static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *data = priv;
|
||||
struct libipw_ccmp_data *data = priv;
|
||||
|
||||
if (len < CCMP_TK_LEN)
|
||||
return -1;
|
||||
|
|
@ -399,9 +392,9 @@ static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
|
|||
return CCMP_TK_LEN;
|
||||
}
|
||||
|
||||
static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv)
|
||||
static void libipw_ccmp_print_stats(struct seq_file *m, void *priv)
|
||||
{
|
||||
struct lib80211_ccmp_data *ccmp = priv;
|
||||
struct libipw_ccmp_data *ccmp = priv;
|
||||
|
||||
seq_printf(m,
|
||||
"key[%d] alg=CCMP key_set=%d "
|
||||
|
|
@ -418,31 +411,28 @@ static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv)
|
|||
ccmp->dot11RSNAStatsCCMPDecryptErrors);
|
||||
}
|
||||
|
||||
static const struct lib80211_crypto_ops lib80211_crypt_ccmp = {
|
||||
static const struct libipw_crypto_ops libipw_crypt_ccmp = {
|
||||
.name = "CCMP",
|
||||
.init = lib80211_ccmp_init,
|
||||
.deinit = lib80211_ccmp_deinit,
|
||||
.encrypt_mpdu = lib80211_ccmp_encrypt,
|
||||
.decrypt_mpdu = lib80211_ccmp_decrypt,
|
||||
.init = libipw_ccmp_init,
|
||||
.deinit = libipw_ccmp_deinit,
|
||||
.encrypt_mpdu = libipw_ccmp_encrypt,
|
||||
.decrypt_mpdu = libipw_ccmp_decrypt,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = lib80211_ccmp_set_key,
|
||||
.get_key = lib80211_ccmp_get_key,
|
||||
.print_stats = lib80211_ccmp_print_stats,
|
||||
.set_key = libipw_ccmp_set_key,
|
||||
.get_key = libipw_ccmp_get_key,
|
||||
.print_stats = libipw_ccmp_print_stats,
|
||||
.extra_mpdu_prefix_len = CCMP_HDR_LEN,
|
||||
.extra_mpdu_postfix_len = CCMP_MIC_LEN,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init lib80211_crypto_ccmp_init(void)
|
||||
int __init libipw_crypto_ccmp_init(void)
|
||||
{
|
||||
return lib80211_register_crypto_ops(&lib80211_crypt_ccmp);
|
||||
return libipw_register_crypto_ops(&libipw_crypt_ccmp);
|
||||
}
|
||||
|
||||
static void __exit lib80211_crypto_ccmp_exit(void)
|
||||
void libipw_crypto_ccmp_exit(void)
|
||||
{
|
||||
lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp);
|
||||
libipw_unregister_crypto_ops(&libipw_crypt_ccmp);
|
||||
}
|
||||
|
||||
module_init(lib80211_crypto_ccmp_init);
|
||||
module_exit(lib80211_crypto_ccmp_exit);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* lib80211 crypt: host-based TKIP encryption implementation for lib80211
|
||||
* libipw crypt: host-based TKIP encryption implementation for libipw
|
||||
*
|
||||
* Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
|
||||
|
|
@ -21,25 +21,18 @@
|
|||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/iw_handler.h>
|
||||
|
||||
#include <crypto/arc4.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("lib80211 crypt: TKIP");
|
||||
MODULE_LICENSE("GPL");
|
||||
#include "libipw.h"
|
||||
|
||||
#define TKIP_HDR_LEN 8
|
||||
|
||||
struct lib80211_tkip_data {
|
||||
struct libipw_tkip_data {
|
||||
#define TKIP_KEY_LEN 32
|
||||
u8 key[TKIP_KEY_LEN];
|
||||
int key_set;
|
||||
|
|
@ -73,23 +66,23 @@ struct lib80211_tkip_data {
|
|||
unsigned long flags;
|
||||
};
|
||||
|
||||
static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv)
|
||||
static unsigned long libipw_tkip_set_flags(unsigned long flags, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *_priv = priv;
|
||||
struct libipw_tkip_data *_priv = priv;
|
||||
unsigned long old_flags = _priv->flags;
|
||||
_priv->flags = flags;
|
||||
return old_flags;
|
||||
}
|
||||
|
||||
static unsigned long lib80211_tkip_get_flags(void *priv)
|
||||
static unsigned long libipw_tkip_get_flags(void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *_priv = priv;
|
||||
struct libipw_tkip_data *_priv = priv;
|
||||
return _priv->flags;
|
||||
}
|
||||
|
||||
static void *lib80211_tkip_init(int key_idx)
|
||||
static void *libipw_tkip_init(int key_idx)
|
||||
{
|
||||
struct lib80211_tkip_data *priv;
|
||||
struct libipw_tkip_data *priv;
|
||||
|
||||
if (fips_enabled)
|
||||
return NULL;
|
||||
|
|
@ -124,9 +117,9 @@ static void *lib80211_tkip_init(int key_idx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void lib80211_tkip_deinit(void *priv)
|
||||
static void libipw_tkip_deinit(void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *_priv = priv;
|
||||
struct libipw_tkip_data *_priv = priv;
|
||||
if (_priv) {
|
||||
crypto_free_shash(_priv->tx_tfm_michael);
|
||||
crypto_free_shash(_priv->rx_tfm_michael);
|
||||
|
|
@ -280,10 +273,10 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
|
|||
#endif
|
||||
}
|
||||
|
||||
static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
|
||||
static int libipw_tkip_hdr(struct sk_buff *skb, int hdr_len,
|
||||
u8 * rc4key, int keylen, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
u8 *pos;
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
|
|
@ -324,9 +317,9 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
|
|||
return TKIP_HDR_LEN;
|
||||
}
|
||||
|
||||
static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
int len;
|
||||
u8 rc4key[16], *pos, *icv;
|
||||
u32 crc;
|
||||
|
|
@ -344,7 +337,7 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
len = skb->len - hdr_len;
|
||||
pos = skb->data + hdr_len;
|
||||
|
||||
if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
|
||||
if ((libipw_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
|
||||
return -1;
|
||||
|
||||
crc = ~crc32_le(~0, pos, len);
|
||||
|
|
@ -373,9 +366,9 @@ static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
u8 rc4key[16];
|
||||
u8 keyidx, *pos;
|
||||
u32 iv32;
|
||||
|
|
@ -419,7 +412,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
pos += TKIP_HDR_LEN;
|
||||
|
||||
if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
|
||||
#ifdef CONFIG_LIB80211_DEBUG
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x\n",
|
||||
hdr->addr2, tkey->rx_iv32, tkey->rx_iv16,
|
||||
iv32, iv16);
|
||||
|
|
@ -450,7 +443,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
* it needs to be recalculated for the next packet. */
|
||||
tkey->rx_phase1_done = 0;
|
||||
}
|
||||
#ifdef CONFIG_LIB80211_DEBUG
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n",
|
||||
hdr->addr2);
|
||||
#endif
|
||||
|
|
@ -538,10 +531,10 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
|
|||
hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
|
||||
}
|
||||
|
||||
static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
|
||||
static int libipw_michael_mic_add(struct sk_buff *skb, int hdr_len,
|
||||
void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
u8 *pos;
|
||||
|
||||
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
|
||||
|
|
@ -560,7 +553,7 @@ static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void lib80211_michael_mic_failure(struct net_device *dev,
|
||||
static void libipw_michael_mic_failure(struct net_device *dev,
|
||||
struct ieee80211_hdr *hdr,
|
||||
int keyidx)
|
||||
{
|
||||
|
|
@ -581,10 +574,10 @@ static void lib80211_michael_mic_failure(struct net_device *dev,
|
|||
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
|
||||
}
|
||||
|
||||
static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
||||
static int libipw_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
||||
int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
u8 mic[8];
|
||||
|
||||
if (!tkey->key_set)
|
||||
|
|
@ -602,7 +595,7 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
|||
skb->dev ? skb->dev->name : "N/A", hdr->addr2,
|
||||
keyidx);
|
||||
if (skb->dev)
|
||||
lib80211_michael_mic_failure(skb->dev, hdr, keyidx);
|
||||
libipw_michael_mic_failure(skb->dev, hdr, keyidx);
|
||||
tkey->dot11RSNAStatsTKIPLocalMICFailures++;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -617,9 +610,9 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_tkip_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
int keyidx;
|
||||
struct crypto_shash *tfm = tkey->tx_tfm_michael;
|
||||
struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4;
|
||||
|
|
@ -650,9 +643,9 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_tkip_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkey = priv;
|
||||
struct libipw_tkip_data *tkey = priv;
|
||||
|
||||
if (len < TKIP_KEY_LEN)
|
||||
return -1;
|
||||
|
|
@ -679,9 +672,9 @@ static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
|
|||
return TKIP_KEY_LEN;
|
||||
}
|
||||
|
||||
static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
|
||||
static void libipw_tkip_print_stats(struct seq_file *m, void *priv)
|
||||
{
|
||||
struct lib80211_tkip_data *tkip = priv;
|
||||
struct libipw_tkip_data *tkip = priv;
|
||||
seq_printf(m,
|
||||
"key[%d] alg=TKIP key_set=%d "
|
||||
"tx_pn=%02x%02x%02x%02x%02x%02x "
|
||||
|
|
@ -705,34 +698,31 @@ static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
|
|||
tkip->dot11RSNAStatsTKIPLocalMICFailures);
|
||||
}
|
||||
|
||||
static const struct lib80211_crypto_ops lib80211_crypt_tkip = {
|
||||
static const struct libipw_crypto_ops libipw_crypt_tkip = {
|
||||
.name = "TKIP",
|
||||
.init = lib80211_tkip_init,
|
||||
.deinit = lib80211_tkip_deinit,
|
||||
.encrypt_mpdu = lib80211_tkip_encrypt,
|
||||
.decrypt_mpdu = lib80211_tkip_decrypt,
|
||||
.encrypt_msdu = lib80211_michael_mic_add,
|
||||
.decrypt_msdu = lib80211_michael_mic_verify,
|
||||
.set_key = lib80211_tkip_set_key,
|
||||
.get_key = lib80211_tkip_get_key,
|
||||
.print_stats = lib80211_tkip_print_stats,
|
||||
.init = libipw_tkip_init,
|
||||
.deinit = libipw_tkip_deinit,
|
||||
.encrypt_mpdu = libipw_tkip_encrypt,
|
||||
.decrypt_mpdu = libipw_tkip_decrypt,
|
||||
.encrypt_msdu = libipw_michael_mic_add,
|
||||
.decrypt_msdu = libipw_michael_mic_verify,
|
||||
.set_key = libipw_tkip_set_key,
|
||||
.get_key = libipw_tkip_get_key,
|
||||
.print_stats = libipw_tkip_print_stats,
|
||||
.extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
|
||||
.extra_mpdu_postfix_len = 4, /* ICV */
|
||||
.extra_msdu_postfix_len = 8, /* MIC */
|
||||
.get_flags = lib80211_tkip_get_flags,
|
||||
.set_flags = lib80211_tkip_set_flags,
|
||||
.get_flags = libipw_tkip_get_flags,
|
||||
.set_flags = libipw_tkip_set_flags,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init lib80211_crypto_tkip_init(void)
|
||||
int __init libipw_crypto_tkip_init(void)
|
||||
{
|
||||
return lib80211_register_crypto_ops(&lib80211_crypt_tkip);
|
||||
return libipw_register_crypto_ops(&libipw_crypt_tkip);
|
||||
}
|
||||
|
||||
static void __exit lib80211_crypto_tkip_exit(void)
|
||||
void libipw_crypto_tkip_exit(void)
|
||||
{
|
||||
lib80211_unregister_crypto_ops(&lib80211_crypt_tkip);
|
||||
libipw_unregister_crypto_ops(&libipw_crypt_tkip);
|
||||
}
|
||||
|
||||
module_init(lib80211_crypto_tkip_init);
|
||||
module_exit(lib80211_crypto_tkip_exit);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* lib80211 crypt: host-based WEP encryption implementation for lib80211
|
||||
* libipw crypt: host-based WEP encryption implementation for libipw
|
||||
*
|
||||
* Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
|
||||
|
|
@ -16,17 +16,11 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include <crypto/arc4.h>
|
||||
#include <linux/crc32.h>
|
||||
#include "libipw.h"
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("lib80211 crypt: WEP");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct lib80211_wep_data {
|
||||
struct libipw_wep_data {
|
||||
u32 iv;
|
||||
#define WEP_KEY_LEN 13
|
||||
u8 key[WEP_KEY_LEN + 1];
|
||||
|
|
@ -36,9 +30,9 @@ struct lib80211_wep_data {
|
|||
struct arc4_ctx rx_ctx;
|
||||
};
|
||||
|
||||
static void *lib80211_wep_init(int keyidx)
|
||||
static void *libipw_wep_init(int keyidx)
|
||||
{
|
||||
struct lib80211_wep_data *priv;
|
||||
struct libipw_wep_data *priv;
|
||||
|
||||
if (fips_enabled)
|
||||
return NULL;
|
||||
|
|
@ -54,16 +48,16 @@ static void *lib80211_wep_init(int keyidx)
|
|||
return priv;
|
||||
}
|
||||
|
||||
static void lib80211_wep_deinit(void *priv)
|
||||
static void libipw_wep_deinit(void *priv)
|
||||
{
|
||||
kfree_sensitive(priv);
|
||||
}
|
||||
|
||||
/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
|
||||
static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
|
||||
static int libipw_wep_build_iv(struct sk_buff *skb, int hdr_len,
|
||||
u8 *key, int keylen, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
u32 klen;
|
||||
u8 *pos;
|
||||
|
||||
|
|
@ -102,19 +96,19 @@ static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
|
|||
*
|
||||
* WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
|
||||
*/
|
||||
static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
u32 crc, klen, len;
|
||||
u8 *pos, *icv;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
|
||||
/* other checks are in lib80211_wep_build_iv */
|
||||
/* other checks are in libipw_wep_build_iv */
|
||||
if (skb_tailroom(skb) < 4)
|
||||
return -1;
|
||||
|
||||
/* add the IV to the frame */
|
||||
if (lib80211_wep_build_iv(skb, hdr_len, NULL, 0, priv))
|
||||
if (libipw_wep_build_iv(skb, hdr_len, NULL, 0, priv))
|
||||
return -1;
|
||||
|
||||
/* Copy the IV into the first 3 bytes of the key */
|
||||
|
|
@ -148,9 +142,9 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
* Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
|
||||
* failure. If frame is OK, IV and ICV will be removed.
|
||||
*/
|
||||
static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
static int libipw_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
u32 crc, klen, plen;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
u8 keyidx, *pos, icv[4];
|
||||
|
|
@ -195,9 +189,9 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_wep_set_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
|
||||
if (len < 0 || len > WEP_KEY_LEN)
|
||||
return -1;
|
||||
|
|
@ -208,9 +202,9 @@ static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
static int libipw_wep_get_key(void *key, int len, u8 * seq, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
|
||||
if (len < wep->key_len)
|
||||
return -1;
|
||||
|
|
@ -220,37 +214,34 @@ static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
|
|||
return wep->key_len;
|
||||
}
|
||||
|
||||
static void lib80211_wep_print_stats(struct seq_file *m, void *priv)
|
||||
static void libipw_wep_print_stats(struct seq_file *m, void *priv)
|
||||
{
|
||||
struct lib80211_wep_data *wep = priv;
|
||||
struct libipw_wep_data *wep = priv;
|
||||
seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
|
||||
}
|
||||
|
||||
static const struct lib80211_crypto_ops lib80211_crypt_wep = {
|
||||
static const struct libipw_crypto_ops libipw_crypt_wep = {
|
||||
.name = "WEP",
|
||||
.init = lib80211_wep_init,
|
||||
.deinit = lib80211_wep_deinit,
|
||||
.encrypt_mpdu = lib80211_wep_encrypt,
|
||||
.decrypt_mpdu = lib80211_wep_decrypt,
|
||||
.init = libipw_wep_init,
|
||||
.deinit = libipw_wep_deinit,
|
||||
.encrypt_mpdu = libipw_wep_encrypt,
|
||||
.decrypt_mpdu = libipw_wep_decrypt,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = lib80211_wep_set_key,
|
||||
.get_key = lib80211_wep_get_key,
|
||||
.print_stats = lib80211_wep_print_stats,
|
||||
.set_key = libipw_wep_set_key,
|
||||
.get_key = libipw_wep_get_key,
|
||||
.print_stats = libipw_wep_print_stats,
|
||||
.extra_mpdu_prefix_len = 4, /* IV */
|
||||
.extra_mpdu_postfix_len = 4, /* ICV */
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init lib80211_crypto_wep_init(void)
|
||||
int __init libipw_crypto_wep_init(void)
|
||||
{
|
||||
return lib80211_register_crypto_ops(&lib80211_crypt_wep);
|
||||
return libipw_register_crypto_ops(&libipw_crypt_wep);
|
||||
}
|
||||
|
||||
static void __exit lib80211_crypto_wep_exit(void)
|
||||
void __exit libipw_crypto_wep_exit(void)
|
||||
{
|
||||
lib80211_unregister_crypto_ops(&lib80211_crypt_wep);
|
||||
libipw_unregister_crypto_ops(&libipw_crypt_wep);
|
||||
}
|
||||
|
||||
module_init(lib80211_crypto_wep_init);
|
||||
module_exit(lib80211_crypto_wep_exit);
|
||||
|
|
@ -169,7 +169,7 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor)
|
|||
|
||||
spin_lock_init(&ieee->lock);
|
||||
|
||||
lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
|
||||
libipw_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
|
||||
|
||||
ieee->wpa_enabled = 0;
|
||||
ieee->drop_unencrypted = 0;
|
||||
|
|
@ -191,7 +191,7 @@ void free_libipw(struct net_device *dev, int monitor)
|
|||
{
|
||||
struct libipw_device *ieee = netdev_priv(dev);
|
||||
|
||||
lib80211_crypt_info_free(&ieee->crypt_info);
|
||||
libipw_crypt_info_free(&ieee->crypt_info);
|
||||
|
||||
libipw_networks_free(ieee);
|
||||
|
||||
|
|
@ -251,6 +251,7 @@ static const struct proc_ops debug_level_proc_ops = {
|
|||
|
||||
static int __init libipw_init(void)
|
||||
{
|
||||
int err;
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
struct proc_dir_entry *e;
|
||||
|
||||
|
|
@ -273,7 +274,33 @@ static int __init libipw_init(void)
|
|||
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
|
||||
|
||||
err = libipw_crypto_init();
|
||||
if (err)
|
||||
goto remove_debugfs;
|
||||
err = libipw_crypto_ccmp_init();
|
||||
if (err)
|
||||
goto uninit_crypto;
|
||||
err = libipw_crypto_tkip_init();
|
||||
if (err)
|
||||
goto uninit_crypto_ccmp;
|
||||
err = libipw_crypto_wep_init();
|
||||
if (err)
|
||||
goto uninit_crypto_tkip;
|
||||
|
||||
return 0;
|
||||
uninit_crypto_tkip:
|
||||
libipw_crypto_tkip_exit();
|
||||
uninit_crypto_ccmp:
|
||||
libipw_crypto_ccmp_exit();
|
||||
uninit_crypto:
|
||||
libipw_crypto_exit();
|
||||
remove_debugfs:
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
remove_proc_entry("debug_level", libipw_proc);
|
||||
remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
|
||||
libipw_proc = NULL;
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit libipw_exit(void)
|
||||
|
|
@ -285,6 +312,11 @@ static void __exit libipw_exit(void)
|
|||
libipw_proc = NULL;
|
||||
}
|
||||
#endif /* CONFIG_LIBIPW_DEBUG */
|
||||
|
||||
libipw_crypto_ccmp_exit();
|
||||
libipw_crypto_tkip_exit();
|
||||
libipw_crypto_wep_exit();
|
||||
libipw_crypto_exit();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@
|
|||
#include <linux/etherdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "libipw.h"
|
||||
|
||||
static void libipw_monitor_rx(struct libipw_device *ieee,
|
||||
|
|
@ -266,7 +263,7 @@ static int libipw_is_eapol_frame(struct libipw_device *ieee,
|
|||
/* Called only as a tasklet (software IRQ), by libipw_rx */
|
||||
static int
|
||||
libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
|
||||
struct lib80211_crypt_data *crypt)
|
||||
struct libipw_crypt_data *crypt)
|
||||
{
|
||||
struct libipw_hdr_3addr *hdr;
|
||||
int res, hdrlen;
|
||||
|
|
@ -298,7 +295,7 @@ libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
|
|||
static int
|
||||
libipw_rx_frame_decrypt_msdu(struct libipw_device *ieee,
|
||||
struct sk_buff *skb, int keyidx,
|
||||
struct lib80211_crypt_data *crypt)
|
||||
struct libipw_crypt_data *crypt)
|
||||
{
|
||||
struct libipw_hdr_3addr *hdr;
|
||||
int res, hdrlen;
|
||||
|
|
@ -345,7 +342,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
|
|||
#endif
|
||||
u8 dst[ETH_ALEN];
|
||||
u8 src[ETH_ALEN];
|
||||
struct lib80211_crypt_data *crypt = NULL;
|
||||
struct libipw_crypt_data *crypt = NULL;
|
||||
int keyidx = 0;
|
||||
int can_be_decrypted = 0;
|
||||
|
||||
|
|
@ -396,7 +393,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
|
|||
wstats.updated |= IW_QUAL_QUAL_INVALID;
|
||||
|
||||
/* Update spy records */
|
||||
wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
|
||||
libipw_spy_update(ieee->dev, hdr->addr2, &wstats);
|
||||
}
|
||||
#endif /* IW_WIRELESS_SPY */
|
||||
#endif /* CONFIG_WIRELESS_EXT */
|
||||
|
|
|
|||
|
|
@ -14,19 +14,21 @@
|
|||
#include <net/iw_handler.h>
|
||||
#include <net/arp.h>
|
||||
#include <net/wext.h>
|
||||
#include "libipw.h"
|
||||
|
||||
static inline struct iw_spy_data *get_spydata(struct net_device *dev)
|
||||
static struct iw_spy_data *get_spydata(struct net_device *dev)
|
||||
{
|
||||
/* This is the new way */
|
||||
if (dev->wireless_data)
|
||||
return dev->wireless_data->spy_data;
|
||||
struct libipw_device *ieee = netdev_priv(dev);
|
||||
|
||||
if (ieee->spy_enabled)
|
||||
return &ieee->spy_data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int iw_handler_set_spy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
int ipw_wx_set_spy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
{
|
||||
struct iw_spy_data * spydata = get_spydata(dev);
|
||||
struct sockaddr * address = (struct sockaddr *) extra;
|
||||
|
|
@ -36,15 +38,15 @@ int iw_handler_set_spy(struct net_device * dev,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
/* Disable spy collection while we copy the addresses.
|
||||
* While we copy addresses, any call to wireless_spy_update()
|
||||
* While we copy addresses, any call to libipw_spy_update()
|
||||
* will NOP. This is OK, as anyway the addresses are changing. */
|
||||
spydata->spy_number = 0;
|
||||
|
||||
/* We want to operate without locking, because wireless_spy_update()
|
||||
/* We want to operate without locking, because libipw_spy_update()
|
||||
* most likely will happen in the interrupt handler, and therefore
|
||||
* have its own locking constraints and needs performance.
|
||||
* The rtnl_lock() make sure we don't race with the other iw_handlers.
|
||||
* This make sure wireless_spy_update() "see" that the spy list
|
||||
* This make sure libipw_spy_update() "see" that the spy list
|
||||
* is temporarily disabled. */
|
||||
smp_wmb();
|
||||
|
||||
|
|
@ -69,12 +71,12 @@ int iw_handler_set_spy(struct net_device * dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iw_handler_set_spy);
|
||||
EXPORT_SYMBOL(ipw_wx_set_spy);
|
||||
|
||||
int iw_handler_get_spy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
int ipw_wx_get_spy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
{
|
||||
struct iw_spy_data * spydata = get_spydata(dev);
|
||||
struct sockaddr * address = (struct sockaddr *) extra;
|
||||
|
|
@ -101,16 +103,16 @@ int iw_handler_get_spy(struct net_device * dev,
|
|||
spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iw_handler_get_spy);
|
||||
EXPORT_SYMBOL(ipw_wx_get_spy);
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
* Standard Wireless Handler : set spy threshold
|
||||
*/
|
||||
int iw_handler_set_thrspy(struct net_device * dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
int ipw_wx_set_thrspy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
{
|
||||
struct iw_spy_data * spydata = get_spydata(dev);
|
||||
struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
|
||||
|
|
@ -128,16 +130,16 @@ int iw_handler_set_thrspy(struct net_device * dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iw_handler_set_thrspy);
|
||||
EXPORT_SYMBOL(ipw_wx_set_thrspy);
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
* Standard Wireless Handler : get spy threshold
|
||||
*/
|
||||
int iw_handler_get_thrspy(struct net_device * dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
int ipw_wx_get_thrspy(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
{
|
||||
struct iw_spy_data * spydata = get_spydata(dev);
|
||||
struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
|
||||
|
|
@ -152,7 +154,7 @@ int iw_handler_get_thrspy(struct net_device * dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iw_handler_get_thrspy);
|
||||
EXPORT_SYMBOL(ipw_wx_get_thrspy);
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
|
|
@ -189,9 +191,9 @@ static void iw_send_thrspy_event(struct net_device * dev,
|
|||
* small, this is good enough. If we wanted to support larger number of
|
||||
* spy addresses, we should use something more efficient...
|
||||
*/
|
||||
void wireless_spy_update(struct net_device * dev,
|
||||
unsigned char * address,
|
||||
struct iw_quality * wstats)
|
||||
void libipw_spy_update(struct net_device * dev,
|
||||
unsigned char * address,
|
||||
struct iw_quality * wstats)
|
||||
{
|
||||
struct iw_spy_data * spydata = get_spydata(dev);
|
||||
int i;
|
||||
|
|
@ -229,4 +231,3 @@ void wireless_spy_update(struct net_device * dev,
|
|||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(wireless_spy_update);
|
||||
|
|
@ -138,7 +138,7 @@ static int libipw_copy_snap(u8 * data, __be16 h_proto)
|
|||
static int libipw_encrypt_fragment(struct libipw_device *ieee,
|
||||
struct sk_buff *frag, int hdr_len)
|
||||
{
|
||||
struct lib80211_crypt_data *crypt =
|
||||
struct libipw_crypt_data *crypt =
|
||||
ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
||||
int res;
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
.qos_ctl = 0
|
||||
};
|
||||
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct libipw_crypt_data *crypt;
|
||||
int priority = skb->priority;
|
||||
int snapped = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
#include <linux/wireless.h>
|
||||
|
||||
#include "libipw.h"
|
||||
|
||||
static const char *libipw_modes[] = {
|
||||
|
|
@ -303,7 +300,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
|||
.flags = 0
|
||||
};
|
||||
int i, key, key_provided, len;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
struct libipw_crypt_data **crypt;
|
||||
int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
|
||||
|
||||
LIBIPW_DEBUG_WX("SET_ENCODE\n");
|
||||
|
|
@ -328,7 +325,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
|||
if (key_provided && *crypt) {
|
||||
LIBIPW_DEBUG_WX("Disabling encryption on key %d.\n",
|
||||
key);
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
} else
|
||||
LIBIPW_DEBUG_WX("Disabling encryption.\n");
|
||||
|
||||
|
|
@ -338,7 +335,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
|||
if (ieee->crypt_info.crypt[i] != NULL) {
|
||||
if (key_provided)
|
||||
break;
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info,
|
||||
libipw_crypt_delayed_deinit(&ieee->crypt_info,
|
||||
&ieee->crypt_info.crypt[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -361,21 +358,21 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
|||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||
/* changing to use WEP; deinit previously used algorithm
|
||||
* on this key */
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
}
|
||||
|
||||
if (*crypt == NULL && host_crypto) {
|
||||
struct lib80211_crypt_data *new_crypt;
|
||||
struct libipw_crypt_data *new_crypt;
|
||||
|
||||
/* take WEP into use */
|
||||
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||
new_crypt = kzalloc(sizeof(struct libipw_crypt_data),
|
||||
GFP_KERNEL);
|
||||
if (new_crypt == NULL)
|
||||
return -ENOMEM;
|
||||
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||
new_crypt->ops = libipw_get_crypto_ops("WEP");
|
||||
if (!new_crypt->ops) {
|
||||
request_module("lib80211_crypt_wep");
|
||||
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||
request_module("libipw_crypt_wep");
|
||||
new_crypt->ops = libipw_get_crypto_ops("WEP");
|
||||
}
|
||||
|
||||
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
||||
|
|
@ -386,7 +383,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
|||
new_crypt = NULL;
|
||||
|
||||
printk(KERN_WARNING "%s: could not initialize WEP: "
|
||||
"load module lib80211_crypt_wep\n", dev->name);
|
||||
"load module libipw_crypt_wep\n", dev->name);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
*crypt = new_crypt;
|
||||
|
|
@ -509,8 +506,8 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
|||
int i, idx, ret = 0;
|
||||
int group_key = 0;
|
||||
const char *alg, *module;
|
||||
const struct lib80211_crypto_ops *ops;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
const struct libipw_crypto_ops *ops;
|
||||
struct libipw_crypt_data **crypt;
|
||||
|
||||
struct libipw_security sec = {
|
||||
.flags = 0,
|
||||
|
|
@ -541,7 +538,7 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
|||
if ((encoding->flags & IW_ENCODE_DISABLED) ||
|
||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
||||
if (*crypt)
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
|
||||
for (i = 0; i < WEP_KEYS; i++)
|
||||
if (ieee->crypt_info.crypt[i] != NULL)
|
||||
|
|
@ -567,15 +564,15 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
|||
switch (ext->alg) {
|
||||
case IW_ENCODE_ALG_WEP:
|
||||
alg = "WEP";
|
||||
module = "lib80211_crypt_wep";
|
||||
module = "libipw_crypt_wep";
|
||||
break;
|
||||
case IW_ENCODE_ALG_TKIP:
|
||||
alg = "TKIP";
|
||||
module = "lib80211_crypt_tkip";
|
||||
module = "libipw_crypt_tkip";
|
||||
break;
|
||||
case IW_ENCODE_ALG_CCMP:
|
||||
alg = "CCMP";
|
||||
module = "lib80211_crypt_ccmp";
|
||||
module = "libipw_crypt_ccmp";
|
||||
break;
|
||||
default:
|
||||
LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||
|
|
@ -584,10 +581,10 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
|||
goto done;
|
||||
}
|
||||
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
ops = libipw_get_crypto_ops(alg);
|
||||
if (ops == NULL) {
|
||||
request_module(module);
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
ops = libipw_get_crypto_ops(alg);
|
||||
}
|
||||
if (ops == NULL) {
|
||||
LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||
|
|
@ -597,9 +594,9 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
|
|||
}
|
||||
|
||||
if (*crypt == NULL || (*crypt)->ops != ops) {
|
||||
struct lib80211_crypt_data *new_crypt;
|
||||
struct libipw_crypt_data *new_crypt;
|
||||
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
|
||||
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
|
||||
if (new_crypt == NULL) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MAX 93
|
||||
#define IWL_BZ_UCODE_API_MAX 94
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MIN 90
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MAX 93
|
||||
#define IWL_SC_UCODE_API_MAX 94
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MIN 90
|
||||
|
|
|
|||
|
|
@ -382,6 +382,8 @@ struct iwl_mac_config_cmd {
|
|||
* @LINK_CONTEXT_MODIFY_EHT_PARAMS: covers iwl_link_ctx_cfg_cmd::puncture_mask.
|
||||
* This flag can be set only if the MAC that this link relates to has
|
||||
* eht_support set to true. No longer used since _VER_3 of this command.
|
||||
* @LINK_CONTEXT_MODIFY_BANDWIDTH: Covers iwl_link_ctx_cfg_cmd::modify_bandwidth.
|
||||
* Request RX OMI to the AP to modify bandwidth of this link.
|
||||
* @LINK_CONTEXT_MODIFY_ALL: set all above flags
|
||||
*/
|
||||
enum iwl_link_ctx_modify_flags {
|
||||
|
|
@ -393,6 +395,7 @@ enum iwl_link_ctx_modify_flags {
|
|||
LINK_CONTEXT_MODIFY_HE_PARAMS = BIT(5),
|
||||
LINK_CONTEXT_MODIFY_BSS_COLOR_DISABLE = BIT(6),
|
||||
LINK_CONTEXT_MODIFY_EHT_PARAMS = BIT(7),
|
||||
LINK_CONTEXT_MODIFY_BANDWIDTH = BIT(8),
|
||||
LINK_CONTEXT_MODIFY_ALL = 0xff,
|
||||
}; /* LINK_CONTEXT_MODIFY_MASK_E_VER_1 */
|
||||
|
||||
|
|
@ -433,6 +436,22 @@ enum iwl_link_ctx_flags {
|
|||
LINK_FLG_NDP_FEEDBACK_ENABLED = BIT(3),
|
||||
}; /* LINK_CONTEXT_FLAG_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_link_modify_bandwidth - link modify (RX OMI) bandwidth
|
||||
* @IWL_LINK_MODIFY_BW_20: request 20 MHz
|
||||
* @IWL_LINK_MODIFY_BW_40: request 40 MHz
|
||||
* @IWL_LINK_MODIFY_BW_80: request 80 MHz
|
||||
* @IWL_LINK_MODIFY_BW_160: request 160 MHz
|
||||
* @IWL_LINK_MODIFY_BW_320: request 320 MHz
|
||||
*/
|
||||
enum iwl_link_modify_bandwidth {
|
||||
IWL_LINK_MODIFY_BW_20,
|
||||
IWL_LINK_MODIFY_BW_40,
|
||||
IWL_LINK_MODIFY_BW_80,
|
||||
IWL_LINK_MODIFY_BW_160,
|
||||
IWL_LINK_MODIFY_BW_320,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_link_config_cmd - command structure to configure the LINK context
|
||||
* in MLD API
|
||||
|
|
@ -457,6 +476,8 @@ enum iwl_link_ctx_flags {
|
|||
* @block_tx: tell the firmware that this link can't Tx. This should be used
|
||||
* only when a link is de-activated because of CSA with mode = 1.
|
||||
* Available since version 5.
|
||||
* @modify_bandwidth: bandwidth request value for RX OMI (see also
|
||||
* %LINK_CONTEXT_MODIFY_BANDWIDTH), from &enum iwl_link_modify_bandwidth.
|
||||
* @reserved1: in version 2, listen_lmac became reserved
|
||||
* @cck_rates: basic rates available for CCK
|
||||
* @ofdm_rates: basic rates available for OFDM
|
||||
|
|
@ -500,10 +521,11 @@ struct iwl_link_config_cmd {
|
|||
__le32 modify_mask;
|
||||
__le32 active;
|
||||
union {
|
||||
__le32 listen_lmac;
|
||||
__le32 listen_lmac; /* only _VER_1 */
|
||||
struct {
|
||||
u8 block_tx;
|
||||
u8 reserved1[3];
|
||||
u8 block_tx; /* since _VER_5 */
|
||||
u8 modify_bandwidth; /* since _VER_6 */
|
||||
u8 reserved1[2];
|
||||
};
|
||||
};
|
||||
__le32 cck_rates;
|
||||
|
|
@ -524,7 +546,7 @@ struct iwl_link_config_cmd {
|
|||
__le16 puncture_mask; /* removed in _VER_3 */
|
||||
__le16 frame_time_rts_th;
|
||||
__le32 flags;
|
||||
__le32 flags_mask;
|
||||
__le32 flags_mask; /* removed in _VER_6 */
|
||||
/* The below fields are for multi-bssid */
|
||||
u8 ref_bssid_addr[6];
|
||||
__le16 reserved_for_ref_bssid_addr;
|
||||
|
|
@ -535,7 +557,7 @@ struct iwl_link_config_cmd {
|
|||
u8 ibss_bssid_addr[6];
|
||||
__le16 reserved_for_ibss_bssid_addr;
|
||||
__le32 reserved3[8];
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5 */
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6 */
|
||||
|
||||
/* Currently FW supports link ids in the range 0-3 and can have
|
||||
* at most two active links for each vif.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021-2023 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021-2024 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -327,18 +327,19 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt);
|
|||
void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt,
|
||||
u32 timepoint,
|
||||
u32 timepoint_data);
|
||||
bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id);
|
||||
void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt);
|
||||
void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
#define IWL_FW_CHECK_FAILED(_obj, _fmt, ...) \
|
||||
IWL_ERR_LIMIT(_obj, _fmt, __VA_ARGS__)
|
||||
#define IWL_FW_CHECK_FAILED(_obj, ...) \
|
||||
IWL_ERR_LIMIT(_obj, __VA_ARGS__)
|
||||
|
||||
#define IWL_FW_CHECK(_obj, _cond, _fmt, ...) \
|
||||
({ \
|
||||
bool __cond = (_cond); \
|
||||
\
|
||||
if (unlikely(__cond)) \
|
||||
IWL_FW_CHECK_FAILED(_obj, _fmt, __VA_ARGS__); \
|
||||
IWL_FW_CHECK_FAILED(_obj, _fmt, ##__VA_ARGS__); \
|
||||
\
|
||||
unlikely(__cond); \
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2023 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -530,3 +530,23 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)
|
|||
}
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fwrt_dump_error_logs);
|
||||
|
||||
bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id)
|
||||
{
|
||||
struct error_table_start {
|
||||
/* cf. struct iwl_error_event_table */
|
||||
u32 valid;
|
||||
__le32 err_id;
|
||||
} err_info;
|
||||
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
iwl_trans_read_mem_bytes(trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
if (err_info.valid && err_id)
|
||||
*err_id = le32_to_cpu(err_info.err_id);
|
||||
|
||||
return !!err_info.valid;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fwrt_read_err_table);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
#define IWL_MVM_TRIGGER_LINK_SEL_TIME_SEC 30
|
||||
#define IWL_MVM_TPT_COUNT_WINDOW_SEC 5
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS 5
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH 11
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH 15
|
||||
#define IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED 11
|
||||
|
||||
#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
|
||||
#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
|
||||
|
|
@ -57,7 +58,6 @@
|
|||
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
|
||||
#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1
|
||||
#define IWL_MVM_TOF_IS_RESPONDER 0
|
||||
#define IWL_MVM_HW_CSUM_DISABLE 0
|
||||
#define IWL_MVM_ADWELL_ENABLE 1
|
||||
#define IWL_MVM_ADWELL_MAX_BUDGET 0
|
||||
#define IWL_MVM_TCM_LOAD_MEDIUM_THRESH 10 /* percentage */
|
||||
|
|
|
|||
|
|
@ -3024,24 +3024,6 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
|
|||
ieee80211_resume_disconnect(vif);
|
||||
}
|
||||
|
||||
static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
|
||||
{
|
||||
struct error_table_start {
|
||||
/* cf. struct iwl_error_event_table */
|
||||
u32 valid;
|
||||
__le32 err_id;
|
||||
} err_info;
|
||||
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
iwl_trans_read_mem_bytes(trans, base,
|
||||
&err_info, sizeof(err_info));
|
||||
if (err_info.valid && err_id)
|
||||
*err_id = le32_to_cpu(err_info.err_id);
|
||||
|
||||
return !!err_info.valid;
|
||||
}
|
||||
|
||||
static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
|
|
@ -3049,9 +3031,9 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
|||
u32 err_id;
|
||||
|
||||
/* check for lmac1 error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[0],
|
||||
&err_id)) {
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[0],
|
||||
&err_id)) {
|
||||
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN && vif) {
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
.rfkill_release = true,
|
||||
|
|
@ -3063,13 +3045,15 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
/* check if we have lmac2 set and check for error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[1], NULL))
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[1],
|
||||
NULL))
|
||||
return true;
|
||||
|
||||
/* check for umac error */
|
||||
if (iwl_mvm_rt_status(mvm->trans,
|
||||
mvm->trans->dbg.umac_error_event_table, NULL))
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.umac_error_event_table,
|
||||
NULL))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
HOW(BLOCKED_FW) \
|
||||
HOW(BLOCKED_NON_BSS) \
|
||||
HOW(BLOCKED_ROC) \
|
||||
HOW(BLOCKED_TMP_NON_BSS) \
|
||||
HOW(EXIT_MISSED_BEACON) \
|
||||
HOW(EXIT_LOW_RSSI) \
|
||||
HOW(EXIT_COEX) \
|
||||
|
|
@ -360,7 +361,8 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
send_cmd:
|
||||
cmd.modify_mask = cpu_to_le32(changes);
|
||||
cmd.flags = cpu_to_le32(flags);
|
||||
cmd.flags_mask = cpu_to_le32(flags_mask);
|
||||
if (cmd_ver < 6)
|
||||
cmd.flags_mask = cpu_to_le32(flags_mask);
|
||||
cmd.spec_link_id = link_conf->link_id;
|
||||
if (cmd_ver < 2)
|
||||
cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac);
|
||||
|
|
|
|||
|
|
@ -1605,6 +1605,7 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
0);
|
||||
u8 new_notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
|
||||
MISSED_BEACONS_NOTIF, 0);
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
|
||||
/* If the firmware uses the new notification (from MAC_CONF_GROUP),
|
||||
* refer to that notification's version.
|
||||
|
|
@ -1617,9 +1618,9 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
/* before version four the ID in the notification refers to mac ID */
|
||||
if (notif_ver < 4) {
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
|
||||
bss_conf = &vif->bss_conf;
|
||||
} else {
|
||||
struct ieee80211_bss_conf *bss_conf =
|
||||
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false);
|
||||
bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false);
|
||||
|
||||
if (!bss_conf)
|
||||
return;
|
||||
|
|
@ -1664,6 +1665,8 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
rx_missed_bcon, rx_missed_bcon_since_rx);
|
||||
}
|
||||
} else if (link_id >= 0 && hweight16(vif->active_links) > 1) {
|
||||
u32 bss_param_ch_cnt_link_id =
|
||||
bss_conf->bss_param_ch_cnt_link_id;
|
||||
u32 scnd_lnk_bcn_lost = 0;
|
||||
|
||||
if (notif_ver >= 5 &&
|
||||
|
|
@ -1677,10 +1680,14 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
/* Exit EMLSR if we lost more than
|
||||
* IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH beacons on boths links
|
||||
* OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH on any link.
|
||||
* OR more than IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED
|
||||
* and the link's bss_param_ch_count has changed.
|
||||
*/
|
||||
if ((rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS &&
|
||||
scnd_lnk_bcn_lost >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS) ||
|
||||
rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH)
|
||||
rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH ||
|
||||
(bss_param_ch_cnt_link_id != link_id &&
|
||||
rx_missed_bcon >= IWL_MVM_BCN_LOSS_EXIT_ESR_THRESH_BSS_PARAM_CHANGED))
|
||||
iwl_mvm_exit_esr(mvm, vif,
|
||||
IWL_MVM_ESR_EXIT_MISSED_BEACON,
|
||||
iwl_mvm_get_primary_link(vif));
|
||||
|
|
|
|||
|
|
@ -1336,6 +1336,8 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
|
|||
* of packets the FW sent out, so we must reconnect.
|
||||
*/
|
||||
iwl_mvm_teardown_tdls_peers(mvm);
|
||||
|
||||
IWL_INFO(mvm, "restart completed\n");
|
||||
}
|
||||
|
||||
void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
|
||||
|
|
@ -1466,15 +1468,16 @@ struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
int iwl_mvm_set_tx_power(struct iwl_mvm *mvm,
|
||||
struct ieee80211_bss_conf *link_conf,
|
||||
s16 tx_power)
|
||||
{
|
||||
u32 cmd_id = REDUCE_TX_POWER_CMD;
|
||||
u32 mac_id = iwl_mvm_vif_from_mac80211(link_conf->vif)->id;
|
||||
int len;
|
||||
struct iwl_dev_tx_power_cmd_v3_v8 cmd = {
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
|
||||
.common.mac_context_id =
|
||||
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
|
||||
.common.mac_context_id = cpu_to_le32(mac_id),
|
||||
};
|
||||
struct iwl_dev_tx_power_cmd cmd_v9_v10;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 3);
|
||||
|
|
@ -1487,8 +1490,7 @@ int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
if (cmd_ver > 8) {
|
||||
/* Those fields sit on the same place for v9 and v10 */
|
||||
cmd_v9_v10.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC);
|
||||
cmd_v9_v10.common.mac_context_id =
|
||||
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id);
|
||||
cmd_v9_v10.common.mac_context_id = cpu_to_le32(mac_id);
|
||||
cmd_v9_v10.common.pwr_restriction = cpu_to_le16(u_tx_power);
|
||||
cmd_data = &cmd_v9_v10;
|
||||
}
|
||||
|
|
@ -1731,6 +1733,21 @@ static void iwl_mvm_unblock_esr_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
|
|||
iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT);
|
||||
}
|
||||
|
||||
static void iwl_mvm_unblock_esr_tmp_non_bss(struct wiphy *wiphy,
|
||||
struct wiphy_work *wk)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif =
|
||||
container_of(wk, struct iwl_mvm_vif,
|
||||
unblock_esr_tmp_non_bss_wk.work);
|
||||
struct iwl_mvm *mvm = mvmvif->mvm;
|
||||
struct ieee80211_vif *vif =
|
||||
container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TMP_NON_BSS);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
|
||||
{
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
|
@ -1749,6 +1766,9 @@ void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
|
|||
|
||||
wiphy_work_init(&mvmvif->unblock_esr_tpt_wk,
|
||||
iwl_mvm_unblock_esr_tpt);
|
||||
|
||||
wiphy_delayed_work_init(&mvmvif->unblock_esr_tmp_non_bss_wk,
|
||||
iwl_mvm_unblock_esr_tmp_non_bss);
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
|
|
@ -1899,6 +1919,8 @@ void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
|
|||
&mvmvif->mlo_int_scan_wk);
|
||||
|
||||
wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);
|
||||
wiphy_delayed_work_cancel(mvm->hw->wiphy,
|
||||
&mvmvif->unblock_esr_tmp_non_bss_wk);
|
||||
|
||||
cancel_delayed_work_sync(&mvmvif->csa_work);
|
||||
}
|
||||
|
|
@ -3303,7 +3325,7 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (changes & BSS_CHANGED_TXPOWER) {
|
||||
IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n",
|
||||
bss_conf->txpower);
|
||||
iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
|
||||
iwl_mvm_set_tx_power(mvm, bss_conf, bss_conf->txpower);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4075,6 +4097,8 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
|
|||
&mvmvif->mlo_int_scan_wk);
|
||||
|
||||
wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);
|
||||
wiphy_delayed_work_cancel(mvm->hw->wiphy,
|
||||
&mvmvif->unblock_esr_tmp_non_bss_wk);
|
||||
|
||||
/* No need for the periodic statistics anymore */
|
||||
if (ieee80211_vif_is_mld(vif) && mvmvif->esr_active)
|
||||
|
|
@ -4236,8 +4260,9 @@ int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
|||
}
|
||||
|
||||
void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u32 changed)
|
||||
struct ieee80211_link_sta *link_sta, u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
if (changed & (IEEE80211_RC_BW_CHANGED |
|
||||
|
|
@ -5067,7 +5092,7 @@ void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
|
|||
(changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
|
||||
IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
|
||||
IEEE80211_CHANCTX_CHANGE_RADAR |
|
||||
IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
|
||||
IEEE80211_CHANCTX_CHANGE_MIN_DEF)),
|
||||
"Cannot change PHY. Ref=%d, changed=0x%X\n",
|
||||
phy_ctxt->ref, changed))
|
||||
return;
|
||||
|
|
@ -5075,7 +5100,7 @@ void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
|
|||
guard(mvm)(mvm);
|
||||
|
||||
/* we are only changing the min_width, may be a noop */
|
||||
if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) {
|
||||
if (changed == IEEE80211_CHANCTX_CHANGE_MIN_DEF) {
|
||||
if (phy_ctxt->width == def->width)
|
||||
return;
|
||||
|
||||
|
|
@ -6562,7 +6587,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
|
|||
.allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
|
||||
.release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
|
||||
.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
|
||||
.sta_rc_update = iwl_mvm_sta_rc_update,
|
||||
.link_sta_rc_update = iwl_mvm_sta_rc_update,
|
||||
.conf_tx = iwl_mvm_mac_conf_tx,
|
||||
.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
|
||||
.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
|
||||
|
|
|
|||
|
|
@ -331,23 +331,18 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* Initialize rate control for the AP station, since we might be
|
||||
* doing a link switch here - we cannot initialize it before since
|
||||
* this needs the phy context assigned (and in FW?), and we cannot
|
||||
* do it later because it needs to be initialized as soon as we're
|
||||
* able to TX on the link, i.e. when active.
|
||||
/*
|
||||
* if link switching (link not active yet) we'll activate it in
|
||||
* firmware later on link-info change, which mac80211 guarantees
|
||||
* for link switch after the stations are set up
|
||||
*/
|
||||
if (mvmvif->ap_sta) {
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
|
||||
rcu_read_lock();
|
||||
link_sta = rcu_dereference(mvmvif->ap_sta->link[link_id]);
|
||||
|
||||
if (!WARN_ON_ONCE(!link_sta))
|
||||
iwl_mvm_rs_rate_init(mvm, vif, mvmvif->ap_sta,
|
||||
link_conf, link_sta,
|
||||
phy_ctxt->channel->band);
|
||||
rcu_read_unlock();
|
||||
if (ieee80211_vif_link_active(vif, link_conf->link_id)) {
|
||||
ret = iwl_mvm_link_changed(mvm, vif, link_conf,
|
||||
LINK_CONTEXT_MODIFY_ACTIVE |
|
||||
LINK_CONTEXT_MODIFY_RATES_INFO,
|
||||
true);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
|
|
@ -355,14 +350,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
link_conf,
|
||||
false);
|
||||
|
||||
/* then activate */
|
||||
ret = iwl_mvm_link_changed(mvm, vif, link_conf,
|
||||
LINK_CONTEXT_MODIFY_ACTIVE |
|
||||
LINK_CONTEXT_MODIFY_RATES_INFO,
|
||||
true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Power state must be updated before quotas,
|
||||
* otherwise fw will complain.
|
||||
|
|
@ -775,6 +762,11 @@ iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm,
|
|||
if (WARN_ON_ONCE(!mvmvif->link[link_conf->link_id]))
|
||||
return;
|
||||
|
||||
/* not yet marked active in vif means during link switch */
|
||||
if (!ieee80211_vif_link_active(vif, link_conf->link_id) &&
|
||||
vif->cfg.assoc && mvmvif->link[link_conf->link_id]->phy_ctxt)
|
||||
link_changes |= LINK_CONTEXT_MODIFY_ACTIVE;
|
||||
|
||||
has_he = link_conf->he_support && !iwlwifi_mod_params.disable_11ax;
|
||||
has_eht = link_conf->eht_support && !iwlwifi_mod_params.disable_11be;
|
||||
|
||||
|
|
@ -1038,7 +1030,7 @@ static void iwl_mvm_mld_link_info_changed(struct ieee80211_hw *hw,
|
|||
if (changes & BSS_CHANGED_TXPOWER) {
|
||||
IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n",
|
||||
link_conf->txpower);
|
||||
iwl_mvm_set_tx_power(mvm, vif, link_conf->txpower);
|
||||
iwl_mvm_set_tx_power(mvm, link_conf, link_conf->txpower);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1376,6 +1368,36 @@ iwl_mvm_mld_mac_pre_channel_switch(struct ieee80211_hw *hw,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT (5 * HZ)
|
||||
|
||||
static void iwl_mvm_mld_prep_add_interface(struct ieee80211_hw *hw,
|
||||
enum nl80211_iftype type)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_MAC80211(mvm, "prep_add_interface: type=%u\n",
|
||||
type);
|
||||
|
||||
if (IS_ERR_OR_NULL(bss_vif) ||
|
||||
!(type == NL80211_IFTYPE_AP ||
|
||||
type == NL80211_IFTYPE_P2P_GO ||
|
||||
type == NL80211_IFTYPE_P2P_CLIENT))
|
||||
return;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(bss_vif);
|
||||
ret = iwl_mvm_block_esr_sync(mvm, bss_vif,
|
||||
IWL_MVM_ESR_BLOCKED_TMP_NON_BSS);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
wiphy_delayed_work_queue(mvmvif->mvm->hw->wiphy,
|
||||
&mvmvif->unblock_esr_tmp_non_bss_wk,
|
||||
IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT);
|
||||
}
|
||||
|
||||
const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
|
||||
.tx = iwl_mvm_mac_tx,
|
||||
.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
|
||||
|
|
@ -1401,7 +1423,7 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
|
|||
.allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
|
||||
.release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
|
||||
.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
|
||||
.sta_rc_update = iwl_mvm_sta_rc_update,
|
||||
.link_sta_rc_update = iwl_mvm_sta_rc_update,
|
||||
.conf_tx = iwl_mvm_mld_mac_conf_tx,
|
||||
.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
|
||||
.mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
|
||||
|
|
@ -1472,4 +1494,5 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
|
|||
.change_sta_links = iwl_mvm_mld_change_sta_links,
|
||||
.can_activate_links = iwl_mvm_mld_can_activate_links,
|
||||
.can_neg_ttlm = iwl_mvm_mld_can_neg_ttlm,
|
||||
.prep_add_interface = iwl_mvm_mld_prep_add_interface,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1182,6 +1182,9 @@ int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
|
|||
link_sta_added_to_fw |= BIT(link_id);
|
||||
|
||||
iwl_mvm_rs_add_sta_link(mvm, mvm_sta_link);
|
||||
|
||||
iwl_mvm_rs_rate_init(mvm, vif, sta, link_conf, link_sta,
|
||||
link_conf->chanreq.oper.chan->band);
|
||||
}
|
||||
|
||||
if (sta_mask_added) {
|
||||
|
|
|
|||
|
|
@ -361,6 +361,9 @@ struct iwl_mvm_vif_link_info {
|
|||
* @IWL_MVM_ESR_BLOCKED_NON_BSS: An active non-BSS interface's link is
|
||||
* preventing EMLSR
|
||||
* @IWL_MVM_ESR_BLOCKED_ROC: remain-on-channel is preventing EMLSR
|
||||
* @IWL_MVM_ESR_BLOCKED_TMP_NON_BSS: An expected active non-BSS interface's link
|
||||
* is preventing EMLSR. This is a temporary blocking that is set when there
|
||||
* is an indication that a non-BSS interface is to be added.
|
||||
* @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
|
||||
* @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
|
||||
* due to low RSSI.
|
||||
|
|
@ -379,6 +382,7 @@ enum iwl_mvm_esr_state {
|
|||
IWL_MVM_ESR_BLOCKED_FW = 0x8,
|
||||
IWL_MVM_ESR_BLOCKED_NON_BSS = 0x10,
|
||||
IWL_MVM_ESR_BLOCKED_ROC = 0x20,
|
||||
IWL_MVM_ESR_BLOCKED_TMP_NON_BSS = 0x40,
|
||||
IWL_MVM_ESR_EXIT_MISSED_BEACON = 0x10000,
|
||||
IWL_MVM_ESR_EXIT_LOW_RSSI = 0x20000,
|
||||
IWL_MVM_ESR_EXIT_COEX = 0x40000,
|
||||
|
|
@ -452,6 +456,8 @@ struct iwl_mvm_esr_exit {
|
|||
* @prevent_esr_done_wk: work that should be done when esr prevention ends.
|
||||
* @mlo_int_scan_wk: work for the internal MLO scan.
|
||||
* @unblock_esr_tpt_wk: work for unblocking EMLSR when tpt is high enough.
|
||||
* @unblock_esr_tmp_non_bss_wk: work for removing the
|
||||
* IWL_MVM_ESR_BLOCKED_TMP_NON_BSS blocking for EMLSR.
|
||||
* @roc_activity: currently running ROC activity for this vif (or
|
||||
* ROC_NUM_ACTIVITIES if no activity is running).
|
||||
* @session_prot_connection_loss: the connection was lost due to session
|
||||
|
|
@ -588,6 +594,7 @@ struct iwl_mvm_vif {
|
|||
struct wiphy_delayed_work prevent_esr_done_wk;
|
||||
struct wiphy_delayed_work mlo_int_scan_wk;
|
||||
struct wiphy_work unblock_esr_tpt_wk;
|
||||
struct wiphy_delayed_work unblock_esr_tmp_non_bss_wk;
|
||||
|
||||
struct iwl_mvm_vif_link_info deflink;
|
||||
struct iwl_mvm_vif_link_info *link[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
|
|
@ -773,7 +780,6 @@ struct iwl_mvm_tcm {
|
|||
* @head_sn: reorder window head sn
|
||||
* @num_stored: number of mpdus stored in the buffer
|
||||
* @queue: queue of this reorder buffer
|
||||
* @last_amsdu: track last ASMDU SN for duplication detection
|
||||
* @valid: reordering is valid for this queue
|
||||
* @lock: protect reorder buffer internal state
|
||||
*/
|
||||
|
|
@ -781,7 +787,6 @@ struct iwl_mvm_reorder_buffer {
|
|||
u16 head_sn;
|
||||
u16 num_stored;
|
||||
int queue;
|
||||
u16 last_amsdu;
|
||||
bool valid;
|
||||
spinlock_t lock;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
|
@ -1584,8 +1589,7 @@ static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm)
|
|||
static inline bool iwl_mvm_is_csum_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CSUM_SUPPORT) &&
|
||||
!IWL_MVM_HW_CSUM_DISABLE;
|
||||
IWL_UCODE_TLV_CAPA_CSUM_SUPPORT);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_mplut_supported(struct iwl_mvm *mvm)
|
||||
|
|
@ -2914,7 +2918,7 @@ iwl_mvm_mac_release_buffered_frames(struct ieee80211_hw *hw,
|
|||
bool more_data);
|
||||
int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
|
||||
void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u32 changed);
|
||||
struct ieee80211_link_sta *link_sta, u32 changed);
|
||||
void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_prep_tx_info *info);
|
||||
|
|
@ -2982,7 +2986,8 @@ void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
bool iwl_mvm_have_links_same_channel(struct iwl_mvm_vif *vif1,
|
||||
struct iwl_mvm_vif *vif2);
|
||||
bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif);
|
||||
int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
int iwl_mvm_set_tx_power(struct iwl_mvm *mvm,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
s16 tx_power);
|
||||
int iwl_mvm_set_hw_timestamp(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
|
|
|
|||
|
|
@ -440,12 +440,6 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
|||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
if (!mvmsta) {
|
||||
IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
|
||||
notif->sta_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags = le32_to_cpu(notif->flags);
|
||||
|
||||
mvm_link_sta = rcu_dereference(mvmsta->link[link_sta->link_id]);
|
||||
|
|
@ -615,11 +609,8 @@ void iwl_mvm_rs_fw_rate_init(struct iwl_mvm *mvm,
|
|||
int cmd_ver;
|
||||
int ret;
|
||||
|
||||
/* Enable external EHT LTF only for GL device and if there's
|
||||
* mutual support by AP and client
|
||||
*/
|
||||
if (CSR_HW_REV_TYPE(mvm->trans->hw_rev) == IWL_CFG_MAC_TYPE_GL &&
|
||||
sband_eht_cap &&
|
||||
/* Enable extra EHT LTF if there's mutual support by AP and client */
|
||||
if (sband_eht_cap &&
|
||||
sband_eht_cap->eht_cap_elem.phy_cap_info[5] &
|
||||
IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF &&
|
||||
link_sta->eht_cap.has_eht &&
|
||||
|
|
|
|||
|
|
@ -773,9 +773,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
|||
return false;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
sta_mask = iwl_mvm_sta_fw_id_mask(mvm, sta, -1);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (IWL_FW_CHECK(mvm,
|
||||
tid != baid_data->tid ||
|
||||
|
|
@ -814,7 +812,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
|||
if (!buffer->num_stored && ieee80211_sn_less(sn, nssn)) {
|
||||
if (!amsdu || last_subframe)
|
||||
buffer->head_sn = nssn;
|
||||
/* No need to update AMSDU last SN - we are moving the head */
|
||||
|
||||
spin_unlock_bh(&buffer->lock);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -831,7 +829,6 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
|||
if (!amsdu || last_subframe)
|
||||
buffer->head_sn = ieee80211_sn_inc(buffer->head_sn);
|
||||
|
||||
/* No need to update AMSDU last SN - we are moving the head */
|
||||
spin_unlock_bh(&buffer->lock);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -841,9 +838,6 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
|||
__skb_queue_tail(&entries[index].frames, skb);
|
||||
buffer->num_stored++;
|
||||
|
||||
if (amsdu)
|
||||
buffer->last_amsdu = sn;
|
||||
|
||||
/*
|
||||
* We cannot trust NSSN for AMSDU sub-frames that are not the last.
|
||||
* The reason is that NSSN advances on the first sub-frame, and may
|
||||
|
|
|
|||
|
|
@ -4328,7 +4328,10 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
unsigned int wdg_timeout =
|
||||
iwl_mvm_get_wd_timeout(mvm, vif);
|
||||
bool mld = iwl_mvm_has_mld_api(mvm->fw);
|
||||
u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
|
||||
u32 type = IWL_STA_LINK;
|
||||
|
||||
if (mld)
|
||||
type = STATION_TYPE_PEER;
|
||||
|
||||
ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
|
||||
NL80211_IFTYPE_UNSPECIFIED, type);
|
||||
|
|
|
|||
|
|
@ -2351,6 +2351,10 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
|||
txq_write_ptr = txq->write_ptr;
|
||||
spin_unlock(&txq->lock);
|
||||
|
||||
/* There is nothing to do if we are flushing an empty queue */
|
||||
if (is_flush && txq_write_ptr == txq_read_ptr)
|
||||
goto out;
|
||||
|
||||
read_ptr = iwl_txq_get_cmd_index(txq, txq_read_ptr);
|
||||
|
||||
if (!test_bit(txq_id, trans_pcie->txqs.queue_used)) {
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ static int p54spi_probe(struct spi_device *spi)
|
|||
gpio_direction_input(p54spi_gpio_irq);
|
||||
|
||||
ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
|
||||
p54spi_interrupt, 0, "p54spi",
|
||||
p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
|
||||
priv->spi);
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "request_irq() failed");
|
||||
|
|
@ -633,8 +633,6 @@ static int p54spi_probe(struct spi_device *spi)
|
|||
|
||||
irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
|
||||
|
||||
disable_irq(gpio_to_irq(p54spi_gpio_irq));
|
||||
|
||||
INIT_WORK(&priv->work, p54spi_work);
|
||||
init_completion(&priv->fw_comp);
|
||||
INIT_LIST_HEAD(&priv->tx_pending);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ config LIBERTAS
|
|||
tristate "Marvell 8xxx Libertas WLAN driver support"
|
||||
depends on USB || MMC || SPI
|
||||
depends on CFG80211
|
||||
select LIB80211
|
||||
select FW_LOADER
|
||||
help
|
||||
A library for Marvell Libertas 8xxx devices.
|
||||
|
|
|
|||
|
|
@ -486,6 +486,7 @@ static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t ie_len)
|
|||
*/
|
||||
|
||||
static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
|
||||
#include <net/iw_handler.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "host.h"
|
||||
#include "dev.h"
|
||||
|
|
|
|||
|
|
@ -938,8 +938,10 @@ void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter)
|
|||
assoc_resp.links[0].bss = priv->req_bss;
|
||||
assoc_resp.buf = priv->assoc_rsp_buf;
|
||||
assoc_resp.len = priv->assoc_rsp_size;
|
||||
wiphy_lock(priv->wdev.wiphy);
|
||||
cfg80211_rx_assoc_resp(priv->netdev,
|
||||
&assoc_resp);
|
||||
wiphy_unlock(priv->wdev.wiphy);
|
||||
priv->assoc_rsp_size = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -875,7 +875,7 @@ struct mwifiex_ietypes_chanstats {
|
|||
struct mwifiex_ie_types_wildcard_ssid_params {
|
||||
struct mwifiex_ie_types_header header;
|
||||
u8 max_ssid_length;
|
||||
u8 ssid[1];
|
||||
u8 ssid[];
|
||||
} __packed;
|
||||
|
||||
#define TSF_DATA_SIZE 8
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#ifndef _MWIFIEX_IOCTL_H_
|
||||
#define _MWIFIEX_IOCTL_H_
|
||||
|
||||
#include <net/lib80211.h>
|
||||
#define NUM_WEP_KEYS 4
|
||||
|
||||
enum {
|
||||
MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
|
||||
|
|
|
|||
|
|
@ -663,7 +663,6 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
|||
bool enable_data = true;
|
||||
u16 cap_info, status_code, aid;
|
||||
const u8 *ie_ptr;
|
||||
struct ieee80211_ht_operation *assoc_resp_ht_oper;
|
||||
|
||||
if (!priv->attempted_bss_desc) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
|
|
@ -779,14 +778,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
|||
ie_ptr = cfg80211_find_ie(WLAN_EID_HT_OPERATION, assoc_rsp->ie_buffer,
|
||||
priv->assoc_rsp_size
|
||||
- sizeof(struct ieee_types_assoc_rsp));
|
||||
if (ie_ptr) {
|
||||
assoc_resp_ht_oper = (struct ieee80211_ht_operation *)(ie_ptr
|
||||
+ sizeof(struct ieee_types_header));
|
||||
priv->assoc_resp_ht_param = assoc_resp_ht_oper->ht_param;
|
||||
priv->ht_param_present = true;
|
||||
} else {
|
||||
priv->ht_param_present = false;
|
||||
}
|
||||
|
||||
priv->ht_param_present = ie_ptr ? true : false;
|
||||
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"info: ASSOC_RESP: curr_pkt_filter is %#x\n",
|
||||
|
|
|
|||
|
|
@ -1679,7 +1679,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
|
|||
}
|
||||
|
||||
ret = devm_request_irq(dev, adapter->irq_wakeup,
|
||||
mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
|
||||
mwifiex_irq_wakeup_handler,
|
||||
IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
|
||||
"wifi_wake", adapter);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
|
||||
|
|
@ -1687,7 +1688,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
|
|||
goto err_exit;
|
||||
}
|
||||
|
||||
disable_irq(adapter->irq_wakeup);
|
||||
if (device_init_wakeup(dev, true)) {
|
||||
dev_err(dev, "fail to init wakeup for mwifiex\n");
|
||||
goto err_exit;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/if_arp.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/lib80211.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/ctype.h>
|
||||
|
|
@ -574,7 +573,6 @@ struct mwifiex_private {
|
|||
u16 listen_interval;
|
||||
u16 atim_window;
|
||||
u8 adhoc_channel;
|
||||
u8 adhoc_is_link_sensed;
|
||||
u8 adhoc_state;
|
||||
struct mwifiex_802_11_security sec_info;
|
||||
struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
|
||||
|
|
@ -683,7 +681,6 @@ struct mwifiex_private {
|
|||
struct mwifiex_ds_mem_rw mem_rw;
|
||||
struct sk_buff_head bypass_txq;
|
||||
struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
|
||||
u8 assoc_resp_ht_param;
|
||||
bool ht_param_present;
|
||||
};
|
||||
|
||||
|
|
@ -802,7 +799,6 @@ struct mwifiex_auto_tdls_peer {
|
|||
unsigned long rssi_jiffies;
|
||||
u8 failure_count;
|
||||
u8 do_discover;
|
||||
u8 do_setup;
|
||||
};
|
||||
|
||||
#define MWIFIEX_TYPE_AGGR_DATA_V2 11
|
||||
|
|
|
|||
|
|
@ -177,17 +177,14 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
|
|||
priv->is_data_rate_auto = true;
|
||||
priv->data_rate = 0;
|
||||
|
||||
priv->assoc_resp_ht_param = 0;
|
||||
priv->ht_param_present = false;
|
||||
|
||||
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
|
||||
GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data)
|
||||
mwifiex_hist_data_reset(priv);
|
||||
|
||||
if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
|
||||
if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
|
||||
priv->adhoc_state = ADHOC_IDLE;
|
||||
priv->adhoc_is_link_sensed = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Memorize the previous SSID and BSSID so
|
||||
|
|
@ -843,7 +840,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
|||
|
||||
case EVENT_ADHOC_BCN_LOST:
|
||||
mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
|
||||
priv->adhoc_is_link_sensed = false;
|
||||
mwifiex_clean_txrx(priv);
|
||||
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
|
||||
if (netif_carrier_ok(priv->netdev))
|
||||
|
|
|
|||
|
|
@ -351,8 +351,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
|||
goto done;
|
||||
}
|
||||
|
||||
priv->adhoc_is_link_sensed = false;
|
||||
|
||||
ret = mwifiex_check_network_compatibility(priv, bss_desc);
|
||||
|
||||
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
|
||||
|
|
|
|||
|
|
@ -1306,7 +1306,6 @@ int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
|
|||
peer->mac_addr,
|
||||
NL80211_TDLS_SETUP,
|
||||
0, GFP_ATOMIC);
|
||||
peer->do_setup = false;
|
||||
priv->check_tdls_tx = false;
|
||||
} else if (peer->failure_count <
|
||||
MWIFIEX_TDLS_MAX_FAIL_COUNT &&
|
||||
|
|
@ -1465,7 +1464,6 @@ void mwifiex_check_auto_tdls(struct timer_list *t)
|
|||
tdls_peer->failure_count <
|
||||
MWIFIEX_TDLS_MAX_FAIL_COUNT) {
|
||||
priv->check_tdls_tx = true;
|
||||
tdls_peer->do_setup = true;
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"check TDLS with peer=%pM\t"
|
||||
"rssi=%d\n", tdls_peer->mac_addr,
|
||||
|
|
|
|||
|
|
@ -494,7 +494,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
|
|||
}
|
||||
}
|
||||
|
||||
wiphy_lock(priv->wdev.wiphy);
|
||||
cfg80211_rx_mlme_mgmt(priv->netdev, skb->data, pkt_len);
|
||||
wiphy_unlock(priv->wdev.wiphy);
|
||||
}
|
||||
|
||||
if (priv->adapter->host_mlme_enabled &&
|
||||
|
|
|
|||
|
|
@ -1163,9 +1163,10 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
|
|||
|
||||
static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct mt7915_phy *phy = mt7915_hw_phy(hw);
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
|
||||
|
|
@ -1709,7 +1710,7 @@ const struct ieee80211_ops mt7915_ops = {
|
|||
.stop_ap = mt7915_stop_ap,
|
||||
.sta_state = mt76_sta_state,
|
||||
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
|
||||
.sta_rc_update = mt7915_sta_rc_update,
|
||||
.link_sta_rc_update = mt7915_sta_rc_update,
|
||||
.set_key = mt7915_set_key,
|
||||
.ampdu_action = mt7915_ampdu_action,
|
||||
.set_rts_threshold = mt7915_set_rts_threshold,
|
||||
|
|
|
|||
|
|
@ -1060,9 +1060,10 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
|
|||
|
||||
static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct mt7996_phy *phy = mt7996_hw_phy(hw);
|
||||
struct mt7996_dev *dev = phy->dev;
|
||||
|
||||
|
|
@ -1472,7 +1473,7 @@ const struct ieee80211_ops mt7996_ops = {
|
|||
.sta_add = mt7996_sta_add,
|
||||
.sta_remove = mt7996_sta_remove,
|
||||
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
|
||||
.sta_rc_update = mt7996_sta_rc_update,
|
||||
.link_sta_rc_update = mt7996_sta_rc_update,
|
||||
.set_key = mt7996_set_key,
|
||||
.ampdu_action = mt7996_ampdu_action,
|
||||
.set_rts_threshold = mt7996_set_rts_threshold,
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
|
|||
}
|
||||
|
||||
static int set_channel(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct wilc *wl = wiphy_priv(wiphy);
|
||||
|
|
@ -1424,7 +1425,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = set_channel(wiphy, &settings->chandef);
|
||||
ret = set_channel(wiphy, dev, &settings->chandef);
|
||||
if (ret != 0)
|
||||
netdev_err(dev, "Error in setting channel\n");
|
||||
|
||||
|
|
@ -1757,57 +1758,10 @@ void wlan_deinit_locks(struct wilc *wilc)
|
|||
cleanup_srcu_struct(&wilc->srcu);
|
||||
}
|
||||
|
||||
int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
|
||||
const struct wilc_hif_func *ops)
|
||||
{
|
||||
struct wilc *wl;
|
||||
int ret, i;
|
||||
|
||||
wl = wilc_create_wiphy(dev);
|
||||
if (!wl)
|
||||
return -EINVAL;
|
||||
|
||||
wlan_init_locks(wl);
|
||||
|
||||
ret = wilc_wlan_cfg_init(wl);
|
||||
if (ret)
|
||||
goto free_wl;
|
||||
|
||||
*wilc = wl;
|
||||
wl->io_type = io_type;
|
||||
wl->hif_func = ops;
|
||||
|
||||
for (i = 0; i < NQUEUES; i++)
|
||||
INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
|
||||
|
||||
INIT_LIST_HEAD(&wl->rxq_head.list);
|
||||
INIT_LIST_HEAD(&wl->vif_list);
|
||||
|
||||
wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
|
||||
wiphy_name(wl->wiphy));
|
||||
if (!wl->hif_workqueue) {
|
||||
ret = -ENOMEM;
|
||||
goto free_cfg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_cfg:
|
||||
wilc_wlan_cfg_deinit(wl);
|
||||
|
||||
free_wl:
|
||||
wlan_deinit_locks(wl);
|
||||
wiphy_unregister(wl->wiphy);
|
||||
wiphy_free(wl->wiphy);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
|
||||
|
||||
struct wilc *wilc_create_wiphy(struct device *dev)
|
||||
static struct wilc *wilc_create_wiphy(struct device *dev)
|
||||
{
|
||||
struct wiphy *wiphy;
|
||||
struct wilc *wl;
|
||||
int ret;
|
||||
|
||||
wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
|
||||
if (!wiphy)
|
||||
|
|
@ -1850,17 +1804,66 @@ struct wilc *wilc_create_wiphy(struct device *dev)
|
|||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT);
|
||||
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
wiphy->features |= NL80211_FEATURE_SAE;
|
||||
set_wiphy_dev(wiphy, dev);
|
||||
wl->wiphy = wiphy;
|
||||
ret = wiphy_register(wiphy);
|
||||
if (ret) {
|
||||
wiphy_free(wiphy);
|
||||
return NULL;
|
||||
}
|
||||
return wl;
|
||||
}
|
||||
|
||||
int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
|
||||
const struct wilc_hif_func *ops)
|
||||
{
|
||||
struct wilc *wl;
|
||||
int ret, i;
|
||||
|
||||
wl = wilc_create_wiphy(dev);
|
||||
if (!wl)
|
||||
return -EINVAL;
|
||||
|
||||
wlan_init_locks(wl);
|
||||
|
||||
ret = wilc_wlan_cfg_init(wl);
|
||||
if (ret)
|
||||
goto free_wl;
|
||||
|
||||
*wilc = wl;
|
||||
wl->io_type = io_type;
|
||||
wl->hif_func = ops;
|
||||
|
||||
for (i = 0; i < NQUEUES; i++)
|
||||
INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
|
||||
|
||||
INIT_LIST_HEAD(&wl->rxq_head.list);
|
||||
INIT_LIST_HEAD(&wl->vif_list);
|
||||
|
||||
wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
|
||||
wiphy_name(wl->wiphy));
|
||||
if (!wl->hif_workqueue) {
|
||||
ret = -ENOMEM;
|
||||
goto free_cfg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_cfg:
|
||||
wilc_wlan_cfg_deinit(wl);
|
||||
|
||||
free_wl:
|
||||
wlan_deinit_locks(wl);
|
||||
wiphy_free(wl->wiphy);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
|
||||
|
||||
int wilc_cfg80211_register(struct wilc *wilc)
|
||||
{
|
||||
/* WPA3/SAE supported only on WILC1000 */
|
||||
if (is_wilc1000(wilc->chipid))
|
||||
wilc->wiphy->features |= NL80211_FEATURE_SAE;
|
||||
|
||||
return wiphy_register(wilc->wiphy);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_cfg80211_register);
|
||||
|
||||
int wilc_init_host_int(struct net_device *net)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
|
||||
const struct wilc_hif_func *ops);
|
||||
struct wilc *wilc_create_wiphy(struct device *dev);
|
||||
int wilc_cfg80211_register(struct wilc *wilc);
|
||||
void wilc_deinit_host_int(struct net_device *net);
|
||||
int wilc_init_host_int(struct net_device *net);
|
||||
void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@
|
|||
#define __WILC1000_FW(api) WILC1000_FW_PREFIX #api ".bin"
|
||||
#define WILC1000_FW(api) __WILC1000_FW(api)
|
||||
|
||||
#define WILC3000_API_VER 1
|
||||
|
||||
#define WILC3000_FW_PREFIX "atmel/wilc3000_wifi_firmware-"
|
||||
#define __WILC3000_FW(api) WILC3000_FW_PREFIX #api ".bin"
|
||||
#define WILC3000_FW(api) __WILC3000_FW(api)
|
||||
|
||||
static irqreturn_t isr_uh_routine(int irq, void *user_data)
|
||||
{
|
||||
struct wilc *wilc = user_data;
|
||||
|
|
@ -195,20 +201,24 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
|
|||
{
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc *wilc = vif->wilc;
|
||||
int chip_id;
|
||||
const struct firmware *wilc_fw;
|
||||
char *firmware;
|
||||
int ret;
|
||||
|
||||
chip_id = wilc_get_chipid(wilc, false);
|
||||
if (is_wilc1000(wilc->chipid))
|
||||
firmware = WILC1000_FW(WILC1000_API_VER);
|
||||
else if (is_wilc3000(wilc->chipid))
|
||||
firmware = WILC3000_FW(WILC3000_API_VER);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id,
|
||||
WILC1000_FW(WILC1000_API_VER));
|
||||
netdev_info(dev, "WILC%d loading firmware [%s]\n",
|
||||
is_wilc1000(wilc->chipid) ? 1000 : 3000,
|
||||
firmware);
|
||||
|
||||
ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER),
|
||||
wilc->dev);
|
||||
ret = request_firmware(&wilc_fw, firmware, wilc->dev);
|
||||
if (ret != 0) {
|
||||
netdev_err(dev, "%s - firmware not available\n",
|
||||
WILC1000_FW(WILC1000_API_VER));
|
||||
netdev_err(dev, "%s - firmware not available\n", firmware);
|
||||
return -EINVAL;
|
||||
}
|
||||
wilc->firmware = wilc_fw;
|
||||
|
|
@ -233,7 +243,7 @@ static int wilc_start_firmware(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wilc1000_firmware_download(struct net_device *dev)
|
||||
static int wilc_firmware_download(struct net_device *dev)
|
||||
{
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc *wilc = vif->wilc;
|
||||
|
|
@ -528,7 +538,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
|
|||
if (ret)
|
||||
goto fail_irq_enable;
|
||||
|
||||
ret = wilc1000_firmware_download(dev);
|
||||
ret = wilc_firmware_download(dev);
|
||||
if (ret)
|
||||
goto fail_irq_enable;
|
||||
|
||||
|
|
@ -608,6 +618,9 @@ static int wilc_mac_open(struct net_device *ndev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
|
||||
vif->idx);
|
||||
|
||||
netdev_dbg(ndev, "Mac address: %pM\n", ndev->dev_addr);
|
||||
ret = wilc_set_mac_address(vif, ndev->dev_addr);
|
||||
if (ret) {
|
||||
|
|
@ -618,9 +631,6 @@ static int wilc_mac_open(struct net_device *ndev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype,
|
||||
vif->idx);
|
||||
|
||||
mgmt_regs.interface_stypes = vif->mgmt_reg_stypes;
|
||||
/* so we detect a change */
|
||||
vif->mgmt_reg_stypes = 0;
|
||||
|
|
@ -1014,3 +1024,4 @@ EXPORT_SYMBOL_GPL(wilc_netdev_ifc_init);
|
|||
MODULE_DESCRIPTION("Atmel WILC1000 core wireless driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER));
|
||||
MODULE_FIRMWARE(WILC3000_FW(WILC3000_API_VER));
|
||||
|
|
|
|||
|
|
@ -182,6 +182,14 @@ static int wilc_sdio_probe(struct sdio_func *func,
|
|||
|
||||
wilc_sdio_init(wilc, false);
|
||||
|
||||
ret = wilc_get_chipid(wilc);
|
||||
if (ret)
|
||||
goto dispose_irq;
|
||||
|
||||
ret = wilc_cfg80211_register(wilc);
|
||||
if (ret)
|
||||
goto dispose_irq;
|
||||
|
||||
ret = wilc_load_mac_from_nv(wilc);
|
||||
if (ret) {
|
||||
pr_err("Can not retrieve MAC address from chip\n");
|
||||
|
|
@ -667,7 +675,6 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
|
|||
struct wilc_sdio *sdio_priv = wilc->bus_data;
|
||||
struct sdio_cmd52 cmd;
|
||||
int loop, ret;
|
||||
u32 chipid;
|
||||
|
||||
/**
|
||||
* function 0 csa enable
|
||||
|
|
@ -756,18 +763,6 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure can read back chip id correctly
|
||||
**/
|
||||
if (!resume) {
|
||||
ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);
|
||||
if (ret) {
|
||||
dev_err(&func->dev, "Fail cmd read chip id...\n");
|
||||
return ret;
|
||||
}
|
||||
dev_err(&func->dev, "chipid (%08x)\n", chipid);
|
||||
}
|
||||
|
||||
sdio_priv->isinit = true;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -815,13 +810,19 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
|
|||
cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
|
||||
} else {
|
||||
cmd.function = 0;
|
||||
cmd.address = WILC_SDIO_IRQ_FLAG_REG;
|
||||
cmd.address = is_wilc1000(wilc->chipid) ?
|
||||
WILC1000_SDIO_IRQ_FLAG_REG :
|
||||
WILC3000_SDIO_IRQ_FLAG_REG;
|
||||
}
|
||||
cmd.raw = 0;
|
||||
cmd.read_write = 0;
|
||||
cmd.data = 0;
|
||||
wilc_sdio_cmd52(wilc, &cmd);
|
||||
irq_flags = cmd.data;
|
||||
|
||||
if (sdio_priv->irq_gpio)
|
||||
irq_flags &= is_wilc1000(wilc->chipid) ? 0x1f : 0x0f;
|
||||
|
||||
tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
|
||||
|
||||
if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
|
||||
|
|
@ -843,22 +844,56 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
|
|||
if (sdio_priv->irq_gpio)
|
||||
reg = val & (BIT(MAX_NUM_INT) - 1);
|
||||
|
||||
/* select VMM table 0 */
|
||||
if (val & SEL_VMM_TBL0)
|
||||
reg |= BIT(5);
|
||||
/* select VMM table 1 */
|
||||
if (val & SEL_VMM_TBL1)
|
||||
reg |= BIT(6);
|
||||
/* enable VMM */
|
||||
if (val & EN_VMM)
|
||||
reg |= BIT(7);
|
||||
if (is_wilc1000(wilc->chipid)) {
|
||||
/* select VMM table 0 */
|
||||
if (val & SEL_VMM_TBL0)
|
||||
reg |= BIT(5);
|
||||
/* select VMM table 1 */
|
||||
if (val & SEL_VMM_TBL1)
|
||||
reg |= BIT(6);
|
||||
/* enable VMM */
|
||||
if (val & EN_VMM)
|
||||
reg |= BIT(7);
|
||||
} else {
|
||||
if (sdio_priv->irq_gpio && reg) {
|
||||
struct sdio_cmd52 cmd;
|
||||
|
||||
cmd.read_write = 1;
|
||||
cmd.function = 0;
|
||||
cmd.raw = 0;
|
||||
cmd.address = WILC3000_SDIO_IRQ_FLAG_REG;
|
||||
cmd.data = reg;
|
||||
|
||||
ret = wilc_sdio_cmd52(wilc, &cmd);
|
||||
if (ret) {
|
||||
dev_err(&func->dev,
|
||||
"Failed cmd52, set 0xfe data (%d) ...\n",
|
||||
__LINE__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
reg = 0;
|
||||
/* select VMM table 0 */
|
||||
if (val & SEL_VMM_TBL0)
|
||||
reg |= BIT(0);
|
||||
/* select VMM table 1 */
|
||||
if (val & SEL_VMM_TBL1)
|
||||
reg |= BIT(1);
|
||||
/* enable VMM */
|
||||
if (val & EN_VMM)
|
||||
reg |= BIT(2);
|
||||
}
|
||||
|
||||
if (reg) {
|
||||
struct sdio_cmd52 cmd;
|
||||
|
||||
cmd.read_write = 1;
|
||||
cmd.function = 0;
|
||||
cmd.raw = 0;
|
||||
cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
|
||||
cmd.address = is_wilc1000(wilc->chipid) ?
|
||||
WILC1000_SDIO_IRQ_CLEAR_FLAG_REG :
|
||||
WILC3000_SDIO_VMM_TBL_CTRL_REG;
|
||||
cmd.data = reg;
|
||||
|
||||
ret = wilc_sdio_cmd52(wilc, &cmd);
|
||||
|
|
@ -979,17 +1014,15 @@ static int wilc_sdio_suspend(struct device *dev)
|
|||
if (!IS_ERR(wilc->rtc_clk))
|
||||
clk_disable_unprepare(wilc->rtc_clk);
|
||||
|
||||
host_sleep_notify(wilc);
|
||||
|
||||
wilc_sdio_disable_interrupt(wilc);
|
||||
|
||||
ret = wilc_sdio_reset(wilc);
|
||||
ret = host_sleep_notify(wilc);
|
||||
if (ret) {
|
||||
dev_err(&func->dev, "Fail reset sdio\n");
|
||||
clk_prepare_enable(wilc->rtc_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
wilc_sdio_disable_interrupt(wilc);
|
||||
|
||||
return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
|
||||
}
|
||||
|
||||
static int wilc_sdio_resume(struct device *dev)
|
||||
|
|
@ -1008,9 +1041,7 @@ static int wilc_sdio_resume(struct device *dev)
|
|||
wilc_sdio_init(wilc, true);
|
||||
wilc_sdio_enable_interrupt(wilc);
|
||||
|
||||
host_wakeup_notify(wilc);
|
||||
|
||||
return 0;
|
||||
return host_wakeup_notify(wilc);
|
||||
}
|
||||
|
||||
static const struct of_device_id wilc_of_match[] = {
|
||||
|
|
|
|||
|
|
@ -245,7 +245,11 @@ static int wilc_bus_probe(struct spi_device *spi)
|
|||
if (ret)
|
||||
goto power_down;
|
||||
|
||||
ret = wilc_validate_chipid(wilc);
|
||||
ret = wilc_get_chipid(wilc);
|
||||
if (ret)
|
||||
goto power_down;
|
||||
|
||||
ret = wilc_cfg80211_register(wilc);
|
||||
if (ret)
|
||||
goto power_down;
|
||||
|
||||
|
|
@ -1229,7 +1233,7 @@ static int wilc_validate_chipid(struct wilc *wilc)
|
|||
dev_err(&spi->dev, "Fail cmd read chip id...\n");
|
||||
return ret;
|
||||
}
|
||||
if (!is_wilc1000(chipid)) {
|
||||
if (!is_wilc1000(chipid) && !is_wilc3000(chipid)) {
|
||||
dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,20 +12,6 @@
|
|||
|
||||
#define WAKE_UP_TRIAL_RETRY 10000
|
||||
|
||||
static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
|
||||
{
|
||||
mutex_lock(&wilc->hif_cs);
|
||||
if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode)
|
||||
chip_wakeup(wilc);
|
||||
}
|
||||
|
||||
static inline void release_bus(struct wilc *wilc, enum bus_release release)
|
||||
{
|
||||
if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
|
||||
chip_allow_sleep(wilc);
|
||||
mutex_unlock(&wilc->hif_cs);
|
||||
}
|
||||
|
||||
static void wilc_wlan_txq_remove(struct wilc *wilc, u8 q_num,
|
||||
struct txq_entry_t *tqe)
|
||||
{
|
||||
|
|
@ -555,7 +541,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
|
|||
return rqe;
|
||||
}
|
||||
|
||||
void chip_allow_sleep(struct wilc *wilc)
|
||||
static int chip_allow_sleep_wilc1000(struct wilc *wilc)
|
||||
{
|
||||
u32 reg = 0;
|
||||
const struct wilc_hif_func *hif_func = wilc->hif_func;
|
||||
|
|
@ -584,7 +570,7 @@ void chip_allow_sleep(struct wilc *wilc)
|
|||
while (--trials) {
|
||||
ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, ®);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
if ((reg & to_host_from_fw_bit) == 0)
|
||||
break;
|
||||
}
|
||||
|
|
@ -594,28 +580,62 @@ void chip_allow_sleep(struct wilc *wilc)
|
|||
/* Clear bit 1 */
|
||||
ret = hif_func->hif_read_reg(wilc, wakeup_reg, ®);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
if (reg & wakeup_bit) {
|
||||
reg &= ~wakeup_bit;
|
||||
ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, ®);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
if (reg & from_host_to_fw_bit) {
|
||||
reg &= ~from_host_to_fw_bit;
|
||||
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(chip_allow_sleep);
|
||||
|
||||
void chip_wakeup(struct wilc *wilc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chip_allow_sleep_wilc3000(struct wilc *wilc)
|
||||
{
|
||||
u32 reg = 0;
|
||||
int ret;
|
||||
const struct wilc_hif_func *hif_func = wilc->hif_func;
|
||||
|
||||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
ret = hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
|
||||
reg & ~WILC_SDIO_WAKEUP_BIT);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = hif_func->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = hif_func->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
|
||||
reg & ~WILC_SPI_WAKEUP_BIT);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chip_allow_sleep(struct wilc *wilc)
|
||||
{
|
||||
if (is_wilc1000(wilc->chipid))
|
||||
return chip_allow_sleep_wilc1000(wilc);
|
||||
else
|
||||
return chip_allow_sleep_wilc3000(wilc);
|
||||
}
|
||||
|
||||
static int chip_wakeup_wilc1000(struct wilc *wilc)
|
||||
{
|
||||
u32 ret = 0;
|
||||
u32 clk_status_val = 0, trials = 0;
|
||||
|
|
@ -627,15 +647,15 @@ void chip_wakeup(struct wilc *wilc)
|
|||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
wakeup_reg = WILC_SDIO_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SDIO_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
|
||||
clk_status_reg = WILC1000_SDIO_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC1000_SDIO_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
|
||||
} else {
|
||||
wakeup_reg = WILC_SPI_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SPI_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SPI_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
|
||||
clk_status_reg = WILC1000_SPI_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC1000_SPI_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
|
||||
}
|
||||
|
|
@ -644,20 +664,20 @@ void chip_wakeup(struct wilc *wilc)
|
|||
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
|
||||
from_host_to_fw_bit);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
/* Set wake-up bit */
|
||||
ret = hif_func->hif_write_reg(wilc, wakeup_reg,
|
||||
wakeup_bit);
|
||||
if (ret)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
while (trials < WAKE_UP_TRIAL_RETRY) {
|
||||
ret = hif_func->hif_read_reg(wilc, clk_status_reg,
|
||||
&clk_status_val);
|
||||
if (ret) {
|
||||
pr_err("Bus error %d %x\n", ret, clk_status_val);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (clk_status_val & clk_status_bit)
|
||||
break;
|
||||
|
|
@ -666,29 +686,135 @@ void chip_wakeup(struct wilc *wilc)
|
|||
}
|
||||
if (trials >= WAKE_UP_TRIAL_RETRY) {
|
||||
pr_err("Failed to wake-up the chip\n");
|
||||
return;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/* Sometimes spi fail to read clock regs after reading
|
||||
* writing clockless registers
|
||||
*/
|
||||
if (wilc->io_type == WILC_HIF_SPI)
|
||||
wilc->hif_func->hif_reset(wilc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(chip_wakeup);
|
||||
|
||||
void host_wakeup_notify(struct wilc *wilc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chip_wakeup_wilc3000(struct wilc *wilc)
|
||||
{
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
u32 wakeup_reg_val, clk_status_reg_val, trials = 0;
|
||||
u32 wakeup_reg, wakeup_bit;
|
||||
u32 clk_status_reg, clk_status_bit;
|
||||
int wake_seq_trials = 5;
|
||||
const struct wilc_hif_func *hif_func = wilc->hif_func;
|
||||
|
||||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
wakeup_reg = WILC_SDIO_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SDIO_WAKEUP_BIT;
|
||||
clk_status_reg = WILC3000_SDIO_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC3000_SDIO_CLK_STATUS_BIT;
|
||||
} else {
|
||||
wakeup_reg = WILC_SPI_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SPI_WAKEUP_BIT;
|
||||
clk_status_reg = WILC3000_SPI_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC3000_SPI_CLK_STATUS_BIT;
|
||||
}
|
||||
|
||||
hif_func->hif_read_reg(wilc, wakeup_reg, &wakeup_reg_val);
|
||||
do {
|
||||
hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val |
|
||||
wakeup_bit);
|
||||
/* Check the clock status */
|
||||
hif_func->hif_read_reg(wilc, clk_status_reg,
|
||||
&clk_status_reg_val);
|
||||
|
||||
/* In case of clocks off, wait 1ms, and check it again.
|
||||
* if still off, wait for another 1ms, for a total wait of 3ms.
|
||||
* If still off, redo the wake up sequence
|
||||
*/
|
||||
while ((clk_status_reg_val & clk_status_bit) == 0 &&
|
||||
(++trials % 4) != 0) {
|
||||
/* Wait for the chip to stabilize*/
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
/* Make sure chip is awake. This is an extra step that
|
||||
* can be removed later to avoid the bus access
|
||||
* overhead
|
||||
*/
|
||||
hif_func->hif_read_reg(wilc, clk_status_reg,
|
||||
&clk_status_reg_val);
|
||||
}
|
||||
/* in case of failure, Reset the wakeup bit to introduce a new
|
||||
* edge on the next loop
|
||||
*/
|
||||
if ((clk_status_reg_val & clk_status_bit) == 0) {
|
||||
hif_func->hif_write_reg(wilc, wakeup_reg,
|
||||
wakeup_reg_val & (~wakeup_bit));
|
||||
/* added wait before wakeup sequence retry */
|
||||
usleep_range(200, 300);
|
||||
}
|
||||
} while ((clk_status_reg_val & clk_status_bit) == 0 && wake_seq_trials-- > 0);
|
||||
if (!wake_seq_trials)
|
||||
dev_err(wilc->dev, "clocks still OFF. Wake up failed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chip_wakeup(struct wilc *wilc)
|
||||
{
|
||||
if (is_wilc1000(wilc->chipid))
|
||||
return chip_wakeup_wilc1000(wilc);
|
||||
else
|
||||
return chip_wakeup_wilc3000(wilc);
|
||||
}
|
||||
|
||||
static inline int acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&wilc->hif_cs);
|
||||
if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode) {
|
||||
ret = chip_wakeup(wilc);
|
||||
if (ret)
|
||||
mutex_unlock(&wilc->hif_cs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int release_bus(struct wilc *wilc, enum bus_release release)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
|
||||
ret = chip_allow_sleep(wilc);
|
||||
mutex_unlock(&wilc->hif_cs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int host_wakeup_notify(struct wilc *wilc)
|
||||
{
|
||||
int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
|
||||
WILC1000_CORTUS_INTERRUPT_2 :
|
||||
WILC3000_CORTUS_INTERRUPT_2, 1);
|
||||
return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host_wakeup_notify);
|
||||
|
||||
void host_sleep_notify(struct wilc *wilc)
|
||||
int host_sleep_notify(struct wilc *wilc)
|
||||
{
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
|
||||
WILC1000_CORTUS_INTERRUPT_1 :
|
||||
WILC3000_CORTUS_INTERRUPT_1, 1);
|
||||
return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host_sleep_notify);
|
||||
|
||||
|
|
@ -715,6 +841,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
int srcu_idx;
|
||||
u8 *txb = wilc->tx_buffer;
|
||||
struct wilc_vif *vif;
|
||||
int rv;
|
||||
|
||||
if (wilc->quit)
|
||||
goto out_update_cnt;
|
||||
|
|
@ -785,7 +912,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
goto out_unlock;
|
||||
vmm_table[i] = 0x0;
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
counter = 0;
|
||||
func = wilc->hif_func;
|
||||
do {
|
||||
|
|
@ -818,19 +948,45 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
if (ret)
|
||||
break;
|
||||
|
||||
ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
do {
|
||||
ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
|
||||
if (is_wilc1000(wilc->chipid)) {
|
||||
ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
|
||||
if (ret)
|
||||
break;
|
||||
if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
|
||||
entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
|
||||
|
||||
do {
|
||||
ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
|
||||
if (ret)
|
||||
break;
|
||||
if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
|
||||
entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
|
||||
break;
|
||||
}
|
||||
} while (--timeout);
|
||||
} else {
|
||||
ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
} while (--timeout);
|
||||
|
||||
/* interrupt firmware */
|
||||
ret = func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, 1);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
do {
|
||||
ret = func->hif_read_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, ®);
|
||||
if (ret)
|
||||
break;
|
||||
if (reg == 0) {
|
||||
/* Get the entries */
|
||||
ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
|
||||
break;
|
||||
}
|
||||
} while (--timeout);
|
||||
}
|
||||
if (timeout <= 0) {
|
||||
ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
|
||||
break;
|
||||
|
|
@ -860,7 +1016,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
goto out_release_bus;
|
||||
}
|
||||
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
offset = 0;
|
||||
i = 0;
|
||||
|
|
@ -922,7 +1080,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
for (i = 0; i < NQUEUES; i++)
|
||||
wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
|
||||
if (ret)
|
||||
|
|
@ -931,7 +1091,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
|
|||
ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
|
||||
|
||||
out_release_bus:
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
if (!ret && rv)
|
||||
ret = rv;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&wilc->txq_add_to_head_cs);
|
||||
|
|
@ -1060,8 +1222,14 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
|
|||
void wilc_handle_isr(struct wilc *wilc)
|
||||
{
|
||||
u32 int_status;
|
||||
int ret;
|
||||
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(wilc->dev, "Cannot acquire bus\n");
|
||||
return;
|
||||
}
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
wilc->hif_func->hif_read_int(wilc, &int_status);
|
||||
|
||||
if (int_status & DATA_INT_EXT)
|
||||
|
|
@ -1070,7 +1238,9 @@ void wilc_handle_isr(struct wilc *wilc)
|
|||
if (!(int_status & (ALL_INT_EXT)))
|
||||
wilc_unknown_isr_ext(wilc);
|
||||
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
if (ret)
|
||||
dev_err_ratelimited(wilc->dev, "Cannot release bus\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_handle_isr);
|
||||
|
||||
|
|
@ -1082,6 +1252,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
u8 *dma_buffer;
|
||||
int ret = 0;
|
||||
u32 reg = 0;
|
||||
int rv;
|
||||
|
||||
blksz = BIT(12);
|
||||
|
||||
|
|
@ -1092,7 +1263,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
offset = 0;
|
||||
pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
|
||||
reg &= ~BIT(10);
|
||||
|
|
@ -1101,11 +1274,17 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
if (reg & BIT(10))
|
||||
pr_err("%s: Failed to reset\n", __func__);
|
||||
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
ret = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
do {
|
||||
addr = get_unaligned_le32(&buffer[offset]);
|
||||
size = get_unaligned_le32(&buffer[offset + 4]);
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
offset += 8;
|
||||
while (((int)size) && (offset < buffer_size)) {
|
||||
if (size <= blksz)
|
||||
|
|
@ -1123,7 +1302,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
offset += size2;
|
||||
size -= size2;
|
||||
}
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
if (!ret && rv)
|
||||
ret = rv;
|
||||
|
||||
if (ret) {
|
||||
pr_err("%s Bus error\n", __func__);
|
||||
|
|
@ -1142,7 +1323,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
|||
int wilc_wlan_start(struct wilc *wilc)
|
||||
{
|
||||
u32 reg = 0;
|
||||
int ret;
|
||||
int ret, rv;
|
||||
u32 chipid;
|
||||
|
||||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
|
|
@ -1151,7 +1332,10 @@ int wilc_wlan_start(struct wilc *wilc)
|
|||
} else if (wilc->io_type == WILC_HIF_SPI) {
|
||||
reg = 1;
|
||||
}
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
|
||||
if (ret)
|
||||
goto release;
|
||||
|
|
@ -1160,6 +1344,9 @@ int wilc_wlan_start(struct wilc *wilc)
|
|||
if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
|
||||
reg |= WILC_HAVE_SDIO_IRQ_GPIO;
|
||||
|
||||
if (is_wilc3000(wilc->chipid))
|
||||
reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
|
||||
|
||||
ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
|
||||
if (ret)
|
||||
goto release;
|
||||
|
|
@ -1182,16 +1369,18 @@ int wilc_wlan_start(struct wilc *wilc)
|
|||
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
|
||||
|
||||
release:
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
return ret;
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
return ret ? ret : rv;
|
||||
}
|
||||
|
||||
int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
|
||||
{
|
||||
u32 reg = 0;
|
||||
int ret;
|
||||
int ret, rv;
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wilc->hif_func->hif_read_reg(wilc, GLOBAL_MODE_CONTROL, ®);
|
||||
if (ret)
|
||||
|
|
@ -1227,9 +1416,9 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
|
|||
ret = 0;
|
||||
release:
|
||||
/* host comm is disabled - we can't issue sleep command anymore: */
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
|
||||
return ret;
|
||||
return ret ? ret : rv;
|
||||
}
|
||||
|
||||
void wilc_wlan_cleanup(struct net_device *dev)
|
||||
|
|
@ -1402,19 +1591,56 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wilc_get_chipid(struct wilc *wilc)
|
||||
{
|
||||
u32 chipid = 0;
|
||||
u32 rfrevid = 0;
|
||||
|
||||
if (wilc->chipid == 0) {
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC3000_CHIP_ID, &chipid);
|
||||
if (!is_wilc3000(chipid)) {
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
|
||||
&rfrevid);
|
||||
|
||||
if (!is_wilc1000(chipid)) {
|
||||
wilc->chipid = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
|
||||
if (rfrevid != 0x1)
|
||||
chipid = WILC_1000_BASE_ID_2A_REV1;
|
||||
} else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
|
||||
if (rfrevid == 0x4)
|
||||
chipid = WILC_1000_BASE_ID_2B_REV1;
|
||||
else if (rfrevid != 0x3)
|
||||
chipid = WILC_1000_BASE_ID_2B_REV2;
|
||||
}
|
||||
}
|
||||
|
||||
wilc->chipid = chipid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_get_chipid);
|
||||
|
||||
static int init_chip(struct net_device *dev)
|
||||
{
|
||||
u32 chipid;
|
||||
u32 reg;
|
||||
int ret = 0;
|
||||
int ret, rv;
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc *wilc = vif->wilc;
|
||||
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
chipid = wilc_get_chipid(wilc, true);
|
||||
ret = wilc_get_chipid(wilc);
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
if ((chipid & 0xfff) != 0xa0) {
|
||||
if ((wilc->chipid & 0xfff) != 0xa0) {
|
||||
ret = wilc->hif_func->hif_read_reg(wilc,
|
||||
WILC_CORTUS_RESET_MUX_SEL,
|
||||
®);
|
||||
|
|
@ -1439,46 +1665,35 @@ static int init_chip(struct net_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
release:
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 wilc_get_chipid(struct wilc *wilc, bool update)
|
||||
{
|
||||
u32 chipid = 0;
|
||||
u32 rfrevid = 0;
|
||||
|
||||
if (wilc->chipid == 0 || update) {
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
|
||||
wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
|
||||
&rfrevid);
|
||||
if (!is_wilc1000(chipid)) {
|
||||
wilc->chipid = 0;
|
||||
return wilc->chipid;
|
||||
}
|
||||
if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
|
||||
if (rfrevid != 0x1)
|
||||
chipid = WILC_1000_BASE_ID_2A_REV1;
|
||||
} else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
|
||||
if (rfrevid == 0x4)
|
||||
chipid = WILC_1000_BASE_ID_2B_REV1;
|
||||
else if (rfrevid != 0x3)
|
||||
chipid = WILC_1000_BASE_ID_2B_REV2;
|
||||
if (is_wilc3000(wilc->chipid)) {
|
||||
ret = wilc->hif_func->hif_read_reg(wilc, WILC3000_BOOTROM_STATUS, ®);
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to read WILC3000 BootROM status register\n");
|
||||
goto release;
|
||||
}
|
||||
|
||||
wilc->chipid = chipid;
|
||||
ret = wilc->hif_func->hif_write_reg(wilc, WILC3000_CORTUS_BOOT_REGISTER_2,
|
||||
WILC_CORTUS_BOOT_FROM_IRAM);
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to write WILC3000 Boot register\n");
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
return wilc->chipid;
|
||||
|
||||
release:
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
|
||||
return ret ? ret : rv;
|
||||
}
|
||||
|
||||
int wilc_load_mac_from_nv(struct wilc *wl)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int ret, rv;
|
||||
unsigned int i;
|
||||
|
||||
acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
ret = acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < WILC_NVMEM_MAX_NUM_BANK; i++) {
|
||||
int bank_offset = get_bank_offset_from_bank_index(i);
|
||||
|
|
@ -1517,14 +1732,14 @@ int wilc_load_mac_from_nv(struct wilc *wl)
|
|||
break;
|
||||
}
|
||||
|
||||
release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
return ret;
|
||||
rv = release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
|
||||
return ret ? ret : rv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wilc_load_mac_from_nv);
|
||||
|
||||
int wilc_wlan_init(struct net_device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0, rv;
|
||||
struct wilc_vif *vif = netdev_priv(dev);
|
||||
struct wilc *wilc;
|
||||
|
||||
|
|
@ -1533,11 +1748,26 @@ int wilc_wlan_init(struct net_device *dev)
|
|||
wilc->quit = 0;
|
||||
|
||||
if (!wilc->hif_func->hif_is_init(wilc)) {
|
||||
acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
|
||||
ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wilc->hif_func->hif_init(wilc, false);
|
||||
release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
if (!ret)
|
||||
ret = wilc_get_chipid(wilc);
|
||||
rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
|
||||
if (!ret && rv)
|
||||
ret = rv;
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (!is_wilc1000(wilc->chipid) && !is_wilc3000(wilc->chipid)) {
|
||||
netdev_err(dev, "Unsupported chipid: %x\n", wilc->chipid);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
netdev_dbg(dev, "chipid (%08x)\n", wilc->chipid);
|
||||
}
|
||||
|
||||
if (!wilc->vmm_table)
|
||||
|
|
|
|||
|
|
@ -96,8 +96,14 @@
|
|||
#define WILC_SPI_WAKEUP_REG 0x1
|
||||
#define WILC_SPI_WAKEUP_BIT BIT(1)
|
||||
|
||||
#define WILC_SPI_CLK_STATUS_REG 0x0f
|
||||
#define WILC_SPI_CLK_STATUS_BIT BIT(2)
|
||||
/* WILC1000 specific */
|
||||
#define WILC1000_SPI_CLK_STATUS_REG 0x0f
|
||||
#define WILC1000_SPI_CLK_STATUS_BIT BIT(2)
|
||||
|
||||
/* WILC3000 specific */
|
||||
#define WILC3000_SPI_CLK_STATUS_REG 0x13
|
||||
#define WILC3000_SPI_CLK_STATUS_BIT BIT(2)
|
||||
|
||||
#define WILC_SPI_HOST_TO_FW_REG 0x0b
|
||||
#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
|
||||
|
||||
|
|
@ -123,14 +129,24 @@
|
|||
#define WILC_SDIO_WAKEUP_REG 0xf0
|
||||
#define WILC_SDIO_WAKEUP_BIT BIT(0)
|
||||
|
||||
#define WILC_SDIO_CLK_STATUS_REG 0xf1
|
||||
#define WILC_SDIO_CLK_STATUS_BIT BIT(0)
|
||||
/* WILC1000 */
|
||||
#define WILC1000_SDIO_CLK_STATUS_REG 0xf1
|
||||
#define WILC1000_SDIO_CLK_STATUS_BIT BIT(0)
|
||||
|
||||
#define WILC1000_SDIO_IRQ_FLAG_REG 0xf7
|
||||
#define WILC1000_SDIO_IRQ_CLEAR_FLAG_REG 0xf8
|
||||
|
||||
/* WILC3000 specific */
|
||||
#define WILC3000_SDIO_CLK_STATUS_REG 0xf0 /* clk & wakeup are on same reg */
|
||||
#define WILC3000_SDIO_CLK_STATUS_BIT BIT(4)
|
||||
|
||||
#define WILC3000_SDIO_VMM_TBL_CTRL_REG 0xf1
|
||||
#define WILC3000_SDIO_IRQ_FLAG_REG 0xfe
|
||||
|
||||
/* Common vendor specific CCCR register */
|
||||
#define WILC_SDIO_INTERRUPT_DATA_SZ_REG 0xf2 /* Read size (2 bytes) */
|
||||
|
||||
#define WILC_SDIO_VMM_TBL_CTRL_REG 0xf6
|
||||
#define WILC_SDIO_IRQ_FLAG_REG 0xf7
|
||||
#define WILC_SDIO_IRQ_CLEAR_FLAG_REG 0xf8
|
||||
|
||||
#define WILC_SDIO_HOST_TO_FW_REG 0xfa
|
||||
#define WILC_SDIO_HOST_TO_FW_BIT BIT(0)
|
||||
|
|
@ -172,8 +188,11 @@
|
|||
#define WILC_HAVE_USE_IRQ_AS_HOST_WAKE BIT(8)
|
||||
|
||||
#define WILC_CORTUS_INTERRUPT_BASE 0x10A8
|
||||
#define WILC_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x4)
|
||||
#define WILC_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x8)
|
||||
#define WILC1000_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x4)
|
||||
#define WILC3000_CORTUS_INTERRUPT_1 (WILC_CORTUS_INTERRUPT_BASE + 0x14)
|
||||
|
||||
#define WILC1000_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x8)
|
||||
#define WILC3000_CORTUS_INTERRUPT_2 (WILC_CORTUS_INTERRUPT_BASE + 0x18)
|
||||
|
||||
/* tx control register 1 to 4 for RX */
|
||||
#define WILC_REG_4_TO_1_RX 0x1e1c
|
||||
|
|
@ -183,6 +202,9 @@
|
|||
|
||||
#define WILC_CORTUS_RESET_MUX_SEL 0x1118
|
||||
#define WILC_CORTUS_BOOT_REGISTER 0xc0000
|
||||
#define WILC3000_BOOTROM_STATUS 0x207ac
|
||||
#define WILC3000_CORTUS_BOOT_REGISTER_2 0x4f0000
|
||||
#define WILC3000_CHIP_ID 0x3b0000
|
||||
|
||||
#define WILC_CORTUS_BOOT_FROM_IRAM 0x71
|
||||
|
||||
|
|
@ -195,6 +217,8 @@
|
|||
#define WILC_1000_BASE_ID_2B_REV1 (WILC_1000_BASE_ID_2B + 1)
|
||||
#define WILC_1000_BASE_ID_2B_REV2 (WILC_1000_BASE_ID_2B + 2)
|
||||
|
||||
#define WILC_3000_BASE_ID 0x300000
|
||||
|
||||
#define WILC_CHIP_REV_FIELD GENMASK(11, 0)
|
||||
|
||||
/********************************************
|
||||
|
|
@ -413,6 +437,11 @@ static inline bool is_wilc1000(u32 id)
|
|||
return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
|
||||
}
|
||||
|
||||
static inline bool is_wilc3000(u32 id)
|
||||
{
|
||||
return (id & (~WILC_CHIP_REV_FIELD)) == WILC_3000_BASE_ID;
|
||||
}
|
||||
|
||||
int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
|
||||
u32 buffer_size);
|
||||
int wilc_wlan_start(struct wilc *wilc);
|
||||
|
|
@ -436,13 +465,11 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
|
|||
|
||||
void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
|
||||
bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size);
|
||||
void host_wakeup_notify(struct wilc *wilc);
|
||||
void host_sleep_notify(struct wilc *wilc);
|
||||
void chip_allow_sleep(struct wilc *wilc);
|
||||
void chip_wakeup(struct wilc *wilc);
|
||||
int host_wakeup_notify(struct wilc *wilc);
|
||||
int host_sleep_notify(struct wilc *wilc);
|
||||
int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
|
||||
u32 count);
|
||||
int wilc_wlan_init(struct net_device *dev);
|
||||
u32 wilc_get_chipid(struct wilc *wilc, bool update);
|
||||
int wilc_get_chipid(struct wilc *wilc);
|
||||
int wilc_load_mac_from_nv(struct wilc *wilc);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
|
|||
cmd->beacon_interval = cpu_to_le16(s->beacon_interval);
|
||||
cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid);
|
||||
cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout);
|
||||
cmd->smps_mode = s->smps_mode;
|
||||
cmd->smps_mode = NL80211_SMPS_OFF;
|
||||
cmd->p2p_ctwindow = s->p2p_ctwindow;
|
||||
cmd->p2p_opp_ps = s->p2p_opp_ps;
|
||||
cmd->pbss = s->pbss;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/if_arp.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/lib80211.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/firmware.h>
|
||||
|
|
|
|||
|
|
@ -3607,7 +3607,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
|
|||
rt2800_rfcsr_write(rt2x00dev, 52, 0x0C);
|
||||
rt2800_rfcsr_write(rt2x00dev, 54, 0xF8);
|
||||
if (rf->channel <= 50) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x06),
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x06);
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0xD3);
|
||||
} else if (rf->channel >= 52) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x04);
|
||||
|
|
|
|||
|
|
@ -5058,10 +5058,12 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
if (bss_conf->enable_beacon)
|
||||
if (bss_conf->enable_beacon) {
|
||||
rtl8xxxu_start_tx_beacon(priv);
|
||||
else
|
||||
schedule_delayed_work(&priv->update_beacon_work, 0);
|
||||
} else {
|
||||
rtl8xxxu_stop_tx_beacon(priv);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON)
|
||||
|
|
|
|||
|
|
@ -2040,31 +2040,33 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
|
|||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
|
||||
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
|
||||
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
|
||||
COUNTRY_CODE_WORLD_WIDE_13};
|
||||
static const int params[] = {
|
||||
RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
|
||||
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
|
||||
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
|
||||
COUNTRY_CODE_WORLD_WIDE_13
|
||||
};
|
||||
u8 *hwinfo;
|
||||
int i;
|
||||
bool is_toshiba_smid1 = false;
|
||||
bool is_toshiba_smid2 = false;
|
||||
bool is_samsung_smid = false;
|
||||
bool is_lenovo_smid = false;
|
||||
u16 toshiba_smid1[] = {
|
||||
static const u16 toshiba_smid1[] = {
|
||||
0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
|
||||
0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
|
||||
0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
|
||||
0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
|
||||
};
|
||||
u16 toshiba_smid2[] = {
|
||||
static const u16 toshiba_smid2[] = {
|
||||
0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
|
||||
0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
|
||||
};
|
||||
u16 samsung_smid[] = {
|
||||
static const u16 samsung_smid[] = {
|
||||
0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
|
||||
0x8193, 0x9191, 0x9192, 0x9193
|
||||
};
|
||||
u16 lenovo_smid[] = {
|
||||
static const u16 lenovo_smid[] = {
|
||||
0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
|
|||
static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
|
||||
u8 length)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
|
|||
}
|
||||
|
||||
static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
||||
const struct rtw_pwr_seq_cmd **cmd_seq)
|
||||
const struct rtw_pwr_seq_cmd * const *cmd_seq)
|
||||
{
|
||||
u8 cut_mask;
|
||||
u8 intf_mask;
|
||||
|
|
@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
|||
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
const struct rtw_pwr_seq_cmd **pwr_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_seq;
|
||||
u32 imr = 0;
|
||||
u8 rpwm;
|
||||
bool cur_pwr;
|
||||
|
|
|
|||
|
|
@ -928,8 +928,10 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
|
|||
|
||||
static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u32 changed)
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct rtw_dev *rtwdev = hw->priv;
|
||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
|
||||
|
|
@ -973,7 +975,7 @@ const struct ieee80211_ops rtw_ops = {
|
|||
.reconfig_complete = rtw_reconfig_complete,
|
||||
.hw_scan = rtw_ops_hw_scan,
|
||||
.cancel_hw_scan = rtw_ops_cancel_hw_scan,
|
||||
.sta_rc_update = rtw_ops_sta_rc_update,
|
||||
.link_sta_rc_update = rtw_ops_sta_rc_update,
|
||||
.set_sar_specs = rtw_ops_set_sar_specs,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = rtw_ops_suspend,
|
||||
|
|
|
|||
|
|
@ -848,9 +848,8 @@ struct rtw_chip_ops {
|
|||
void (*phy_set_param)(struct rtw_dev *rtwdev);
|
||||
void (*set_channel)(struct rtw_dev *rtwdev, u8 channel,
|
||||
u8 bandwidth, u8 primary_chan_idx);
|
||||
void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat);
|
||||
u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
|
||||
u32 addr, u32 mask);
|
||||
bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
|
||||
|
|
@ -1167,7 +1166,7 @@ enum rtw_fwcd_item {
|
|||
|
||||
/* hardware configuration for each IC */
|
||||
struct rtw_chip_info {
|
||||
struct rtw_chip_ops *ops;
|
||||
const struct rtw_chip_ops *ops;
|
||||
u8 id;
|
||||
|
||||
const char *fw_name;
|
||||
|
|
@ -1209,8 +1208,8 @@ struct rtw_chip_info {
|
|||
|
||||
/* init values */
|
||||
u8 sys_func_en;
|
||||
const struct rtw_pwr_seq_cmd **pwr_on_seq;
|
||||
const struct rtw_pwr_seq_cmd **pwr_off_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_on_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_off_seq;
|
||||
const struct rtw_rqpn *rqpn_table;
|
||||
const struct rtw_prioq_addrs *prioq_addrs;
|
||||
const struct rtw_page_table *page_table;
|
||||
|
|
@ -1242,7 +1241,7 @@ struct rtw_chip_info {
|
|||
u8 bfer_su_max_num;
|
||||
u8 bfer_mu_max_num;
|
||||
|
||||
struct rtw_hw_reg_offset *edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th;
|
||||
s8 l2h_th_ini_cs;
|
||||
s8 l2h_th_ini_ad;
|
||||
|
||||
|
|
|
|||
|
|
@ -1065,7 +1065,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
|
|||
dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
|
||||
/* offset from rx_desc to payload */
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
|
|||
|
||||
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
|
||||
rtw_write32_mask(rtwdev,
|
||||
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@
|
|||
#define TBTT_PROHIBIT_HOLD_TIME 0x80
|
||||
#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64
|
||||
|
||||
/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */
|
||||
#define RX_DRV_INFO_SZ_UNIT_8703B 8
|
||||
|
||||
#define TRANS_SEQ_END \
|
||||
0xFFFF, \
|
||||
RTW_PWR_CUT_ALL_MSK, \
|
||||
|
|
@ -481,14 +478,14 @@ static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {
|
|||
{TRANS_SEQ_END},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = {
|
||||
trans_pre_enable_8703b,
|
||||
trans_carddis_to_cardemu_8703b,
|
||||
trans_cardemu_to_act_8703b,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
|
||||
trans_act_to_lps_8703b,
|
||||
trans_act_to_reset_mcu_8703b,
|
||||
trans_act_to_cardemu_8703b,
|
||||
|
|
@ -1032,57 +1029,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
|||
query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = 0;
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;
|
||||
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
|
||||
pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
|
||||
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
|
||||
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
|
||||
* simply drops the packet. Maybe this should go into
|
||||
* rtw_rx_fill_rx_status()?
|
||||
*/
|
||||
if (pkt_stat->pkt_len == 0) {
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
|
||||
}
|
||||
}
|
||||
|
||||
#define ADDA_ON_VAL_8703B 0x03c00014
|
||||
|
||||
static
|
||||
|
|
@ -1941,14 +1887,14 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
|
|||
{ {0x61, 0x08, 0x03, 0x11, 0x11} },
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8703b_ops = {
|
||||
static const struct rtw_chip_ops rtw8703b_ops = {
|
||||
.mac_init = rtw8723x_mac_init,
|
||||
.dump_fw_crash = NULL,
|
||||
.shutdown = NULL,
|
||||
.read_efuse = rtw8703b_read_efuse,
|
||||
.phy_set_param = rtw8703b_phy_set_param,
|
||||
.set_channel = rtw8703b_set_channel,
|
||||
.query_rx_desc = rtw8703b_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.read_rf = rtw_phy_read_rf_sipi,
|
||||
.write_rf = rtw_phy_write_rf_reg_sipi,
|
||||
.set_tx_power_index = rtw8723x_set_tx_power_index,
|
||||
|
|
|
|||
|
|
@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = 0;
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
|
||||
u8 channel, u32 thres)
|
||||
{
|
||||
|
|
@ -1430,10 +1389,10 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
|
|||
dm_info->pwr_trk_triggered = false;
|
||||
}
|
||||
|
||||
static struct rtw_chip_ops rtw8723d_ops = {
|
||||
static const struct rtw_chip_ops rtw8723d_ops = {
|
||||
.phy_set_param = rtw8723d_phy_set_param,
|
||||
.read_efuse = rtw8723x_read_efuse,
|
||||
.query_rx_desc = rtw8723d_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8723d_set_channel,
|
||||
.mac_init = rtw8723x_mac_init,
|
||||
.shutdown = rtw8723d_shutdown,
|
||||
|
|
@ -1788,7 +1747,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = {
|
||||
trans_carddis_to_cardemu_8723d,
|
||||
trans_cardemu_to_act_8723d,
|
||||
NULL
|
||||
|
|
@ -2004,7 +1963,7 @@ static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = {
|
||||
trans_act_to_lps_8723d,
|
||||
trans_act_to_pre_carddis_8723d,
|
||||
trans_act_to_cardemu_8723d,
|
||||
|
|
|
|||
|
|
@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
|
||||
{
|
||||
|
|
@ -1254,7 +1213,7 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
|
|||
fill_txdesc_checksum_common(txdesc, 16);
|
||||
}
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
||||
{0x0086,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_SDIO_MSK,
|
||||
|
|
@ -1292,7 +1251,7 @@ static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
||||
{0x0020,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
|
||||
|
|
@ -1396,7 +1355,7 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
||||
{0x0093,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_ALL_MSK,
|
||||
|
|
@ -1454,7 +1413,7 @@ static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
||||
{0x0007,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
|
||||
|
|
@ -1567,13 +1526,13 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = {
|
||||
trans_carddis_to_cardemu_8821c,
|
||||
trans_cardemu_to_act_8821c,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = {
|
||||
trans_act_to_cardemu_8821c,
|
||||
trans_cardemu_to_carddis_8821c,
|
||||
NULL
|
||||
|
|
@ -1629,7 +1588,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
|
|||
[6] = RTW_DEF_RFE(8821c, 0, 0),
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg rtw8821c_dig[] = {
|
||||
static const struct rtw_hw_reg rtw8821c_dig[] = {
|
||||
[0] = { .addr = 0xc50, .mask = 0x7f },
|
||||
};
|
||||
|
||||
|
|
@ -1639,7 +1598,7 @@ static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
|
|||
.rdata = LTECOEX_READ_DATA,
|
||||
};
|
||||
|
||||
static struct rtw_page_table page_table_8821c[] = {
|
||||
static const struct rtw_page_table page_table_8821c[] = {
|
||||
/* not sure what [0] stands for */
|
||||
{16, 16, 16, 14, 1},
|
||||
{16, 16, 16, 14, 1},
|
||||
|
|
@ -1648,7 +1607,7 @@ static struct rtw_page_table page_table_8821c[] = {
|
|||
{16, 16, 16, 14, 1},
|
||||
};
|
||||
|
||||
static struct rtw_rqpn rqpn_table_8821c[] = {
|
||||
static const struct rtw_rqpn rqpn_table_8821c[] = {
|
||||
/* not sure what [0] stands for */
|
||||
{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
|
||||
RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
|
||||
|
|
@ -1667,7 +1626,7 @@ static struct rtw_rqpn rqpn_table_8821c[] = {
|
|||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8821c = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8821c = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
|
|
@ -1683,10 +1642,10 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = {
|
|||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8821c_ops = {
|
||||
static const struct rtw_chip_ops rtw8821c_ops = {
|
||||
.phy_set_param = rtw8821c_phy_set_param,
|
||||
.read_efuse = rtw8821c_read_efuse,
|
||||
.query_rx_desc = rtw8821c_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8821c_set_channel,
|
||||
.mac_init = rtw8821c_mac_init,
|
||||
.read_rf = rtw_phy_read_rf,
|
||||
|
|
|
|||
|
|
@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
|
||||
{
|
||||
|
|
@ -1978,13 +1937,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = {
|
||||
trans_carddis_to_cardemu_8822b,
|
||||
trans_cardemu_to_act_8822b,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = {
|
||||
trans_act_to_cardemu_8822b,
|
||||
trans_cardemu_to_carddis_8822b,
|
||||
NULL
|
||||
|
|
@ -2156,7 +2115,7 @@ static const struct rtw_rqpn rqpn_table_8822b[] = {
|
|||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8822b = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8822b = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
|
|
@ -2172,10 +2131,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = {
|
|||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8822b_ops = {
|
||||
static const struct rtw_chip_ops rtw8822b_ops = {
|
||||
.phy_set_param = rtw8822b_phy_set_param,
|
||||
.read_efuse = rtw8822b_read_efuse,
|
||||
.query_rx_desc = rtw8822b_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8822b_set_channel,
|
||||
.mac_init = rtw8822b_mac_init,
|
||||
.read_rf = rtw_phy_read_rf,
|
||||
|
|
@ -2521,7 +2480,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
|
|||
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
|
||||
static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
|
||||
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
|||
}
|
||||
}
|
||||
|
||||
static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
pkt_stat->hdr = hdr;
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck,
|
||||
u8 *tx_pwr_ref_ofdm)
|
||||
|
|
@ -4874,13 +4832,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = {
|
|||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = {
|
||||
trans_carddis_to_cardemu_8822c,
|
||||
trans_cardemu_to_act_8822c,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = {
|
||||
trans_act_to_cardemu_8822c,
|
||||
trans_cardemu_to_carddis_8822c,
|
||||
NULL
|
||||
|
|
@ -4972,7 +4930,7 @@ static const struct rtw_rqpn rqpn_table_8822c[] = {
|
|||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8822c = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8822c = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
|
|
@ -4988,10 +4946,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = {
|
|||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8822c_ops = {
|
||||
static const struct rtw_chip_ops rtw8822c_ops = {
|
||||
.phy_set_param = rtw8822c_phy_set_param,
|
||||
.read_efuse = rtw8822c_read_efuse,
|
||||
.query_rx_desc = rtw8822c_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8822c_set_channel,
|
||||
.mac_init = rtw8822c_mac_init,
|
||||
.dump_fw_crash = rtw8822c_dump_fw_crash,
|
||||
|
|
@ -5301,7 +5259,7 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
|
|||
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
|
||||
static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {
|
||||
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
|
||||
},
|
||||
|
|
|
|||
|
|
@ -187,11 +187,10 @@ void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
|||
}
|
||||
EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
|
||||
|
||||
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *phy_status)
|
||||
static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
u8 path;
|
||||
|
|
@ -242,5 +241,64 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
|||
}
|
||||
|
||||
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
|
||||
|
||||
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
|
||||
* simply drops the packet.
|
||||
*/
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) {
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_rx_fill_rx_status);
|
||||
|
||||
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
struct rtw_rx_desc *rx_desc = rx_desc8;
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 enc_type, swdec;
|
||||
void *phy_status;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN);
|
||||
pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32);
|
||||
pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR);
|
||||
pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0,
|
||||
RTW_RX_DESC_W0_DRV_INFO_SIZE);
|
||||
enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE);
|
||||
pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT);
|
||||
pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST);
|
||||
swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC);
|
||||
pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE;
|
||||
|
||||
pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID);
|
||||
|
||||
pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H);
|
||||
pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT);
|
||||
|
||||
pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE);
|
||||
|
||||
pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW);
|
||||
|
||||
pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
phy_status = rx_desc8 + desc_sz + pkt_stat->shift;
|
||||
hdr = phy_status + pkt_stat->drv_info_sz;
|
||||
pkt_stat->hdr = hdr;
|
||||
|
||||
if (pkt_stat->phy_status)
|
||||
rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_rx_query_rx_desc);
|
||||
|
|
|
|||
|
|
@ -14,42 +14,40 @@ enum rtw_rx_desc_enc {
|
|||
RX_DESC_ENC_WEP104 = 5,
|
||||
};
|
||||
|
||||
#define GET_RX_DESC_PHYST(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26))
|
||||
#define GET_RX_DESC_ICV_ERR(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15))
|
||||
#define GET_RX_DESC_CRC32(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14))
|
||||
#define GET_RX_DESC_SWDEC(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27))
|
||||
#define GET_RX_DESC_C2H(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28))
|
||||
#define GET_RX_DESC_PKT_LEN(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0))
|
||||
#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16))
|
||||
#define GET_RX_DESC_SHIFT(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24))
|
||||
#define GET_RX_DESC_ENC_TYPE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20))
|
||||
#define GET_RX_DESC_RX_RATE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0))
|
||||
#define GET_RX_DESC_MACID(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0))
|
||||
#define GET_RX_DESC_PPDU_CNT(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29))
|
||||
#define GET_RX_DESC_TSFL(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))
|
||||
#define GET_RX_DESC_BW(rxdesc) \
|
||||
(le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4)))
|
||||
struct rtw_rx_desc {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
} __packed;
|
||||
|
||||
#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0)
|
||||
#define RTW_RX_DESC_W0_CRC32 BIT(14)
|
||||
#define RTW_RX_DESC_W0_ICV_ERR BIT(15)
|
||||
#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16)
|
||||
#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20)
|
||||
#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24)
|
||||
#define RTW_RX_DESC_W0_PHYST BIT(26)
|
||||
#define RTW_RX_DESC_W0_SWDEC BIT(27)
|
||||
|
||||
#define RTW_RX_DESC_W1_MACID GENMASK(6, 0)
|
||||
|
||||
#define RTW_RX_DESC_W2_C2H BIT(28)
|
||||
#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29)
|
||||
|
||||
#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0)
|
||||
|
||||
#define RTW_RX_DESC_W4_BW GENMASK(5, 4)
|
||||
|
||||
#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0)
|
||||
|
||||
void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
struct sk_buff *skb);
|
||||
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *phy_status);
|
||||
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat);
|
||||
|
|
|
|||
|
|
@ -981,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len)
|
|||
|
||||
while (true) {
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
pkt_stat.shift;
|
||||
|
||||
|
|
@ -1297,12 +1296,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
|
|||
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
|
||||
skb_queue_purge(&rtwsdio->tx_queue[i]);
|
||||
|
||||
flush_workqueue(rtwsdio->txwq);
|
||||
destroy_workqueue(rtwsdio->txwq);
|
||||
kfree(rtwsdio->tx_handler_data);
|
||||
|
||||
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
|
||||
ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]);
|
||||
}
|
||||
|
||||
int rtw_sdio_probe(struct sdio_func *sdio_func,
|
||||
|
|
|
|||
|
|
@ -423,10 +423,11 @@ static void rtw_usb_tx_handler(struct work_struct *work)
|
|||
|
||||
static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
|
||||
{
|
||||
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
|
||||
skb_queue_purge(&rtwusb->tx_queue[i]);
|
||||
ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]);
|
||||
}
|
||||
|
||||
static void rtw_usb_write_port_complete(struct urb *urb)
|
||||
|
|
@ -570,8 +571,8 @@ static void rtw_usb_rx_handler(struct work_struct *work)
|
|||
|
||||
do {
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
pkt_stat.shift;
|
||||
|
||||
|
|
@ -889,9 +890,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
|
|||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
|
||||
rtw_usb_tx_queue_purge(rtwusb);
|
||||
flush_workqueue(rtwusb->txwq);
|
||||
destroy_workqueue(rtwusb->txwq);
|
||||
rtw_usb_tx_queue_purge(rtwusb);
|
||||
}
|
||||
|
||||
static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
|
||||
|
|
|
|||
|
|
@ -211,25 +211,17 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
const struct rtw89_sec_cam_entry *sec_cam,
|
||||
bool inform_fw)
|
||||
static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
const struct rtw89_sec_cam_entry *sec_cam,
|
||||
bool inform_fw)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
|
||||
struct rtw89_vif *rtwvif;
|
||||
struct rtw89_addr_cam_entry *addr_cam;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for deleting sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
|
||||
for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {
|
||||
if (addr_cam->sec_ent[i] != sec_cam->sec_cam_idx)
|
||||
|
|
@ -239,11 +231,11 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
|||
}
|
||||
|
||||
if (inform_fw) {
|
||||
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
|
||||
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev,
|
||||
"failed to update dctl cam del key: %d\n", ret);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
|
||||
}
|
||||
|
|
@ -251,25 +243,17 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct rtw89_sec_cam_entry *sec_cam)
|
||||
static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct rtw89_sec_cam_entry *sec_cam)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
|
||||
struct rtw89_vif *rtwvif;
|
||||
struct rtw89_addr_cam_entry *addr_cam;
|
||||
u8 key_idx = 0;
|
||||
int ret;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for adding sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
|
||||
if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
||||
key->cipher == WLAN_CIPHER_SUITE_WEP104)
|
||||
|
|
@ -285,13 +269,13 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
|||
addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
|
||||
addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
|
||||
set_bit(key_idx, addr_cam->sec_cam_map);
|
||||
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
|
||||
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
|
||||
ret);
|
||||
|
|
@ -302,6 +286,92 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
const struct rtw89_sec_cam_entry *sec_cam,
|
||||
bool inform_fw)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
|
||||
struct rtw89_sta_link *rtwsta_link;
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
struct rtw89_vif *rtwvif;
|
||||
unsigned int link_id;
|
||||
int ret;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for deleting sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = vif_to_rtwvif(vif);
|
||||
|
||||
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
|
||||
rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL;
|
||||
if (rtwsta && !rtwsta_link)
|
||||
continue;
|
||||
|
||||
ret = __rtw89_cam_detach_sec_cam(rtwdev, rtwvif_link, rtwsta_link,
|
||||
sec_cam, inform_fw);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct rtw89_sec_cam_entry *sec_cam)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
|
||||
struct rtw89_sta_link *rtwsta_link;
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
struct rtw89_vif *rtwvif;
|
||||
unsigned int link_id;
|
||||
int key_link_id;
|
||||
int ret;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for adding sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = vif_to_rtwvif(vif);
|
||||
|
||||
key_link_id = ieee80211_vif_is_mld(vif) ? key->link_id : 0;
|
||||
if (key_link_id >= 0) {
|
||||
rtwvif_link = rtwvif->links[key_link_id];
|
||||
rtwsta_link = rtwsta ? rtwsta->links[key_link_id] : NULL;
|
||||
|
||||
if (!rtwvif_link || (rtwsta && !rtwsta_link)) {
|
||||
rtw89_err(rtwdev, "No drv link for adding sec cam\n");
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
|
||||
rtwsta_link, key, sec_cam);
|
||||
}
|
||||
|
||||
/* key_link_id < 0: MLD pairwise key */
|
||||
if (!rtwsta) {
|
||||
rtw89_err(rtwdev, "No sta for adding MLD pairwise sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
|
||||
rtwvif_link = rtwsta_link->rtwvif_link;
|
||||
ret = __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
|
||||
rtwsta_link, key, sec_cam);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
|
|
@ -485,10 +555,10 @@ void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
|
|||
clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
|
||||
}
|
||||
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
|
||||
|
||||
rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
|
||||
rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
|
||||
|
|
@ -593,7 +663,7 @@ static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
|
|||
}
|
||||
|
||||
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_bssid_cam_entry *bssid_cam,
|
||||
const u8 *bssid)
|
||||
{
|
||||
|
|
@ -613,7 +683,7 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
|||
}
|
||||
|
||||
bssid_cam->bssid_cam_idx = bssid_cam_idx;
|
||||
bssid_cam->phy_idx = rtwvif->phy_idx;
|
||||
bssid_cam->phy_idx = rtwvif_link->phy_idx;
|
||||
bssid_cam->len = BSSID_CAM_ENT_SIZE;
|
||||
bssid_cam->offset = 0;
|
||||
bssid_cam->valid = true;
|
||||
|
|
@ -622,20 +692,21 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
|
||||
{
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
|
||||
|
||||
ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
|
||||
ether_addr_copy(bssid_cam->bssid, rtwvif_link->bssid);
|
||||
}
|
||||
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
|
||||
ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
|
||||
rtwvif_link->bssid);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to init bssid cam\n");
|
||||
return ret;
|
||||
|
|
@ -651,19 +722,27 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
|||
}
|
||||
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta, u8 *cmd)
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link, u8 *cmd)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
|
||||
u8 bss_color = vif->bss_conf.he_bss_color.color;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
|
||||
rtwsta_link);
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
u8 bss_color;
|
||||
u8 bss_mask;
|
||||
|
||||
if (vif->bss_conf.nontransmitted)
|
||||
rcu_read_lock();
|
||||
|
||||
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
|
||||
bss_color = bss_conf->he_bss_color.color;
|
||||
|
||||
if (bss_conf->nontransmitted)
|
||||
bss_mask = RTW89_BSSID_MATCH_5_BYTES;
|
||||
else
|
||||
bss_mask = RTW89_BSSID_MATCH_ALL;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
|
||||
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
|
||||
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
|
||||
|
|
@ -694,19 +773,30 @@ static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
|
|||
}
|
||||
|
||||
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
const u8 *scan_mac_addr,
|
||||
u8 *cmd)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
|
||||
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
|
||||
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
|
||||
struct rtw89_addr_cam_entry *addr_cam =
|
||||
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr;
|
||||
u8 sma_hash, tma_hash, addr_msk_start;
|
||||
u8 sma_start = 0;
|
||||
u8 tma_start = 0;
|
||||
u8 *tma = sta ? sta->addr : rtwvif->bssid;
|
||||
const u8 *tma;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (sta) {
|
||||
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
|
||||
tma = link_sta->addr;
|
||||
} else {
|
||||
tma = rtwvif_link->bssid;
|
||||
}
|
||||
|
||||
if (addr_cam->addr_mask != 0) {
|
||||
addr_msk_start = __ffs(addr_cam->addr_mask);
|
||||
|
|
@ -723,10 +813,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
|||
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
|
||||
|
||||
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
|
||||
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
|
||||
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
|
||||
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
|
||||
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
|
||||
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type);
|
||||
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond);
|
||||
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule);
|
||||
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx);
|
||||
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
|
||||
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
|
||||
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
|
||||
|
|
@ -748,20 +838,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
|||
FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
|
||||
FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
|
||||
|
||||
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
|
||||
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
|
||||
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
|
||||
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
|
||||
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
|
||||
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
|
||||
FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
|
||||
if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
|
||||
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port);
|
||||
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port);
|
||||
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger);
|
||||
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop);
|
||||
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind);
|
||||
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind);
|
||||
FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id :
|
||||
rtwvif_link->mac_id);
|
||||
if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA)
|
||||
FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
|
||||
else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
|
||||
else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
|
||||
FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
|
||||
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
|
||||
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
|
||||
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
|
||||
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern);
|
||||
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc);
|
||||
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic);
|
||||
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
|
||||
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
|
||||
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
|
||||
|
|
@ -780,18 +871,22 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
|||
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
|
||||
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
|
||||
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
struct rtw89_addr_cam_entry *addr_cam =
|
||||
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
|
||||
|
||||
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
|
||||
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
|
||||
rtwvif_link->mac_id,
|
||||
DCTLINFO_V1_C0_MACID) |
|
||||
le32_encode_bits(1, DCTLINFO_V1_C0_OP);
|
||||
|
||||
|
|
@ -862,15 +957,17 @@ void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
|||
}
|
||||
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
struct rtw89_addr_cam_entry *addr_cam =
|
||||
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
|
||||
|
||||
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
|
||||
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
|
||||
rtwvif_link->mac_id,
|
||||
DCTLINFO_V2_C0_MACID) |
|
||||
le32_encode_bits(1, DCTLINFO_V2_C0_OP);
|
||||
|
||||
|
|
|
|||
|
|
@ -526,34 +526,34 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
|
|||
#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
|
||||
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
|
||||
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
|
||||
int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_addr_cam_entry *addr_cam,
|
||||
const struct rtw89_bssid_cam_entry *bssid_cam);
|
||||
void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_addr_cam_entry *addr_cam);
|
||||
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_bssid_cam_entry *bssid_cam,
|
||||
const u8 *bssid);
|
||||
void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_bssid_cam_entry *bssid_cam);
|
||||
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *vif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *vif,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
const u8 *scan_mac_addr, u8 *cmd);
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 *h2c);
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta, u8 *cmd);
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link, u8 *cmd);
|
||||
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
|
|
@ -564,6 +564,6 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
|
|||
struct ieee80211_key_conf *key,
|
||||
bool inform_fw);
|
||||
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif);
|
||||
struct rtw89_vif_link *rtwvif_link);
|
||||
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev);
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user