From 50282c0283165afbb6430b7acc90e905bbe412b6 Mon Sep 17 00:00:00 2001 From: Vasileios Amoiridis Date: Wed, 4 Sep 2024 17:49:17 +0200 Subject: [PATCH 001/126] wifi: brcmfmac: of: Make use of irq_get_trigger_type() Convert irqd_get_trigger_type(irq_get_irq_data(irq)) cases to the more simple irq_get_trigger_type(). Signed-off-by: Vasileios Amoiridis Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240904154919.118513-2-vassilisamir@gmail.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index fe4f65756105..e2611f164fa8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -138,7 +138,7 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, brcmf_err("interrupt could not be mapped\n"); return; } - 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; From 18ae128c1ddcaf0ca697238621b0e237e9653384 Mon Sep 17 00:00:00 2001 From: Vasileios Amoiridis Date: Wed, 4 Sep 2024 17:49:18 +0200 Subject: [PATCH 002/126] wifi: wlcore: sdio: Make use of irq_get_trigger_type() Convert irqd_get_trigger_type(irq_get_irq_data(irq)) cases to the more simple irq_get_trigger_type(irq). Signed-off-by: Vasileios Amoiridis Reviewed-by: Sabeeh Khan Tested-by: Sabeeh Khan Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240904154919.118513-3-vassilisamir@gmail.com --- drivers/net/wireless/ti/wlcore/sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 92fb5b8dcdae..9e1b644beba9 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -324,15 +324,13 @@ static int wl1271_probe(struct sdio_func *func, memset(res, 0x00, sizeof(res)); res[0].start = irq; - res[0].flags = IORESOURCE_IRQ | - irqd_get_trigger_type(irq_get_irq_data(irq)); + res[0].flags = IORESOURCE_IRQ | irq_get_trigger_type(irq); res[0].name = "irq"; if (wakeirq > 0) { res[1].start = wakeirq; - res[1].flags = IORESOURCE_IRQ | - irqd_get_trigger_type(irq_get_irq_data(wakeirq)); + res[1].flags = IORESOURCE_IRQ | irq_get_trigger_type(wakeirq); res[1].name = "wakeirq"; num_irqs = 2; } else { From a3ede2b0e65a955d64a00261efec56d9e1e1f872 Mon Sep 17 00:00:00 2001 From: Vasileios Amoiridis Date: Wed, 4 Sep 2024 17:49:19 +0200 Subject: [PATCH 003/126] wifi: wlcore: sdio: Use helper to define resources Resources definition can become simpler and more organised by using the dedicated helpers. Signed-off-by: Vasileios Amoiridis Tested-by: Sabeeh Khan Reviewed-by: Sabeeh Khan Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240904154919.118513-4-vassilisamir@gmail.com --- drivers/net/wireless/ti/wlcore/sdio.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 9e1b644beba9..a73207bbe5d7 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -323,15 +323,12 @@ static int wl1271_probe(struct sdio_func *func, memset(res, 0x00, sizeof(res)); - res[0].start = irq; - res[0].flags = IORESOURCE_IRQ | irq_get_trigger_type(irq); - res[0].name = "irq"; - + res[0] = DEFINE_RES_IRQ_NAMED(irq, "irq"); + res[0].flags |= irq_get_trigger_type(irq); if (wakeirq > 0) { - res[1].start = wakeirq; - res[1].flags = IORESOURCE_IRQ | irq_get_trigger_type(wakeirq); - res[1].name = "wakeirq"; + res[1] = DEFINE_RES_IRQ_NAMED(wakeirq, "wakeirq"); + res[1].flags |= irq_get_trigger_type(wakeirq); num_irqs = 2; } else { num_irqs = 1; From 97cb465ee6c1cbc1965fe4e3f26676ce2a2d72f6 Mon Sep 17 00:00:00 2001 From: Jacobe Zang Date: Tue, 10 Sep 2024 11:04:11 +0800 Subject: [PATCH 004/126] dt-bindings: net: wireless: brcm4329-fmac: add pci14e4,449d It's the device id used by AP6275P which is the Wi-Fi module used by Rockchip's RK3588 evaluation board and also used in some other RK3588 boards. Acked-by: Arend van Spriel Acked-by: Krzysztof Kozlowski Signed-off-by: Jacobe Zang Reviewed-by: Sebastian Reichel Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910-wireless-mainline-v14-1-9d80fea5326d@wesion.com --- .../devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml index e564f20d8f41..2c2093c77ec9 100644 --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml @@ -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 From 7ca3fac195411c43d4455ffe008698551011d3f2 Mon Sep 17 00:00:00 2001 From: Jacobe Zang Date: Tue, 10 Sep 2024 11:04:12 +0800 Subject: [PATCH 005/126] dt-bindings: net: wireless: brcm4329-fmac: add clock description for AP6275P Not only AP6275P Wi-Fi device but also all Broadcom wireless devices allow external low power clock input. In DTS the clock as an optional choice in the absence of an internal clock. Reviewed-by: Arend van Spriel Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jacobe Zang Reviewed-by: Sebastian Reichel Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910-wireless-mainline-v14-2-9d80fea5326d@wesion.com --- .../bindings/net/wireless/brcm,bcm4329-fmac.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml index 2c2093c77ec9..a3607d55ef36 100644 --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml @@ -122,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 From 0ff0843310b74e565901d85f849fb308c3b1f220 Mon Sep 17 00:00:00 2001 From: Jacobe Zang Date: Tue, 10 Sep 2024 11:04:13 +0800 Subject: [PATCH 006/126] wifi: brcmfmac: Add optional lpo clock enable support WiFi modules often require 32kHz clock to function. Add support to enable the clock to PCIe driver and move "brcm,bcm4329-fmac" check to the top of brcmf_of_probe. Change function prototypes from void to int and add appropriate errno's for return values that will be send to bus when error occurred. Co-developed-by: Ondrej Jirman Signed-off-by: Ondrej Jirman Co-developed-by: Arend van Spriel Signed-off-by: Arend van Spriel Reviewed-by: Sai Krishna Signed-off-by: Jacobe Zang Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel # On RK3588 EVB1 Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910-wireless-mainline-v14-3-9d80fea5326d@wesion.com --- .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +-- .../broadcom/brcm80211/brcmfmac/common.c | 3 ++- .../wireless/broadcom/brcm80211/brcmfmac/of.c | 25 +++++++++++++------ .../wireless/broadcom/brcm80211/brcmfmac/of.h | 9 ++++--- .../broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ .../broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++------ .../broadcom/brcm80211/brcmfmac/usb.c | 3 +++ 7 files changed, 47 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index d35262335eaf..17f6b33beabd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -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); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index b24faae35873..58d50918dd17 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -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; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index e2611f164fa8..b90e23bb9366 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #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,15 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, of_node_put(root); } + clk = devm_clk_get_optional_enabled(dev, "lpo"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no"); + clk_set_rate(clk, 32768); + 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 +133,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 = irq_get_trigger_type(irq); sdio->oob_irq_supported = true; sdio->oob_irq_nr = irq; sdio->oob_irq_flags = irqf; + + return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h index 10bf52253337..ae124c73fc3b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h @@ -3,11 +3,12 @@ * Copyright (c) 2014 Broadcom Corporation */ #ifdef CONFIG_OF -void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings); +int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings); #else -static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings) +static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { + return 0; } #endif /* CONFIG_OF */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index ce482a3877e9..190e8990618c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -2452,6 +2452,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) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 1461dc453ac2..a9b4d560cbfc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -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 */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 8afbf529c745..2821c27f317e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -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); From ea11a89c3ac64ada9d8b7f7de279cb6385ed194f Mon Sep 17 00:00:00 2001 From: Jacobe Zang Date: Tue, 10 Sep 2024 11:04:14 +0800 Subject: [PATCH 007/126] wifi: brcmfmac: add flag for random seed during firmware download Providing the random seed to firmware was tied to the fact that the device has a valid OTP, which worked for some Apple chips. However, it turns out the BCM43752 device also needs the random seed in order to get firmware running. Suspect it is simply tied to the firmware branch used for the device. Introducing a mechanism to allow setting it for a device through the device table. Co-developed-by: Ondrej Jirman Signed-off-by: Ondrej Jirman Co-developed-by: Arend van Spriel Signed-off-by: Arend van Spriel Signed-off-by: Jacobe Zang Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel # On RK3588 EVB1 Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910-wireless-mainline-v14-4-9d80fea5326d@wesion.com --- .../broadcom/brcm80211/brcmfmac/pcie.c | 52 ++++++++++++++++--- .../broadcom/brcm80211/include/brcm_hw_ids.h | 2 + 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 190e8990618c..c0fdaa4dceda 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -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[]; @@ -2475,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); @@ -2663,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[] = { @@ -2698,9 +2733,10 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA), BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC), BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC_SEED), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC_SEED), { /* end: all zeroes */ } }; diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h index 44684bf1b9ac..c1e22c589d85 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h @@ -52,6 +52,7 @@ #define BRCM_CC_43664_CHIP_ID 43664 #define BRCM_CC_43666_CHIP_ID 43666 #define BRCM_CC_4371_CHIP_ID 0x4371 +#define BRCM_CC_43752_CHIP_ID 43752 #define BRCM_CC_4377_CHIP_ID 0x4377 #define BRCM_CC_4378_CHIP_ID 0x4378 #define BRCM_CC_4387_CHIP_ID 0x4387 @@ -94,6 +95,7 @@ #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 #define BRCM_PCIE_4371_DEVICE_ID 0x440d #define BRCM_PCIE_43596_DEVICE_ID 0x4415 +#define BRCM_PCIE_43752_DEVICE_ID 0x449d #define BRCM_PCIE_4377_DEVICE_ID 0x4488 #define BRCM_PCIE_4378_DEVICE_ID 0x4425 #define BRCM_PCIE_4387_DEVICE_ID 0x4433 From bcd1371bd85e560ccc9159b7747f94bfe43b77a6 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Tue, 10 Sep 2024 20:43:12 +0800 Subject: [PATCH 008/126] wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: cd8d3d321285 ("p54spi: p54spi driver") Signed-off-by: Jinjie Ruan Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910124314.698896-2-ruanjinjie@huawei.com --- drivers/net/wireless/intersil/p54/p54spi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c index d33a994906a7..27f44a9f0bc1 100644 --- a/drivers/net/wireless/intersil/p54/p54spi.c +++ b/drivers/net/wireless/intersil/p54/p54spi.c @@ -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); From 9a98dd48b6d834d7a3fe5e8e7b8c3a1d006f9685 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Tue, 10 Sep 2024 20:43:13 +0800 Subject: [PATCH 009/126] wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: 853402a00823 ("mwifiex: Enable WoWLAN for both sdio and pcie") Signed-off-by: Jinjie Ruan Acked-by: Brian Norris Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910124314.698896-3-ruanjinjie@huawei.com --- drivers/net/wireless/marvell/mwifiex/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 96d1f6039fbc..855019fe5485 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -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; From 5a4d42c1688c88f3be6aef46b0ea6c32694cd2b8 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Tue, 10 Sep 2024 20:43:14 +0800 Subject: [PATCH 010/126] wifi: wl1251: Use IRQF_NO_AUTOEN flag in request_irq() As commit cbe16f35bee6 ("genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()") said, the code below is subobtimal. IRQF_NO_AUTOEN flag can be used by drivers to request_irq(). It prevents the automatic enabling of the requested interrupt in the same safe way. With that the usage can be simplified and corrected. irq_set_status_flags(irq, IRQ_NOAUTOEN); request_irq(dev, irq...); Signed-off-by: Jinjie Ruan Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240910124314.698896-4-ruanjinjie@huawei.com --- drivers/net/wireless/ti/wl1251/sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index c705081249d6..b45050243129 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -233,8 +233,8 @@ static int wl1251_sdio_probe(struct sdio_func *func, } if (wl->irq) { - irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); - ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); + ret = request_irq(wl->irq, wl1251_line_irq, IRQF_NO_AUTOEN, + "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; From 9e698af3a42f76720f38b55076ccb1ec4fbf8d4b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 12 Sep 2024 14:53:35 +0100 Subject: [PATCH 011/126] wifi: rtlwifi: make read-only arrays static const Don't populate the read-only arrays params, toshiba_smid1, toshiba_smid2, samsung_smid and lenovo_smid on the stack at run time, instead make them static const. Signed-off-by: Colin Ian King Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240912135335.590464-1-colin.i.king@gmail.com --- .../wireless/realtek/rtlwifi/rtl8723be/hw.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index 0e77de1baaf8..bcfc53af4c1a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -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 }; From 2e8fd540c081fd4bd4fd16d619285e4d08a5b585 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 13 Sep 2024 15:13:36 +0800 Subject: [PATCH 012/126] wifi: rtw89: 8922a: rfk: enlarge TSSI timeout time to 20ms Firmware needs more time to execute TSSI calibration command. Enlarge timeout time accordingly, otherwise driver throws messages: rtw89_8922ae 0000:03:00.0: failed to wait RF TSSI Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240913071340.41822-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 63b1ff2f98ed..fb422bff4912 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2035,7 +2035,7 @@ static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtw rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54); rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84); - rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 6); + rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20); rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34); rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32); From cd0d81d101b9abe87cd514711e7197bea60934f3 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 13 Sep 2024 15:13:37 +0800 Subject: [PATCH 013/126] wifi: rtw89: 8922a: rfk: support firmware command RX DCK v1 format RX DCK stands for receiver DC calibration. The v1 format adds a field to indicate the calibration is for operation channel or an average value for all scanning channels. Update the format accordingly, and increase firmware format sequence to 2. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240913071340.41822-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 35 +++++++++++++------ drivers/net/wireless/realtek/rtw89/fw.h | 9 +++-- drivers/net/wireless/realtek/rtw89/phy.c | 4 +-- drivers/net/wireless/realtek/rtw89/phy.h | 2 +- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 6 ++-- 6 files changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 4ed9034fdb46..64b7fd1f6079 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4445,6 +4445,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0, RTW89_FW_FEATURE_WOW_REASON_V1, RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, + RTW89_FW_FEATURE_RFK_RXDCK_V0, }; struct rtw89_fw_suit { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index d9b0e7ebe619..93a338bbf59c 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -687,6 +687,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), }; static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, @@ -5518,30 +5519,44 @@ int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, } int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, - const struct rtw89_chan *chan) + const struct rtw89_chan *chan, bool is_chl_k) { + struct rtw89_h2c_rf_rxdck_v0 *v0; struct rtw89_h2c_rf_rxdck *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; + int ver = -1; int ret; + if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) { + len = sizeof(*v0); + ver = 0; + } + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n"); return -ENOMEM; } skb_put(skb, len); + v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data; + + v0->len = len; + v0->phy = phy_idx; + v0->is_afe = false; + v0->kpath = RF_AB; + v0->cur_band = chan->band_type; + v0->cur_bw = chan->band_width; + v0->cur_ch = chan->channel; + v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); + + if (ver == 0) + goto hdr; + h2c = (struct rtw89_h2c_rf_rxdck *)skb->data; + h2c->is_chl_k = is_chl_k; - h2c->len = len; - h2c->phy = phy_idx; - h2c->is_afe = false; - h2c->kpath = RF_AB; - h2c->cur_band = chan->band_type; - h2c->cur_bw = chan->band_width; - h2c->cur_ch = chan->channel; - h2c->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK); - +hdr: rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK, H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len); diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index ad47e77d740b..78820bd28098 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4286,7 +4286,7 @@ struct rtw89_h2c_rf_dack { __le32 type; } __packed; -struct rtw89_h2c_rf_rxdck { +struct rtw89_h2c_rf_rxdck_v0 { u8 len; u8 phy; u8 is_afe; @@ -4297,6 +4297,11 @@ struct rtw89_h2c_rf_rxdck { u8 rxdck_dbg_en; } __packed; +struct rtw89_h2c_rf_rxdck { + struct rtw89_h2c_rf_rxdck_v0 v0; + u8 is_chl_k; +} __packed; + enum rtw89_rf_log_type { RTW89_RF_RUN_LOG = 0, RTW89_RF_RPT_LOG = 1, @@ -4501,7 +4506,7 @@ int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan); int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, - const struct rtw89_chan *chan); + const struct rtw89_chan *chan, bool is_chl_k); int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, bool rack, bool dack); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index c7165e757842..0c0d25e602c9 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3171,13 +3171,13 @@ EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait); int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan, - unsigned int ms) + bool is_chl_k, unsigned int ms) { int ret; rtw89_phy_rfk_report_prep(rtwdev); - ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan); + ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan, is_chl_k); if (ret) return ret; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 6dd8ec46939a..d00faf151d39 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -929,7 +929,7 @@ int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev, int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan, - unsigned int ms); + bool is_chl_k, unsigned int ms); void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, const struct rtw89_chan *chan, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index fb422bff4912..c2be460f6238 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -13,7 +13,7 @@ #include "rtw8922a_rfk.h" #include "util.h" -#define RTW8922A_FW_FORMAT_MAX 1 +#define RTW8922A_FW_FORMAT_MAX 2 #define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw" #define RTW8922A_MODULE_FIRMWARE \ RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin" @@ -1998,7 +1998,7 @@ static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev) rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5); rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, chan, 58); - rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32); + rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, false, 32); } static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) @@ -2037,7 +2037,7 @@ static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtw rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84); rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20); rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34); - rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32); + rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32); rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP); From 8d445310ba6118a1ad2454a906acea7b7cc3f7e8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 13 Sep 2024 15:13:38 +0800 Subject: [PATCH 014/126] wifi: rtw89: rfk: add firmware debug log of TSSI TSSI is short for transmitter signal strength indication. Print out the TSSI log from firmware C2H events. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240913071340.41822-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.h | 8 ++++++ drivers/net/wireless/realtek/rtw89/phy.c | 35 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 78820bd28098..4980a7041fb8 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4362,6 +4362,14 @@ struct rtw89_c2h_rf_rxdck_rpt_log { u8 timeout[2]; } __packed; +struct rtw89_c2h_rf_tssi_rpt_log { + s8 alignment_power[2][2][4]; + u8 alignment_power_cw_h[2][2][4]; + u8 alignment_power_cw_l[2][2][4]; + u8 tssi_alimk_state[2][2]; + u8 default_txagc_offset[2][2]; +} __packed; + struct rtw89_c2h_rf_txgapk_rpt_log { __le32 r0x8010[2]; __le32 chk_cnt; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 0c0d25e602c9..c2116c2987fd 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2692,7 +2692,9 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, struct rtw89_c2h_rf_txgapk_rpt_log *txgapk; struct rtw89_c2h_rf_rxdck_rpt_log *rxdck; struct rtw89_c2h_rf_dack_rpt_log *dack; + struct rtw89_c2h_rf_tssi_rpt_log *tssi; struct rtw89_c2h_rf_dpk_rpt_log *dpk; + int i, j, k; switch (func) { case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK: @@ -2770,6 +2772,39 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch, rxdck->timeout); return; + case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI: + if (len != sizeof(*tssi)) + goto out; + + tssi = content; + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 4; k++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw_h[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power_cw_h[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw_l[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power_cw_l[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power[%d][%d][%d]=%d\n", + i, j, k, tssi->alignment_power[i][j][k]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] alignment_power_cw[%d][%d][%d]=%d\n", + i, j, k, + (tssi->alignment_power_cw_h[i][j][k] << 8) + + tssi->alignment_power_cw_l[i][j][k]); + } + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] tssi_alimk_state[%d][%d]=%d\n", + i, j, tssi->tssi_alimk_state[i][j]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[TSSI] default_txagc_offset[%d]=%d\n", + j, tssi->default_txagc_offset[0][j]); + } + } + return; case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK: if (len != sizeof(*txgapk)) goto out; From 6f540670456e807c56a3f46b2fbcbe0e567158e2 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 13 Sep 2024 15:13:39 +0800 Subject: [PATCH 015/126] wifi: rtw89: rfk: add firmware debug log of IQK Print out IQ signal calibration log from firmware C2H events. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240913071340.41822-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.h | 36 ++++++++++++ drivers/net/wireless/realtek/rtw89/phy.c | 74 ++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 4980a7041fb8..bbf62950182a 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4318,6 +4318,42 @@ struct rtw89_c2h_rf_run_log { __le32 arg[4]; } __packed; +struct rtw89_c2h_rf_iqk_rpt_log { + bool iqk_tx_fail[2]; + bool iqk_rx_fail[2]; + bool is_iqk_init; + bool is_reload; + bool is_wb_txiqk[2]; + bool is_wb_rxiqk[2]; + bool is_nbiqk; + bool txiqk_en; + bool rxiqk_en; + bool lok_en; + bool iqk_xym_en; + bool iqk_sram_en; + bool iqk_fft_en; + bool is_fw_iqk; + bool is_iqk_enable; + bool iqk_cfir_en; + bool thermal_rek_en; + u8 iqk_band[2]; + u8 iqk_ch[2]; + u8 iqk_bw[2]; + u8 iqk_times; + u8 version; + u8 phy; + u8 fwk_status; + u8 rsvd; + __le32 reload_cnt; + __le32 iqk_fail_cnt; + __le32 lok_idac[2]; + __le32 lok_vbuf[2]; + __le32 rftxgain[2][4]; + __le32 rfrxgain[2][4]; + __le32 tx_xym[2][4]; + __le32 rx_xym[2][4]; +} __packed; + struct rtw89_c2h_rf_dpk_rpt_log { u8 ver; u8 idx[2]; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index c2116c2987fd..ae404ca4e2ee 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2694,9 +2694,83 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, struct rtw89_c2h_rf_dack_rpt_log *dack; struct rtw89_c2h_rf_tssi_rpt_log *tssi; struct rtw89_c2h_rf_dpk_rpt_log *dpk; + struct rtw89_c2h_rf_iqk_rpt_log *iqk; int i, j, k; switch (func) { + case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK: + if (len != sizeof(*iqk)) + goto out; + + iqk = content; + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_iqk_init = %x\n", iqk->is_iqk_init); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_reload = %x\n", iqk->is_reload); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_nbiqk = %x\n", iqk->is_nbiqk); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->txiqk_en = %x\n", iqk->txiqk_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rxiqk_en = %x\n", iqk->rxiqk_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->lok_en = %x\n", iqk->lok_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_xym_en = %x\n", iqk->iqk_xym_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_sram_en = %x\n", iqk->iqk_sram_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_fft_en = %x\n", iqk->iqk_fft_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_fw_iqk = %x\n", iqk->is_fw_iqk); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->is_iqk_enable = %x\n", iqk->is_iqk_enable); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->iqk_cfir_en = %x\n", iqk->iqk_cfir_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->thermal_rek_en = %x\n", iqk->thermal_rek_en); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->version = %x\n", iqk->version); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->phy = %x\n", iqk->phy); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status); + + for (i = 0; i < 2; i++) { + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] ======== Path %x ========\n", i); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n", + i, iqk->iqk_band[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_ch[%d] = %x\n", + i, iqk->iqk_ch[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n", + i, iqk->iqk_bw[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n", + i, le32_to_cpu(iqk->lok_idac[i])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n", + i, le32_to_cpu(iqk->lok_vbuf[i])); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_tx_fail[%d] = %x\n", + i, iqk->iqk_tx_fail[i]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n", + i, iqk->iqk_rx_fail[i]); + for (j = 0; j < 4; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rftxgain[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rftxgain[i][j])); + for (j = 0; j < 4; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->tx_xym[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->tx_xym[i][j])); + for (j = 0; j < 4; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rfrxgain[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rfrxgain[i][j])); + for (j = 0; j < 4; j++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[IQK] iqk->rx_xym[%d][%d] = %x\n", + i, j, le32_to_cpu(iqk->rx_xym[i][j])); + } + return; case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK: if (len != sizeof(*dpk)) goto out; From bd25f45f089690d591f00a7c2b92a9ab84cad48c Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 13 Sep 2024 15:13:40 +0800 Subject: [PATCH 016/126] wifi: rtw89: rfk: update firmware debug log of DACK to v2 Update DACK (digital-to-analog converters calibration) log to v2 by firmware C2H events. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240913071340.41822-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.h | 12 +++-- drivers/net/wireless/realtek/rtw89/phy.c | 62 ++++++++++++++++++------ 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index bbf62950182a..5b8d83d90a4e 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4375,19 +4375,25 @@ struct rtw89_c2h_rf_dpk_rpt_log { struct rtw89_c2h_rf_dack_rpt_log { u8 fwdack_ver; - u8 fwdack_rpt_ver; + u8 fwdack_info_ver; u8 msbk_d[2][2][16]; u8 dadck_d[2][2]; u8 cdack_d[2][2][2]; - __le16 addck2_d[2][2][2]; + u8 addck2_hd[2][2][2]; + u8 addck2_ld[2][2][2]; u8 adgaink_d[2][2]; - __le16 biask_d[2][2]; + u8 biask_hd[2][2]; + u8 biask_ld[2][2]; u8 addck_timeout; u8 cdack_timeout; u8 dadck_timeout; u8 msbk_timeout; u8 adgaink_timeout; + u8 wbadcdck_timeout; + u8 drck_timeout; u8 dack_fail; + u8 wbdck_d[2]; + u8 rck_d; } __packed; struct rtw89_c2h_rf_rxdck_rpt_log { diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ae404ca4e2ee..87719b22381d 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2792,8 +2792,23 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, dack = content; - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ver=0x%x 0x%x\n", - dack->fwdack_ver, dack->fwdack_rpt_ver); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]FWDACK SUMMARY!!!!!\n"); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]FWDACK ver = 0x%x, FWDACK rpt_ver = 0x%x, driver rpt_ver = 0x%x\n", + dack->fwdack_ver, dack->fwdack_info_ver, 0x2); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]timeout code = [0x%x 0x%x 0x%x 0x%x 0x%x]\n", + dack->addck_timeout, dack->cdack_timeout, dack->dadck_timeout, + dack->adgaink_timeout, dack->msbk_timeout); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]DACK fail = 0x%x\n", dack->dack_fail); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S0 WBADCK = [0x%x]\n", dack->wbdck_d[0]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]S1 WBADCK = [0x%x]\n", dack->wbdck_d[1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, + "[DACK]DRCK = [0x%x]\n", dack->rck_d); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n", dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n", @@ -2804,13 +2819,17 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n", - dack->addck2_d[0][0][0], dack->addck2_d[0][0][1]); + ((u32)dack->addck2_hd[0][0][0] << 8) | dack->addck2_ld[0][0][0], + ((u32)dack->addck2_hd[0][0][1] << 8) | dack->addck2_ld[0][0][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n", - dack->addck2_d[0][1][0], dack->addck2_d[0][1][1]); + ((u32)dack->addck2_hd[0][1][0] << 8) | dack->addck2_ld[0][1][0], + ((u32)dack->addck2_hd[0][1][1] << 8) | dack->addck2_ld[0][1][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n", - dack->addck2_d[1][0][0], dack->addck2_d[1][0][1]); + ((u32)dack->addck2_hd[1][0][0] << 8) | dack->addck2_ld[1][0][0], + ((u32)dack->addck2_hd[1][0][1] << 8) | dack->addck2_ld[1][0][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n", - dack->addck2_d[1][1][0], dack->addck2_d[1][1][1]); + ((u32)dack->addck2_hd[1][1][0] << 8) | dack->addck2_ld[1][1][0], + ((u32)dack->addck2_hd[1][1][1] << 8) | dack->addck2_ld[1][1][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n", dack->adgaink_d[0][0], dack->adgaink_d[0][1]); @@ -2823,18 +2842,29 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, dack->dadck_d[1][0], dack->dadck_d[1][1]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n", - dack->biask_d[0][0]); + ((u32)dack->biask_hd[0][0] << 8) | dack->biask_ld[0][0]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n", - dack->biask_d[1][0]); + ((u32)dack->biask_hd[1][0] << 8) | dack->biask_ld[1][0]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic: %*ph\n", - (int)sizeof(dack->msbk_d[0][0]), dack->msbk_d[0][0]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc: %*ph\n", - (int)sizeof(dack->msbk_d[0][1]), dack->msbk_d[0][1]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic: %*ph\n", - (int)sizeof(dack->msbk_d[1][0]), dack->msbk_d[1][0]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc: %*ph\n", - (int)sizeof(dack->msbk_d[1][1]), dack->msbk_d[1][1]); + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[0][0][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[0][1][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[1][0][i]); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); + for (i = 0; i < 0x10; i++) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", + dack->msbk_d[1][1][i]); return; case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK: if (len != sizeof(*rxdck)) From 140403599b74839b0a57c5397b7e8579e5332364 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 18 Sep 2024 01:53:55 +0300 Subject: [PATCH 017/126] wifi: rtw88: Constify some arrays and structs These are never modified, so make them const: card_enable_flow_8703b card_disable_flow_8703b rtw8703b_ops rtw8723d_ops card_enable_flow_8723d card_disable_flow_8723d trans_carddis_to_cardemu_8821c trans_cardemu_to_act_8821c trans_act_to_cardemu_8821c trans_cardemu_to_carddis_8821c card_enable_flow_8821c card_disable_flow_8821c rtw8821c_dig page_table_8821c rqpn_table_8821c prioq_addrs_8821c rtw8821c_ops card_enable_flow_8822b card_disable_flow_8822b prioq_addrs_8822b rtw8822b_ops rtw8822b_edcca_th card_enable_flow_8822c card_disable_flow_8822c prioq_addrs_8822c rtw8822c_ops rtw8822c_edcca_th Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/dae7994f-3491-40de-b537-ebf68df084bb@gmail.com --- drivers/net/wireless/realtek/rtw88/fw.c | 2 +- drivers/net/wireless/realtek/rtw88/mac.c | 4 ++-- drivers/net/wireless/realtek/rtw88/main.h | 8 +++---- drivers/net/wireless/realtek/rtw88/phy.c | 2 +- drivers/net/wireless/realtek/rtw88/rtw8703b.c | 6 ++--- drivers/net/wireless/realtek/rtw88/rtw8723d.c | 6 ++--- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 22 +++++++++---------- drivers/net/wireless/realtek/rtw88/rtw8822b.c | 10 ++++----- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++----- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index b9b0114e253b..813c12148819 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -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, diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 564f5988ee82..e5abcc20b63c 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -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; diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 945117afe143..83180c488c37 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1167,7 +1167,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 +1209,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 +1242,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; diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index 37ef80c9091d..d57a2aabd89b 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c index 222608de33cd..e3ac748ad646 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c @@ -481,14 +481,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, @@ -1941,7 +1941,7 @@ 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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index 3fba4054d45f..7f33e141e646 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -1430,7 +1430,7 @@ 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, @@ -1788,7 +1788,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 +2004,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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index 526e8de77b3e..9d21c4b1450e 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -1254,7 +1254,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 +1292,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 +1396,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 +1454,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 +1567,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 +1629,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 +1639,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 +1648,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 +1667,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,7 +1683,7 @@ 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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 6edb17aea90e..650585086e8f 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -1978,13 +1978,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 +2156,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,7 +2172,7 @@ 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, @@ -2521,7 +2521,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}, }; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index 1dbe1cdbc3fd..a5531e663dde 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -4874,13 +4874,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 +4972,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,7 +4988,7 @@ 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, @@ -5301,7 +5301,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 }, From 3e5e4a801aaf4283390cc34959c6c48f910ca5ea Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 22 Aug 2024 09:42:55 +0800 Subject: [PATCH 018/126] wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb When removing kernel modules by: rmmod rtw88_8723cs rtw88_8703b rtw88_8723x rtw88_sdio rtw88_core Driver uses skb_queue_purge() to purge TX skb, but not report tx status causing "Have pending ack frames!" warning. Use ieee80211_purge_tx_queue() to correct this. Since ieee80211_purge_tx_queue() doesn't take locks, to prevent racing between TX work and purge TX queue, flush and destroy TX work in advance. wlan0: deauthenticating from aa:f5:fd:60:4c:a8 by local choice (Reason: 3=DEAUTH_LEAVING) ------------[ cut here ]------------ Have pending ack frames! WARNING: CPU: 3 PID: 9232 at net/mac80211/main.c:1691 ieee80211_free_ack_frame+0x5c/0x90 [mac80211] CPU: 3 PID: 9232 Comm: rmmod Tainted: G C 6.10.1-200.fc40.aarch64 #1 Hardware name: pine64 Pine64 PinePhone Braveheart (1.1)/Pine64 PinePhone Braveheart (1.1), BIOS 2024.01 01/01/2024 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] lr : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] sp : ffff80008c1b37b0 x29: ffff80008c1b37b0 x28: ffff000003be8000 x27: 0000000000000000 x26: 0000000000000000 x25: ffff000003dc14b8 x24: ffff80008c1b37d0 x23: ffff000000ff9f80 x22: 0000000000000000 x21: 000000007fffffff x20: ffff80007c7e93d8 x19: ffff00006e66f400 x18: 0000000000000000 x17: ffff7ffffd2b3000 x16: ffff800083fc0000 x15: 0000000000000000 x14: 0000000000000000 x13: 2173656d61726620 x12: 6b636120676e6964 x11: 0000000000000000 x10: 000000000000005d x9 : ffff8000802af2b0 x8 : ffff80008c1b3430 x7 : 0000000000000001 x6 : 0000000000000001 x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000003be8000 Call trace: ieee80211_free_ack_frame+0x5c/0x90 [mac80211] idr_for_each+0x74/0x110 ieee80211_free_hw+0x44/0xe8 [mac80211] rtw_sdio_remove+0x9c/0xc0 [rtw88_sdio] sdio_bus_remove+0x44/0x180 device_remove+0x54/0x90 device_release_driver_internal+0x1d4/0x238 driver_detach+0x54/0xc0 bus_remove_driver+0x78/0x108 driver_unregister+0x38/0x78 sdio_unregister_driver+0x2c/0x40 rtw_8723cs_driver_exit+0x18/0x1000 [rtw88_8723cs] __do_sys_delete_module.isra.0+0x190/0x338 __arm64_sys_delete_module+0x1c/0x30 invoke_syscall+0x74/0x100 el0_svc_common.constprop.0+0x48/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x3c/0x158 el0t_64_sync_handler+0x120/0x138 el0t_64_sync+0x194/0x198 ---[ end trace 0000000000000000 ]--- Reported-by: Peter Robinson Closes: https://lore.kernel.org/linux-wireless/CALeDE9OAa56KMzgknaCD3quOgYuEHFx9_hcT=OFgmMAb+8MPyA@mail.gmail.com/ Tested-by: Ping-Ke Shih # 8723DU Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240822014255.10211-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/sdio.c | 6 +++--- drivers/net/wireless/realtek/rtw88/usb.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 21d0754dd7f6..b67e551fcee3 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1297,12 +1297,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, diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index e83ab6fb83f5..dbc7d8d73494 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -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) @@ -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, From 2f7dae17c48cd1d5616f11d22b3de675db7ab40d Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:52 +0800 Subject: [PATCH 019/126] wifi: rtw89: rename rtw89_vif to rtw89_vif_link ahead for MLO This is an intermediate version that is separated from subsequent major MLO changes, so some functions' namings are not really determined here. e.g. struct rtw89_vif_link *vif_to_rtwvif_safe(struct ieee80211_vif *vif) No logic is changed. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 109 ++--- drivers/net/wireless/realtek/rtw89/cam.h | 16 +- drivers/net/wireless/realtek/rtw89/chan.c | 162 +++---- drivers/net/wireless/realtek/rtw89/chan.h | 4 +- drivers/net/wireless/realtek/rtw89/coex.c | 33 +- drivers/net/wireless/realtek/rtw89/coex.h | 3 +- drivers/net/wireless/realtek/rtw89/core.c | 275 +++++------ drivers/net/wireless/realtek/rtw89/core.h | 72 +-- drivers/net/wireless/realtek/rtw89/debug.c | 17 +- drivers/net/wireless/realtek/rtw89/fw.c | 356 +++++++------- drivers/net/wireless/realtek/rtw89/fw.h | 78 ++-- drivers/net/wireless/realtek/rtw89/mac.c | 442 +++++++++--------- drivers/net/wireless/realtek/rtw89/mac.h | 70 +-- drivers/net/wireless/realtek/rtw89/mac80211.c | 205 ++++---- drivers/net/wireless/realtek/rtw89/mac_be.c | 14 +- drivers/net/wireless/realtek/rtw89/phy.c | 74 +-- drivers/net/wireless/realtek/rtw89/phy.h | 2 +- drivers/net/wireless/realtek/rtw89/ps.c | 92 ++-- drivers/net/wireless/realtek/rtw89/ps.h | 10 +- drivers/net/wireless/realtek/rtw89/regd.c | 46 +- drivers/net/wireless/realtek/rtw89/rtw8851b.c | 13 +- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 12 +- drivers/net/wireless/realtek/rtw89/rtw8852b.c | 13 +- .../net/wireless/realtek/rtw89/rtw8852bt.c | 13 +- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 12 +- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 10 +- drivers/net/wireless/realtek/rtw89/ser.c | 36 +- drivers/net/wireless/realtek/rtw89/util.h | 8 +- drivers/net/wireless/realtek/rtw89/wow.c | 125 ++--- drivers/net/wireless/realtek/rtw89/wow.h | 8 +- 30 files changed, 1197 insertions(+), 1133 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 4476fc7e53db..a3e6d40b3078 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -218,7 +218,7 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, bool inform_fw) { struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; struct rtw89_addr_cam_entry *addr_cam; unsigned int i; int ret = 0; @@ -228,8 +228,8 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, return -EINVAL; } - rtwvif = (struct rtw89_vif *)vif->drv_priv; - addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta); + rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta); 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 +239,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); 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, NULL); if (ret) rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret); } @@ -258,7 +258,7 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, struct rtw89_sec_cam_entry *sec_cam) { struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; struct rtw89_addr_cam_entry *addr_cam; u8 key_idx = 0; int ret; @@ -268,8 +268,8 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, return -EINVAL; } - rtwvif = (struct rtw89_vif *)vif->drv_priv; - addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta); + rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta); if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) @@ -285,13 +285,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); 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, NULL); if (ret) { rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n", ret); @@ -485,10 +485,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 +593,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 +613,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 +622,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,11 +652,12 @@ 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_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, u8 *cmd) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); - struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, + rtwsta); u8 bss_color = vif->bss_conf.he_bss_color.color; u8 bss_mask; @@ -694,19 +696,20 @@ 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_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, 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_vif *vif = rtwvif_to_vif(rtwvif_link); + struct rtw89_addr_cam_entry *addr_cam = + rtw89_get_addr_cam_of(rtwvif_link, rtwsta); struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta); - const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr; + 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; + u8 *tma = sta ? sta->addr : rtwvif_link->bssid; if (addr_cam->addr_mask != 0) { addr_msk_start = __ffs(addr_cam->addr_mask); @@ -723,10 +726,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 +751,20 @@ 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 ? rtwsta->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]); @@ -783,15 +786,16 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, } void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, 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); 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 ? rtwsta->mac_id : rtwvif_link->mac_id, DCTLINFO_V1_C0_MACID) | le32_encode_bits(1, DCTLINFO_V1_C0_OP); @@ -862,15 +866,16 @@ 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_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, 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); 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 ? rtwsta->mac_id : rtwvif_link->mac_id, DCTLINFO_V2_C0_MACID) | le32_encode_bits(1, DCTLINFO_V2_C0_OP); diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h index 5d7b624c2dd4..18ede69144b6 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.h +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -526,33 +526,33 @@ 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_vif_link *vif, struct rtw89_sta *rtwsta, 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_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, 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_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, struct rtw89_h2c_dctlinfo_ud_v2 *h2c); int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, u8 *cmd); int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, @@ -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 diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index 7070c85e2c28..f20431c3e201 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -239,7 +239,7 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev, { struct rtw89_hal *hal = &rtwdev->hal; const struct rtw89_chanctx_cfg *cfg; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; int idx; for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { @@ -254,8 +254,8 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev, w->active_chanctxs++; } - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - if (rtwvif->chanctx_assigned) + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + if (rtwvif_link->chanctx_assigned) w->active_roles++; } } @@ -387,9 +387,9 @@ int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev, static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role, u64 tsf) { - struct rtw89_vif *rtwvif = role->rtwvif; + struct rtw89_vif_link *rtwvif_link = role->rtwvif_link; u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval); - u64 sync_tsf = READ_ONCE(rtwvif->sync_bcn_tsf); + u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); u32 remainder; if (tsf < sync_tsf) { @@ -413,8 +413,8 @@ static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux int ret; req.group = mcc->group; - req.macid_x = ref->rtwvif->mac_id; - req.macid_y = aux->rtwvif->mac_id; + req.macid_x = ref->rtwvif_link->mac_id; + req.macid_y = aux->rtwvif_link->mac_id; ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt); if (ret) { rtw89_debug(rtwdev, RTW89_DBG_CHAN, @@ -440,10 +440,10 @@ static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES); arg.num = 2; - arg.infos[0].band = ref->rtwvif->mac_idx; - arg.infos[0].port = ref->rtwvif->port; - arg.infos[1].band = aux->rtwvif->mac_idx; - arg.infos[1].port = aux->rtwvif->port; + arg.infos[0].band = ref->rtwvif_link->mac_idx; + arg.infos[0].port = ref->rtwvif_link->port; + arg.infos[1].band = aux->rtwvif_link->mac_idx; + arg.infos[1].port = aux->rtwvif_link->port; ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt); if (ret) { @@ -523,11 +523,11 @@ u32 rtw89_mcc_role_fw_macid_bitmap_to_u32(struct rtw89_mcc_role *mcc_role) static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_mcc_role *mcc_role = data; - struct rtw89_vif *target = mcc_role->rtwvif; + struct rtw89_vif_link *target = mcc_role->rtwvif_link; - if (rtwvif != target) + if (rtwvif_link != target) return; rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta->mac_id); @@ -536,9 +536,9 @@ static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta) static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *mcc_role) { - struct rtw89_vif *rtwvif = mcc_role->rtwvif; + struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; - rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif->mac_id); + rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id); ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_mcc_role_macid_sta_iter, mcc_role); @@ -564,7 +564,7 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev, static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *mcc_role) { - struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif_link); struct ieee80211_p2p_noa_desc *noa_desc; u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval); u32 max_toa_us, max_tob_us, max_dur_us; @@ -597,7 +597,7 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, return; } - ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif, &tsf); + ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif_link, &tsf); if (ret) { rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret); return; @@ -632,14 +632,14 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, } static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_mcc_role *role) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chan *chan; memset(role, 0, sizeof(*role)); - role->rtwvif = rtwvif; + role->rtwvif_link = rtwvif_link; role->beacon_interval = vif->bss_conf.beacon_int; if (!role->beacon_interval) { @@ -650,10 +650,10 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev, role->duration = role->beacon_interval / 2; - chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); role->is_2ghz = chan->band_type == RTW89_BAND_2G; - role->is_go = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_GO; - role->is_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; + role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO; + role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; rtw89_mcc_fill_role_macid_bitmap(rtwdev, role); rtw89_mcc_fill_role_policy(rtwdev, role); @@ -678,7 +678,7 @@ static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev) } struct rtw89_mcc_fill_role_selector { - struct rtw89_vif *bind_vif[NUM_OF_RTW89_CHANCTX]; + struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX]; }; static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES); @@ -689,7 +689,7 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev, void *data) { struct rtw89_mcc_fill_role_selector *sel = data; - struct rtw89_vif *role_vif = sel->bind_vif[ordered_idx]; + struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx]; int ret; if (!role_vif) { @@ -712,21 +712,21 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev, static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev) { struct rtw89_mcc_fill_role_selector sel = {}; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; int ret; - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - if (!rtwvif->chanctx_assigned) + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + if (!rtwvif_link->chanctx_assigned) continue; - if (sel.bind_vif[rtwvif->chanctx_idx]) { + if (sel.bind_vif[rtwvif_link->chanctx_idx]) { rtw89_warn(rtwdev, "MCC skip extra vif on chanctx[%d]\n", - rtwvif->mac_id, rtwvif->chanctx_idx); + rtwvif_link->mac_id, rtwvif_link->chanctx_idx); continue; } - sel.bind_vif[rtwvif->chanctx_idx] = rtwvif; + sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link; } ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel); @@ -754,13 +754,13 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev, memset(&pattern->courtesy, 0, sizeof(pattern->courtesy)); if (pattern->tob_aux <= 0 || pattern->toa_aux <= 0) { - pattern->courtesy.macid_tgt = aux->rtwvif->mac_id; - pattern->courtesy.macid_src = ref->rtwvif->mac_id; + pattern->courtesy.macid_tgt = aux->rtwvif_link->mac_id; + pattern->courtesy.macid_src = ref->rtwvif_link->mac_id; pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; pattern->courtesy.enable = true; } else if (pattern->tob_ref <= 0 || pattern->toa_ref <= 0) { - pattern->courtesy.macid_tgt = ref->rtwvif->mac_id; - pattern->courtesy.macid_src = aux->rtwvif->mac_id; + pattern->courtesy.macid_tgt = ref->rtwvif_link->mac_id; + pattern->courtesy.macid_src = aux->rtwvif_link->mac_id; pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT; pattern->courtesy.enable = true; } @@ -1263,7 +1263,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev, u64 tsf_src; int ret; - ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif, &tsf_src); + ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif_link, &tsf_src); if (ret) { rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret); return; @@ -1280,12 +1280,12 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev, div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder); tsf_ofst_tgt = bcn_intvl_src_us - remainder; - config->sync.macid_tgt = tgt->rtwvif->mac_id; - config->sync.band_tgt = tgt->rtwvif->mac_idx; - config->sync.port_tgt = tgt->rtwvif->port; - config->sync.macid_src = src->rtwvif->mac_id; - config->sync.band_src = src->rtwvif->mac_idx; - config->sync.port_src = src->rtwvif->port; + config->sync.macid_tgt = tgt->rtwvif_link->mac_id; + config->sync.band_tgt = tgt->rtwvif_link->mac_idx; + config->sync.port_tgt = tgt->rtwvif_link->port; + config->sync.macid_src = src->rtwvif_link->mac_id; + config->sync.band_src = src->rtwvif_link->mac_idx; + config->sync.port_src = src->rtwvif_link->port; config->sync.offset = tsf_ofst_tgt / 1024; config->sync.enable = true; @@ -1294,7 +1294,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev, config->sync.macid_tgt, config->sync.macid_src, config->sync.offset); - rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif, src->rtwvif, + rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif_link, src->rtwvif_link, config->sync.offset); } @@ -1305,13 +1305,13 @@ static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev) struct rtw89_mcc_config *config = &mcc->config; u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval); u32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref); - struct rtw89_vif *rtwvif = ref->rtwvif; + struct rtw89_vif_link *rtwvif_link = ref->rtwvif_link; u64 tsf, start_tsf; u32 cur_tbtt_ofst; u64 min_time; int ret; - ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf); + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); if (ret) { rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret); return ret; @@ -1390,13 +1390,13 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro const struct rtw89_chan *chan; int ret; - chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx); + chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); req.central_ch_seg0 = chan->channel; req.primary_ch = chan->primary_channel; req.bandwidth = chan->band_width; req.ch_band_type = chan->band_type; - req.macid = role->rtwvif->mac_id; + req.macid = role->rtwvif_link->mac_id; req.group = mcc->group; req.c2h_rpt = policy->c2h_rpt; req.tx_null_early = policy->tx_null_early; @@ -1421,7 +1421,7 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro } ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, - role->rtwvif->mac_id, + role->rtwvif_link->mac_id, role->macid_bitmap); if (ret) { rtw89_debug(rtwdev, RTW89_DBG_CHAN, @@ -1448,7 +1448,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role, slot_arg->duration = role->duration; slot_arg->role_num = 1; - chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx); + chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx); slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI; slot_arg->roles[0].is_master = role == ref; @@ -1458,7 +1458,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role, slot_arg->roles[0].primary_ch = chan->primary_channel; slot_arg->roles[0].en_tx_null = !policy->dis_tx_null; slot_arg->roles[0].null_early = policy->tx_null_early; - slot_arg->roles[0].macid = role->rtwvif->mac_id; + slot_arg->roles[0].macid = role->rtwvif_link->mac_id; slot_arg->roles[0].macid_main_bitmap = rtw89_mcc_role_fw_macid_bitmap_to_u32(role); } @@ -1569,7 +1569,7 @@ static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace) } } - req.macid = ref->rtwvif->mac_id; + req.macid = ref->rtwvif_link->mac_id; req.tsf_high = config->start_tsf >> 32; req.tsf_low = config->start_tsf; @@ -1598,7 +1598,7 @@ static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev, if (!courtesy->enable) return; - if (courtesy->macid_src == ref->rtwvif->mac_id) { + if (courtesy->macid_src == ref->rtwvif_link->mac_id) { slot_arg_src = &arg->slots[ref->slot_idx]; slot_idx_tgt = aux->slot_idx; } else { @@ -1717,9 +1717,9 @@ static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_chang struct rtw89_fw_mcc_duration req = { .group = mcc->group, .btc_in_group = false, - .start_macid = ref->rtwvif->mac_id, - .macid_x = ref->rtwvif->mac_id, - .macid_y = aux->rtwvif->mac_id, + .start_macid = ref->rtwvif_link->mac_id, + .macid_x = ref->rtwvif_link->mac_id, + .macid_y = aux->rtwvif_link->mac_id, .duration_x = ref->duration, .duration_y = aux->duration, .start_tsf_high = config->start_tsf >> 32, @@ -1813,18 +1813,18 @@ static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable) struct ieee80211_p2p_noa_desc noa_desc = {}; u64 start_time = config->start_tsf; u32 interval = config->mcc_interval; - struct rtw89_vif *rtwvif_go; + struct rtw89_vif_link *rtwvif_go; u32 duration; if (mcc->mode != RTW89_MCC_MODE_GO_STA) return; if (ref->is_go) { - rtwvif_go = ref->rtwvif; + rtwvif_go = ref->rtwvif_link; start_time += ieee80211_tu_to_usec(ref->duration); duration = config->mcc_interval - ref->duration; } else if (aux->is_go) { - rtwvif_go = aux->rtwvif; + rtwvif_go = aux->rtwvif_link; start_time += ieee80211_tu_to_usec(pattern->tob_ref) + ieee80211_tu_to_usec(config->beacon_offset) + ieee80211_tu_to_usec(pattern->toa_aux); @@ -1865,9 +1865,9 @@ static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev) return; if (ref->is_go) - rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, true); + rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true); else if (aux->is_go) - rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, true); + rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true); rtw89_mcc_handle_beacon_noa(rtwdev, true); } @@ -1882,9 +1882,9 @@ static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev) return; if (ref->is_go) - rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, false); + rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false); else if (aux->is_go) - rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, false); + rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false); rtw89_mcc_handle_beacon_noa(rtwdev, false); } @@ -1942,7 +1942,7 @@ struct rtw89_mcc_stop_sel { static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel, const struct rtw89_mcc_role *mcc_role) { - sel->mac_id = mcc_role->rtwvif->mac_id; + sel->mac_id = mcc_role->rtwvif_link->mac_id; sel->slot_idx = mcc_role->slot_idx; } @@ -1953,7 +1953,7 @@ static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev, { struct rtw89_mcc_stop_sel *sel = data; - if (!mcc_role->rtwvif->chanctx_assigned) + if (!mcc_role->rtwvif_link->chanctx_assigned) return 0; rtw89_mcc_stop_sel_fill(sel, mcc_role); @@ -2081,7 +2081,7 @@ static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev, int ret; ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group, - upd->rtwvif->mac_id, + upd->rtwvif_link->mac_id, upd->macid_bitmap); if (ret) { rtw89_debug(rtwdev, RTW89_DBG_CHAN, @@ -2106,7 +2106,7 @@ static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev, int i; arg.sch_idx = mcc->group; - arg.macid = upd->rtwvif->mac_id; + arg.macid = upd->rtwvif_link->mac_id; for (i = 0; i < 32; i++) { if (add & BIT(i)) { @@ -2144,7 +2144,7 @@ static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev, void *data) { struct rtw89_mcc_role upd = { - .rtwvif = mcc_role->rtwvif, + .rtwvif_link = mcc_role->rtwvif_link, }; int ret; @@ -2375,7 +2375,7 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx idx2) { struct rtw89_hal *hal = &rtwdev->hal; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; u8 cur; if (idx1 == idx2) @@ -2386,13 +2386,13 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, swap(hal->chanctx[idx1], hal->chanctx[idx2]); - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - if (!rtwvif->chanctx_assigned) + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + if (!rtwvif_link->chanctx_assigned) continue; - if (rtwvif->chanctx_idx == idx1) - rtwvif->chanctx_idx = idx2; - else if (rtwvif->chanctx_idx == idx2) - rtwvif->chanctx_idx = idx1; + if (rtwvif_link->chanctx_idx == idx1) + rtwvif_link->chanctx_idx = idx2; + else if (rtwvif_link->chanctx_idx == idx2) + rtwvif_link->chanctx_idx = idx1; } cur = atomic_read(&hal->roc_chanctx_idx); @@ -2444,14 +2444,14 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, } int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_chanctx_conf *ctx) { struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; struct rtw89_entity_weight w = {}; - rtwvif->chanctx_idx = cfg->idx; - rtwvif->chanctx_assigned = true; + rtwvif_link->chanctx_idx = cfg->idx; + rtwvif_link->chanctx_assigned = true; cfg->ref_count++; if (cfg->idx == RTW89_CHANCTX_0) @@ -2469,7 +2469,7 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, } void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_chanctx_conf *ctx) { struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; @@ -2479,8 +2479,8 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, enum rtw89_entity_mode new; int ret; - rtwvif->chanctx_idx = RTW89_CHANCTX_0; - rtwvif->chanctx_assigned = false; + rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; + rtwvif_link->chanctx_assigned = false; cfg->ref_count--; if (cfg->ref_count != 0) diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h index c6d31984e575..4ed777ea5064 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.h +++ b/drivers/net/wireless/realtek/rtw89/chan.h @@ -106,10 +106,10 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, struct ieee80211_chanctx_conf *ctx, u32 changed); int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_chanctx_conf *ctx); void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_chanctx_conf *ctx); #endif diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index df51b29142aa..af9f975983ae 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4995,12 +4995,12 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) struct rtw89_txtime_data *iter_data = (struct rtw89_txtime_data *)data; struct rtw89_dev *rtwdev = iter_data->rtwdev; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; struct rtw89_btc_wl_link_info *plink = NULL; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u32 tx_time = iter_data->tx_time; u8 tx_retry = iter_data->tx_retry; u16 enable = iter_data->enable; @@ -7479,12 +7479,13 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); } -void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, enum btc_role_state state) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; @@ -7497,7 +7498,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], role is STA=%d\n", vif->type == NL80211_IFTYPE_STATION); - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif_link->port); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n", chan->band_type, chan->channel, chan->band_width); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n", @@ -7525,15 +7526,15 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif r.mode = mode; } - if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) + if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) return; rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], wifi_role=%d\n", rtwvif->wifi_role); + "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role); - r.role = rtwvif->wifi_role; - r.phy = rtwvif->phy_idx; - r.pid = rtwvif->port; + r.role = rtwvif_link->wifi_role; + r.phy = rtwvif_link->phy_idx; + r.pid = rtwvif_link->port; r.active = true; r.connected = MLME_LINKED; r.bcn_period = vif->bss_conf.beacon_int; @@ -7545,7 +7546,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif r.chdef.center_ch = chan->channel; r.chdef.bw = chan->band_width; r.chdef.chan = chan->primary_channel; - ether_addr_copy(r.mac_addr, rtwvif->mac_addr); + ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr); if (rtwsta && vif->type == NL80211_IFTYPE_STATION) r.mac_id = rtwsta->mac_id; @@ -7791,14 +7792,14 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) struct rtw89_btc_wl_link_info *link_info = NULL; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; struct rtw89_traffic_stats *link_info_t = NULL; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_traffic_stats *stats = &rtwvif->stats; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_traffic_stats *stats = &rtwvif_link->stats; const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc_wl_role_info *r; struct rtw89_btc_wl_role_info_v1 *r1; u32 last_tx_rate, last_rx_rate; u16 last_tx_lvl, last_rx_lvl; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u8 rssi; u8 busy = 0; u8 dir = 0; @@ -7810,7 +7811,7 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); link_info = &wl->link_info[port]; - link_info->stat.traffic = rtwvif->stats; + link_info->stat.traffic = rtwvif_link->stats; link_info_t = &link_info->stat.traffic; if (link_info->connected == MLME_NO_LINK) { diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h index de53b56632f7..2a3bd1ead7c3 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.h +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -271,7 +271,8 @@ void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work); void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work); void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work); void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work); -void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, enum btc_role_state state); void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 4553810634c6..314c2e2ef8e9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -436,12 +436,12 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev) return 0; } -void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_chan *chan) { const struct cfg80211_chan_def *chandef; - chandef = rtw89_chandef_get(rtwdev, rtwvif->chanctx_idx); + chandef = rtw89_chandef_get(rtwdev, rtwvif_link->chanctx_idx); rtw89_get_channel_params(chandef, chan); } @@ -591,12 +591,12 @@ static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_sta *sta = tx_req->sta; struct rtw89_sta *rtwsta; if (!sta) - return rtwvif->mac_id; + return rtwvif_link->mac_id; rtwsta = (struct rtw89_sta *)sta->drv_priv; return rtwsta->mac_id; @@ -619,10 +619,10 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, { const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); struct sk_buff *skb = tx_req->skb; u8 qsel, ch_dma; @@ -631,7 +631,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, desc_info->qsel = qsel; desc_info->ch_dma = ch_dma; - desc_info->port = desc_info->hiq ? rtwvif->port : 0; + desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL; desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE; @@ -762,7 +762,7 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, { struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) goto desc_bk; @@ -773,10 +773,10 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, desc_info->a_ctrl_bsr = true; desc_bk: - if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr) + if (!rtwvif_link || rtwvif_link->last_a_ctrl == desc_info->a_ctrl_bsr) return; - rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr; + rtwvif_link->last_a_ctrl = desc_info->a_ctrl_bsr; desc_info->bk = true; } @@ -785,9 +785,9 @@ static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, { struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; - enum rtw89_chanctx_idx idx = rtwvif->chanctx_idx; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; + enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); u16 lowest_rate; @@ -813,7 +813,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, { struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; @@ -829,7 +829,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, desc_info->tid_indicate = tid_indicate; desc_info->qsel = qsel; desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); - desc_info->port = desc_info->hiq ? rtwvif->port : 0; + desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; desc_info->er_cap = rtwsta ? rtwsta->er_cap : false; desc_info->stbc = rtwsta ? rtwsta->ra.stbc_cap : false; desc_info->ldpc = rtwsta ? rtwsta->ra.ldpc_cap : false; @@ -1028,7 +1028,7 @@ int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) { struct rtw89_core_tx_request tx_req = {0}; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; int ret; tx_req.skb = skb; @@ -1036,7 +1036,7 @@ int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, tx_req.vif = vif; rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true); - rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true); + rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, true); rtw89_core_tx_update_desc_info(rtwdev, &tx_req); rtw89_core_tx_wake(rtwdev, &tx_req); @@ -1879,14 +1879,14 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct sk_buff *skb) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data; u8 *pos, *end, type, tf_bw; u16 aid, tf_rua; if (!ether_addr_equal(vif->bss_conf.bssid, tf->ta) || - rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION || - rtwvif->net_type == RTW89_NET_TYPE_NO_LINK) + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION || + rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK) return; type = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_TYPE_MASK); @@ -1911,11 +1911,11 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, if (aid == vif->cfg.aid) { enum nl80211_he_ru_alloc rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1); - rtwvif->stats.rx_tf_acc++; + rtwvif_link->stats.rx_tf_acc++; rtwdev->stats.rx_tf_acc++; if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ && rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106) - rtwvif->pwr_diff_en = true; + rtwvif_link->pwr_diff_en = true; break; } @@ -1986,7 +1986,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work); } -static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif, +static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link, struct ieee80211_hdr *hdr, size_t len) { struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr; @@ -1994,13 +1994,13 @@ static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif, if (len < offsetof(typeof(*mgmt), u.beacon.variable)) return; - WRITE_ONCE(rtwvif->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp)); + WRITE_ONCE(rtwvif_link->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp)); } static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_vif_rx_stats_iter_data *iter_data = data; struct rtw89_dev *rtwdev = iter_data->rtwdev; struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; @@ -2029,7 +2029,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, if (ieee80211_is_beacon(hdr->frame_control)) { if (vif->type == NL80211_IFTYPE_STATION && !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { - rtw89_vif_sync_bcn_tsf(rtwvif, hdr, skb->len); + rtw89_vif_sync_bcn_tsf(rtwvif_link, hdr, skb->len); rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu); } pkt_stat->beacon_nr++; @@ -2041,7 +2041,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, if (desc_info->data_rate < RTW89_HW_RATE_NR) pkt_stat->rx_rate_cnt[desc_info->data_rate]++; - rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false); + rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, false); } static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, @@ -2869,7 +2869,7 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv { struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_txq *txq; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; struct rtw89_txq *rtwtxq; unsigned long frame_cnt; unsigned long byte_cnt; @@ -2879,9 +2879,9 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv ieee80211_txq_schedule_start(hw, ac); while ((txq = ieee80211_next_txq(hw, ac))) { rtwtxq = (struct rtw89_txq *)txq->drv_priv; - rtwvif = (struct rtw89_vif *)txq->vif->drv_priv; + rtwvif_link = (struct rtw89_vif_link *)txq->vif->drv_priv; - if (rtwvif->offchan) { + if (rtwvif_link->offchan) { ieee80211_return_txq(hw, txq, true); continue; } @@ -2956,13 +2956,14 @@ static void rtw89_core_sta_pending_tx_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif_target = data, *rtwvif = rtwsta->rtwvif; - struct rtw89_dev *rtwdev = rtwvif->rtwdev; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_vif_link *rtwvif_target = data; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct sk_buff *skb, *tmp; int qsel, ret; - if (rtwvif->chanctx_idx != rtwvif_target->chanctx_idx) + if (rtwvif_link->chanctx_idx != rtwvif_target->chanctx_idx) return; if (skb_queue_len(&rtwsta->roc_queue) == 0) @@ -2982,17 +2983,17 @@ static void rtw89_core_sta_pending_tx_iter(void *data, } static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_core_sta_pending_tx_iter, - rtwvif); + rtwvif_link); } static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool qos, bool ps) + struct rtw89_vif_link *rtwvif_link, bool qos, bool ps) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct sk_buff *skb; @@ -3035,13 +3036,13 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, return ret; } -void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; - struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_roc *roc = &rtwvif_link->roc; struct cfg80211_chan_def roc_chan; - struct rtw89_vif *tmp; + struct rtw89_vif_link *tmp; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -3050,34 +3051,34 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) rtw89_leave_lps(rtwdev); rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC); - ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, true); + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true); if (ret) rtw89_debug(rtwdev, RTW89_DBG_TXRX, "roc send null-1 failed: %d\n", ret); rtw89_for_each_rtwvif(rtwdev, tmp) - if (tmp->chanctx_idx == rtwvif->chanctx_idx) + if (tmp->chanctx_idx == rtwvif_link->chanctx_idx) tmp->offchan = true; cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT); - rtw89_config_roc_chandef(rtwdev, rtwvif->chanctx_idx, &roc_chan); + rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, &roc_chan); rtw89_set_channel(rtwdev); rtw89_write32_clr(rtwdev, rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); ieee80211_ready_on_channel(hw); - cancel_delayed_work(&rtwvif->roc.roc_work); - ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work, - msecs_to_jiffies(rtwvif->roc.duration)); + cancel_delayed_work(&rtwvif_link->roc.roc_work); + ieee80211_queue_delayed_work(hw, &rtwvif_link->roc.roc_work, + msecs_to_jiffies(rtwvif_link->roc.duration)); } -void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; - struct rtw89_roc *roc = &rtwvif->roc; - struct rtw89_vif *tmp; + struct rtw89_roc *roc = &rtwvif_link->roc; + struct rtw89_vif_link *tmp; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -3093,18 +3094,18 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) rtwdev->hal.rx_fltr); roc->state = RTW89_ROC_IDLE; - rtw89_config_roc_chandef(rtwdev, rtwvif->chanctx_idx, NULL); + rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, NULL); rtw89_chanctx_proceed(rtwdev); - ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, false); + ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false); if (ret) rtw89_debug(rtwdev, RTW89_DBG_TXRX, "roc send null-0 failed: %d\n", ret); rtw89_for_each_rtwvif(rtwdev, tmp) - if (tmp->chanctx_idx == rtwvif->chanctx_idx) + if (tmp->chanctx_idx == rtwvif_link->chanctx_idx) tmp->offchan = false; - rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif); + rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif_link); queue_work(rtwdev->txq_wq, &rtwdev->txq_work); if (hw->conf.flags & IEEE80211_CONF_IDLE) @@ -3114,10 +3115,10 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) void rtw89_roc_work(struct work_struct *work) { - struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, - roc.roc_work.work); - struct rtw89_dev *rtwdev = rtwvif->rtwdev; - struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, + roc.roc_work.work); + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; + struct rtw89_roc *roc = &rtwvif_link->roc; mutex_lock(&rtwdev->mutex); @@ -3127,7 +3128,7 @@ void rtw89_roc_work(struct work_struct *work) break; case RTW89_ROC_MGMT: case RTW89_ROC_NORMAL: - rtw89_roc_end(rtwdev, rtwvif); + rtw89_roc_end(rtwdev, rtwvif_link); break; default: break; @@ -3188,39 +3189,40 @@ static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; bool tfc_changed; tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats); - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats); - rtw89_fw_h2c_tp_offload(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + rtw89_traffic_stats_calc(rtwdev, &rtwvif_link->stats); + rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link); } return tfc_changed; } -static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && - rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || - rtwvif->tdls_peer) + if ((rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || + rtwvif_link->tdls_peer) return; - if (rtwvif->offchan) + if (rtwvif_link->offchan) return; - if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && - rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) - rtw89_enter_lps(rtwdev, rtwvif, true); + if (rtwvif_link->stats.tx_tfc_lv == RTW89_TFC_IDLE && + rtwvif_link->stats.rx_tfc_lv == RTW89_TFC_IDLE) + rtw89_enter_lps(rtwdev, rtwvif_link, true); } static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_vif_enter_lps(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_vif_enter_lps(rtwdev, rtwvif_link); } static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev) @@ -3396,24 +3398,24 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, #define RTW89_TYPE_MAPPING(_type) \ case NL80211_IFTYPE_ ## _type: \ - rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ break void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; switch (vif->type) { case NL80211_IFTYPE_STATION: if (vif->p2p) - rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT; + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT; else - rtwvif->wifi_role = RTW89_WIFI_ROLE_STATION; + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_STATION; break; case NL80211_IFTYPE_AP: if (vif->p2p) - rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_GO; + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_GO; else - rtwvif->wifi_role = RTW89_WIFI_ROLE_AP; + rtwvif_link->wifi_role = RTW89_WIFI_ROLE_AP; break; RTW89_TYPE_MAPPING(ADHOC); RTW89_TYPE_MAPPING(MONITOR); @@ -3426,23 +3428,23 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: - rtwvif->net_type = RTW89_NET_TYPE_AP_MODE; - rtwvif->self_role = RTW89_SELF_ROLE_AP; + rtwvif_link->net_type = RTW89_NET_TYPE_AP_MODE; + rtwvif_link->self_role = RTW89_SELF_ROLE_AP; break; case NL80211_IFTYPE_ADHOC: - rtwvif->net_type = RTW89_NET_TYPE_AD_HOC; - rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; + rtwvif_link->net_type = RTW89_NET_TYPE_AD_HOC; + rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT; break; case NL80211_IFTYPE_STATION: if (assoc) { - rtwvif->net_type = RTW89_NET_TYPE_INFRA; - rtwvif->trigger = vif->bss_conf.he_support; + rtwvif_link->net_type = RTW89_NET_TYPE_INFRA; + rtwvif_link->trigger = vif->bss_conf.he_support; } else { - rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; - rtwvif->trigger = false; + rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; + rtwvif_link->trigger = false; } - rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; - rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; + rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT; + rtwvif_link->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; break; case NL80211_IFTYPE_MONITOR: break; @@ -3456,7 +3458,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; @@ -3464,7 +3466,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, int ret; rtwsta->rtwdev = rtwdev; - rtwsta->rtwvif = rtwvif; + rtwsta->rtwvif_link = rtwvif_link; rtwsta->prev_rssi = 0; INIT_LIST_HEAD(&rtwsta->ba_cam_list); skb_queue_head_init(&rtwsta->roc_queue); @@ -3483,16 +3485,16 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { /* for station mode, assign the mac_id from itself */ - rtwsta->mac_id = rtwvif->mac_id; + rtwsta->mac_id = rtwvif_link->mac_id; /* must do rtw89_reg_6ghz_recalc() before rfk channel */ - ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif, true); + ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); if (ret) return ret; - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, BTC_ROLE_MSTS_STA_CONN_START); - rtw89_chip_rfk_channel(rtwdev, rtwvif); + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { rtwsta->mac_id = rtw89_acquire_mac_id(rtwdev); if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) @@ -3505,7 +3507,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, RTW89_ROLE_CREATE); if (ret) { rtw89_release_mac_id(rtwdev, rtwsta->mac_id); @@ -3513,11 +3515,11 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta); + ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta); if (ret) return ret; - ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta); + ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta); if (ret) return ret; @@ -3531,7 +3533,7 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; if (vif->type == NL80211_IFTYPE_STATION) @@ -3539,7 +3541,7 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, rtwdev->total_sta_assoc--; if (sta->tdls) - rtwvif->tdls_peer--; + rtwvif_link->tdls_peer--; rtwsta->disassoc = true; return 0; @@ -3549,7 +3551,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; int ret; @@ -3566,7 +3568,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { rtw89_vif_type_mapping(vif, false); - rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true); + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true); } ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta); @@ -3575,14 +3577,14 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, true); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, true); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } /* update cam aid mac_id net_type */ - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; @@ -3595,16 +3597,18 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta); + struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, + rtwsta); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); int ret; if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { if (sta->tdls) { - ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, sta->addr); + ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam, + sta->addr); if (ret) { rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n"); return ret; @@ -3624,14 +3628,14 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, false); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, false); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } /* update cam aid mac_id net_type */ - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; @@ -3639,7 +3643,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, rtwdev->total_sta_assoc++; if (sta->tdls) - rtwvif->tdls_peer++; + rtwvif_link->tdls_peer++; rtw89_phy_ra_assoc(rtwdev, sta); rtw89_mac_bf_assoc(rtwdev, vif, sta); rtw89_mac_bf_monitor_calc(rtwdev, sta, false); @@ -3651,12 +3655,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) rtwsta->er_cap = true; - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, BTC_ROLE_MSTS_STA_CONN_END); rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template, chan); - rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); + rtw89_phy_ul_tb_assoc(rtwdev, rtwvif_link); - ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta->mac_id); if (ret) { rtw89_warn(rtwdev, "failed to send h2c general packet\n"); return ret; @@ -3672,18 +3676,18 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; int ret; if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - rtw89_reg_6ghz_recalc(rtwdev, rtwvif, false); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false); + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, BTC_ROLE_MSTS_STA_DIS_CONN); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { rtw89_release_mac_id(rtwdev, rtwsta->mac_id); - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, RTW89_ROLE_REMOVE); if (ret) { rtw89_warn(rtwdev, "failed to send h2c role info\n"); @@ -4152,15 +4156,15 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) void rtw89_core_update_beacon_work(struct work_struct *work) { struct rtw89_dev *rtwdev; - struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, - update_beacon_work); + struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, + update_beacon_work); - if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE) + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) return; - rtwdev = rtwvif->rtwdev; + rtwdev = rtwvif_link->rtwdev; mutex_lock(&rtwdev->mutex); - rtw89_chip_h2c_update_beacon(rtwdev, rtwvif); + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); mutex_unlock(&rtwdev->mutex); } @@ -4444,38 +4448,39 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev) } EXPORT_SYMBOL(rtw89_core_deinit); -void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, const u8 *mac_addr, bool hw_scan) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); rtwdev->scanning = true; rtw89_leave_lps(rtwdev); if (hw_scan) rtw89_leave_ips_by_hwflags(rtwdev); - ether_addr_copy(rtwvif->mac_addr, mac_addr); + ether_addr_copy(rtwvif_link->mac_addr, mac_addr); rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type); - rtw89_chip_rfk_scan(rtwdev, rtwvif, true); + rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true); rtw89_hci_recalc_int_mit(rtwdev); rtw89_phy_config_edcca(rtwdev, true); - rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr); } void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool hw_scan) { - struct rtw89_vif *rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; + struct rtw89_vif_link *rtwvif_link = + vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; - if (!rtwvif) + if (!rtwvif_link) return; - ether_addr_copy(rtwvif->mac_addr, vif->addr); - rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); + ether_addr_copy(rtwvif_link->mac_addr, vif->addr); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); - rtw89_chip_rfk_scan(rtwdev, rtwvif, false); + rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); rtw89_phy_config_edcca(rtwdev, false); @@ -4697,7 +4702,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) int ret; int tx_headroom = IEEE80211_HT_CTL_LEN; - hw->vif_data_size = sizeof(struct rtw89_vif); + hw->vif_data_size = sizeof(struct rtw89_vif_link); hw->sta_data_size = sizeof(struct rtw89_sta); hw->txq_data_size = sizeof(struct rtw89_txq); hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 64b7fd1f6079..21e0099d6324 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3359,7 +3359,7 @@ struct rtw89_sta { bool disassoc; bool er_cap; struct rtw89_dev *rtwdev; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; struct rtw89_ra_info ra; struct rtw89_ra_report ra_report; int max_agg_wait; @@ -3460,7 +3460,7 @@ struct rtw89_p2p_noa_setter { u8 noa_index; }; -struct rtw89_vif { +struct rtw89_vif_link { struct list_head list; struct rtw89_dev *rtwdev; struct rtw89_roc roc; @@ -3599,11 +3599,11 @@ struct rtw89_chip_ops { void (*rfk_hw_init)(struct rtw89_dev *rtwdev); void (*rfk_init)(struct rtw89_dev *rtwdev); void (*rfk_init_late)(struct rtw89_dev *rtwdev); - void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void (*rfk_band_changed)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan); - void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool start); void (*rfk_track)(struct rtw89_dev *rtwdev); void (*power_trim)(struct rtw89_dev *rtwdev); @@ -3646,10 +3646,10 @@ struct rtw89_chip_ops { u32 *tx_en, enum rtw89_sch_tx_sel sel); int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, @@ -3658,10 +3658,10 @@ struct rtw89_chip_ops { struct ieee80211_vif *vif, struct ieee80211_sta *sta); int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int (*h2c_update_beacon)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); + struct rtw89_vif_link *rtwvif_link); int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params); @@ -5409,7 +5409,7 @@ struct rtw89_mcc_policy { }; struct rtw89_mcc_role { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; struct rtw89_mcc_policy policy; struct rtw89_mcc_limit limit; @@ -5961,21 +5961,21 @@ static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, INIT_LIST_HEAD(&rtwtxq->list); } -static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) +static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif_link *rtwvif_link) { - void *p = rtwvif; + void *p = rtwvif_link; return container_of(p, struct ieee80211_vif, drv_priv); } -static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif) +static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif_link *rtwvif_link) { - return rtwvif ? rtwvif_to_vif(rtwvif) : NULL; + return rtwvif_link ? rtwvif_to_vif(rtwvif_link) : NULL; } -static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif) +static inline struct rtw89_vif_link *vif_to_rtwvif_safe(struct ieee80211_vif *vif) { - return vif ? (struct rtw89_vif *)vif->drv_priv : NULL; + return vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; } static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) @@ -6079,20 +6079,20 @@ enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua) } static inline -struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif, +struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { if (rtwsta) { struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) return &rtwsta->addr_cam; } - return &rtwvif->addr_cam; + return &rtwvif_link->addr_cam; } static inline -struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif *rtwvif, +struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { if (rtwsta) { @@ -6101,7 +6101,7 @@ struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif *rtwvif, if (sta->tdls) return &rtwsta->bssid_cam; } - return &rtwvif->bssid_cam; + return &rtwvif_link->bssid_cam; } static inline @@ -6161,10 +6161,10 @@ static inline const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev) { struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - if (rtwvif) - return rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); + if (rtwvif_link) + return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); else return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); } @@ -6241,12 +6241,12 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev) } static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->ops->rfk_channel) - chip->ops->rfk_channel(rtwdev, rtwvif); + chip->ops->rfk_channel(rtwdev, rtwvif_link); } static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev, @@ -6260,12 +6260,12 @@ static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev, } static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool start) + struct rtw89_vif_link *rtwvif_link, bool start) { const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->ops->rfk_scan) - chip->ops->rfk_scan(rtwdev, rtwvif, start); + chip->ops->rfk_scan(rtwdev, rtwvif_link, start); } static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev) @@ -6352,14 +6352,14 @@ static inline void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chip_info *chip = rtwdev->chip; if (!vif->bss_conf.he_support || !vif->cfg.assoc) return; if (chip->ops->set_txpwr_ul_tb_offset) - chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx); + chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx); } static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev, @@ -6458,14 +6458,14 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) static inline int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { const struct rtw89_chip_info *chip = rtwdev->chip; if (!chip->ops->h2c_dctl_sec_cam) return 0; - return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); + return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta); } static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) @@ -6641,7 +6641,7 @@ void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef); void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef, struct rtw89_chan *chan); int rtw89_set_channel(struct rtw89_dev *rtwdev); -void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_chan *chan); u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); @@ -6666,13 +6666,13 @@ int rtw89_core_start(struct rtw89_dev *rtwdev); void rtw89_core_stop(struct rtw89_dev *rtwdev); void rtw89_core_update_beacon_work(struct work_struct *work); void rtw89_roc_work(struct work_struct *work); -void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, const u8 *mac_addr, bool hw_scan); void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool hw_scan); -int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active); void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event); diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 29f85210f919..26327e4b071d 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3740,21 +3740,22 @@ static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_lis static void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct seq_file *m = (struct seq_file *)data; - struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; + struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; - seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr); + seq_printf(m, "VIF [%d] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr); seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); - rtw89_dump_addr_cam(m, rtwdev, &rtwvif->addr_cam); - rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: "); + rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam); + rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list, + "\tpkt_ofld[GENERAL]: "); } static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) { - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct rtw89_ba_cam_entry *entry; bool first = true; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 93a338bbf59c..5284dcecef85 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1742,7 +1742,7 @@ void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) } #define H2C_CAM_LEN 60 -int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, const u8 *scan_mac_addr) { struct sk_buff *skb; @@ -1754,8 +1754,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, return -ENOMEM; } skb_put(skb, H2C_CAM_LEN); - rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data); - rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data); + rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta, scan_mac_addr, + skb->data); + rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta, skb->data); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1777,7 +1778,7 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, } int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { struct rtw89_h2c_dctlinfo_ud_v1 *h2c; @@ -1793,7 +1794,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data; - rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, h2c); + rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta, h2c); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1816,7 +1817,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { struct rtw89_h2c_dctlinfo_ud_v2 *h2c; @@ -1832,7 +1833,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; - rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif, rtwsta, h2c); + rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta, h2c); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1855,10 +1856,10 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_dctlinfo_ud_v2 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -1913,7 +1914,7 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_h2c_ba_cam *h2c; u8 macid = rtwsta->mac_id; u32 len = sizeof(*h2c); @@ -1961,7 +1962,8 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) | - le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BA_CAM_W1_BAND); + le32_encode_bits(rtwvif_link->mac_idx, + RTW89_H2C_BA_CAM_W1_BAND); } end: @@ -2044,7 +2046,7 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_h2c_ba_cam_v1 *h2c; u8 macid = rtwsta->mac_id; u32 len = sizeof(*h2c); @@ -2093,7 +2095,8 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */ h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) | le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) | - le32_encode_bits(!!rtwvif->mac_idx, RTW89_H2C_BA_CAM_V1_W1_BAND_SEL); + le32_encode_bits(!!rtwvif_link->mac_idx, + RTW89_H2C_BA_CAM_V1_W1_BAND_SEL); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -2198,11 +2201,11 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) } static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03}; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; @@ -2242,9 +2245,9 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, } static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); struct ieee80211_hdr_3addr *hdr; @@ -2273,7 +2276,7 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, } static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; @@ -2296,9 +2299,9 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS); hdr->frame_control = fc; - ether_addr_copy(hdr->addr1, rtwvif->bssid); - ether_addr_copy(hdr->addr2, rtwvif->mac_addr); - ether_addr_copy(hdr->addr3, rtwvif->bssid); + ether_addr_copy(hdr->addr1, rtwvif_link->bssid); + ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr); + ether_addr_copy(hdr->addr3, rtwvif_link->bssid); skb_put_zero(skb, sec_hdr_len); @@ -2313,18 +2316,18 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, arp_hdr->ar_pln = 4; arp_hdr->ar_op = htons(ARPOP_REPLY); - ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr); - arp_skb->sender_ip = rtwvif->ip_addr; + ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr); + arp_skb->sender_ip = rtwvif_link->ip_addr; return skb; } static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, enum rtw89_fw_pkt_ofld_type type, u8 *id) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_pktofld_info *info; struct sk_buff *skb; int ret; @@ -2347,13 +2350,13 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true); break; case RTW89_PKT_OFLD_TYPE_EAPOL_KEY: - skb = rtw89_eapol_get(rtwdev, rtwvif); + skb = rtw89_eapol_get(rtwdev, rtwvif_link); break; case RTW89_PKT_OFLD_TYPE_SA_QUERY: - skb = rtw89_sa_query_get(rtwdev, rtwvif); + skb = rtw89_sa_query_get(rtwdev, rtwvif_link); break; case RTW89_PKT_OFLD_TYPE_ARP_RSP: - skb = rtw89_arp_response_get(rtwdev, rtwvif); + skb = rtw89_arp_response_get(rtwdev, rtwvif_link); break; default: goto err; @@ -2368,7 +2371,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, if (ret) goto err; - list_add_tail(&info->list, &rtwvif->general_pkt_list); + list_add_tail(&info->list, &rtwvif_link->general_pkt_list); *id = info->id; return 0; @@ -2378,9 +2381,10 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, } void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool notify_fw) + struct rtw89_vif_link *rtwvif_link, + bool notify_fw) { - struct list_head *pkt_list = &rtwvif->general_pkt_list; + struct list_head *pkt_list = &rtwvif_link->general_pkt_list; struct rtw89_pktofld_info *info, *tmp; list_for_each_entry_safe(info, tmp, pkt_list, list) { @@ -2395,16 +2399,16 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, notify_fw); } #define H2C_GENERAL_PKT_LEN 6 #define H2C_GENERAL_PKT_ID_UND 0xff int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u8 macid) + struct rtw89_vif_link *rtwvif_link, u8 macid) { u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; @@ -2412,11 +2416,11 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct sk_buff *skb; int ret; - rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); - rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); - rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); @@ -2495,10 +2499,10 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, return ret; } -int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_h2c_lps_ch_info *h2c; u32 len = sizeof(*h2c); @@ -2551,8 +2555,8 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_p2p_noa_desc *desc, u8 act, u8 noa_id) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; struct sk_buff *skb; u8 *cmd; @@ -2566,7 +2570,7 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, skb_put(skb, H2C_P2P_ACT_LEN); cmd = skb->data; - RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id); + RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id); RTW89_SET_FWCMD_P2P_P2PID(cmd, 0); RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id); RTW89_SET_FWCMD_P2P_ACT(cmd, act); @@ -2623,11 +2627,11 @@ static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, #define H2C_CMC_TBL_LEN 68 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { const struct rtw89_chip_info *chip = rtwdev->chip; - u8 macid = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + u8 macid = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; struct sk_buff *skb; int ret; @@ -2649,7 +2653,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, } SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) SET_CMC_TBL_DATA_DCM(skb->data, 0); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -2672,10 +2676,10 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl); int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -2815,12 +2819,12 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, { const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); struct sk_buff *skb; u8 pads[RTW89_PPE_BW_NUM]; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; u16 lowest_rate; int ret; @@ -2852,7 +2856,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, SET_CMC_TBL_ULDL(skb->data, 1); else SET_CMC_TBL_ULDL(skb->data, 0); - SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); + SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port); if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) { SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); @@ -2867,7 +2871,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, if (sta) SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->deflink.he_cap.has_he); - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) SET_CMC_TBL_DATA_DCM(skb->data, 0); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -2950,10 +2954,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u8 pads[RTW89_PPE_BW_NUM]; u32 len = sizeof(*h2c); @@ -3001,10 +3005,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL); - h2c->w4 = le32_encode_bits(rtwvif->port, CCTLINFO_G7_W4_MULTI_PORT_ID); + h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID); h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID); - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) { + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM); h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM); } @@ -3210,11 +3214,11 @@ int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, } int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_h2c_bcn_upd *h2c; struct sk_buff *skb_beacon; struct ieee80211_hdr *hdr; @@ -3241,7 +3245,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, return -ENOMEM; } - noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data); + noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); if (noa_len && (noa_len <= skb_tailroom(skb_beacon) || pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { @@ -3261,11 +3265,11 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_bcn_upd *)skb->data; - h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_W0_PORT) | + h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) | le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) | - le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) | le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST); - h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) | + h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) | le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) | le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) | le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE); @@ -3290,10 +3294,10 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon); int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_h2c_bcn_upd_be *h2c; struct sk_buff *skb_beacon; struct ieee80211_hdr *hdr; @@ -3320,7 +3324,7 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, return -ENOMEM; } - noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data); + noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data); if (noa_len && (noa_len <= skb_tailroom(skb_beacon) || pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) { @@ -3340,11 +3344,11 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data; - h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) | + h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) | le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) | - le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) | le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST); - h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) | + h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) | le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) | le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) | le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE); @@ -3374,22 +3378,22 @@ EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be); #define H2C_ROLE_MAINTAIN_LEN 4 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, enum rtw89_upd_mode upd_mode) { struct sk_buff *skb; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; u8 self_role; int ret; - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) { + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { if (rtwsta) self_role = RTW89_SELF_ROLE_AP_CLIENT; else - self_role = rtwvif->self_role; + self_role = rtwvif_link->self_role; } else { - self_role = rtwvif->self_role; + self_role = rtwvif_link->self_role; } skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN); @@ -3401,7 +3405,7 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id); SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role); SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode); - SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role); + SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif_link->wifi_role); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, @@ -3422,11 +3426,11 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, } static enum rtw89_fw_sta_type -rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); if (!sta) goto by_vif; @@ -3447,14 +3451,14 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, return RTW89_FW_N_AC_STA; } -int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, bool dis_conn) { struct sk_buff *skb; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; - u8 self_role = rtwvif->self_role; + u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 self_role = rtwvif_link->self_role; enum rtw89_fw_sta_type sta_type; - u8 net_type = rtwvif->net_type; + u8 net_type = rtwvif_link->net_type; struct rtw89_h2c_join_v1 *h2c_v1; struct rtw89_h2c_join *h2c; u32 len = sizeof(*h2c); @@ -3481,16 +3485,17 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) | le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) | - le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_JOININFO_W0_BAND) | - le32_encode_bits(rtwvif->wmm, RTW89_H2C_JOININFO_W0_WMM) | - le32_encode_bits(rtwvif->trigger, RTW89_H2C_JOININFO_W0_TGR) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) | + le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) | + le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) | le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) | le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) | le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) | le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) | - le32_encode_bits(rtwvif->port, RTW89_H2C_JOININFO_W0_PORT_ID) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) | le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) | - le32_encode_bits(rtwvif->wifi_role, RTW89_H2C_JOININFO_W0_WIFI_ROLE) | + le32_encode_bits(rtwvif_link->wifi_role, + RTW89_H2C_JOININFO_W0_WIFI_ROLE) | le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE); if (!format_v1) @@ -3498,7 +3503,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data; - sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif, rtwsta); + sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta); h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE); h2c_v1->w2 = 0; @@ -3619,7 +3624,7 @@ int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, } #define H2C_EDCA_LEN 12 -int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u8 ac, u32 val) { struct sk_buff *skb; @@ -3632,7 +3637,7 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, } skb_put(skb, H2C_EDCA_LEN); RTW89_SET_EDCA_SEL(skb->data, 0); - RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx); + RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx); RTW89_SET_EDCA_WMM(skb->data, 0); RTW89_SET_EDCA_AC(skb->data, ac); RTW89_SET_EDCA_PARAM(skb->data, val); @@ -3656,7 +3661,8 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, } #define H2C_TSF32_TOGL_LEN 4 -int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en) { struct sk_buff *skb; @@ -3672,9 +3678,9 @@ int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif skb_put(skb, H2C_TSF32_TOGL_LEN); cmd = skb->data; - RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx); + RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx); RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en); - RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port); + RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port); RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -3731,7 +3737,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool connect) { - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL; s32 thold = RTW89_DEFAULT_CQM_THOLD; u32 hyst = RTW89_DEFAULT_CQM_HYST; @@ -3743,7 +3749,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) return -EINVAL; - if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA) + if (!rtwvif_link || !bss_conf || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) return -EINVAL; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); @@ -3769,7 +3775,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | le32_encode_bits(thold + MAX_RSSI, RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | - le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, @@ -3834,15 +3840,15 @@ int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, return ret; } -int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct rtw89_traffic_stats *stats = &rtwvif->stats; + struct rtw89_traffic_stats *stats = &rtwvif_link->stats; struct rtw89_h2c_ofld *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; int ret; - if (rtwvif->net_type != RTW89_NET_TYPE_INFRA) + if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) return -EINVAL; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); @@ -3854,7 +3860,7 @@ int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) skb_put(skb, len); h2c = (struct rtw89_h2c_ofld *)skb->data; - h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); @@ -4859,7 +4865,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, #define RTW89_SCAN_DELAY_TSF_UNIT 104800 int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool wowlan) { struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; @@ -4881,7 +4887,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, h2c = (struct rtw89_h2c_scanofld *)skb->data; if (option->delay) { - ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf); + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); if (ret) { rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret); scan_mode = RTW89_SCAN_IMMEDIATE; @@ -4891,8 +4897,8 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, } } - h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | - le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) | le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); @@ -4964,12 +4970,12 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool wowlan) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct rtw89_h2c_scanofld_be_macc_role *macc_role; struct rtw89_chan *op = &scan_info->op_chan; struct rtw89_h2c_scanofld_be_opch *opch; @@ -5017,8 +5023,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) | le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) | le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) | - le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) | - le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) | + le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) | le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND); h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) | @@ -5083,11 +5089,11 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, for (i = 0; i < option->num_opch; i++) { opch = ptr; - opch->w0 = le32_encode_bits(rtwvif->mac_id, + opch->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) | le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) | - le32_encode_bits(rtwvif->port, + le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) | le32_encode_bits(RTW89_SCAN_OPMODE_INTV, RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) | @@ -5886,11 +5892,11 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) } static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_pktofld_info *info, enum nl80211_band band, u8 ssid_idx) { - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; if (band != NL80211_BAND_6GHZ) return false; @@ -5907,11 +5913,11 @@ static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, } static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct sk_buff *skb, u8 ssid_idx) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct ieee80211_scan_ies *ies = rtwvif_link->scan_ies; struct rtw89_pktofld_info *info; struct sk_buff *new; int ret = 0; @@ -5936,7 +5942,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, goto out; } - rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band, + rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif_link, info, band, ssid_idx); ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); @@ -5954,22 +5960,22 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, } static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct sk_buff *skb; u8 num = req->n_ssids, i; int ret; for (i = 0; i < num; i++) { - skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, req->ssids[i].ssid, req->ssids[i].ssid_len, req->ie_len); if (!skb) return -ENOMEM; - ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i); + ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i); kfree_skb(skb); if (ret) @@ -5985,8 +5991,8 @@ static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, { struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; struct list_head *pkt_list = rtwdev->scan_info.pkt_list; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); - struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct ieee80211_scan_ies *ies = rtwvif_link->scan_ies; struct cfg80211_scan_6ghz_params *params; struct rtw89_pktofld_info *info, *tmp; struct ieee80211_hdr *hdr; @@ -6015,7 +6021,7 @@ static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, if (found) continue; - skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, NULL, 0, req->ie_len); skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); skb_put_data(skb, ies->common_ies, ies->common_ie_len); @@ -6106,8 +6112,8 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct rtw89_chan *op = &rtwdev->scan_info.op_chan; struct rtw89_pktofld_info *info; u8 band, probe_count = 0; @@ -6223,8 +6229,8 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct rtw89_pktofld_info *info; u8 band, probe_count = 0, i; @@ -6280,7 +6286,7 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, } int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; @@ -6330,9 +6336,9 @@ int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, } int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected) + struct rtw89_vif_link *rtwvif_link, bool connected) { - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct rtw89_mac_chinfo *ch_info, *tmp; struct ieee80211_channel *channel; struct list_head chan_list; @@ -6407,7 +6413,7 @@ int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, } int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; @@ -6459,9 +6465,9 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, } int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected) + struct rtw89_vif_link *rtwvif_link, bool connected) { - struct cfg80211_scan_request *req = rtwvif->scan_req; + struct cfg80211_scan_request *req = rtwvif_link->scan_req; struct rtw89_mac_chinfo_be *ch_info, *tmp; struct ieee80211_channel *channel; struct list_head chan_list; @@ -6518,17 +6524,17 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, } static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected) + struct rtw89_vif_link *rtwvif_link, bool connected) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; int ret; - ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif); + ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link); if (ret) { rtw89_err(rtwdev, "Update probe request failed\n"); goto out; } - ret = mac->add_chan_list(rtwdev, rtwvif, connected); + ret = mac->add_chan_list(rtwdev, rtwvif_link, connected); out: return ret; } @@ -6536,27 +6542,27 @@ static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_scan_request *scan_req) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct cfg80211_scan_request *req = &scan_req->req; u32 rx_fltr = rtwdev->hal.rx_fltr; u8 mac_addr[ETH_ALEN]; - rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan); + rtw89_get_channel(rtwdev, rtwvif_link, &rtwdev->scan_info.op_chan); rtwdev->scan_info.scanning_vif = vif; rtwdev->scan_info.last_chan_idx = 0; rtwdev->scan_info.abort = false; - rtwvif->scan_ies = &scan_req->ies; - rtwvif->scan_req = req; + rtwvif_link->scan_ies = &scan_req->ies; + rtwvif_link->scan_req = req; ieee80211_stop_queues(rtwdev->hw); - rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, false); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false); if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) get_random_mask_addr(mac_addr, req->mac_addr, req->mac_addr_mask); else ether_addr_copy(mac_addr, vif->addr); - rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true); + rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true); rx_fltr &= ~B_AX_A_BCN_CHK_EN; rx_fltr &= ~B_AX_A_BC; @@ -6574,7 +6580,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct cfg80211_scan_info info = { .aborted = aborted, }; @@ -6590,12 +6596,12 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, rtw89_core_scan_complete(rtwdev, vif, true); ieee80211_scan_completed(rtwdev->hw, &info); ieee80211_wake_queues(rtwdev->hw); - rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, true); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true); rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); rtw89_release_pkt_list(rtwdev); - rtwvif->scan_req = NULL; - rtwvif->scan_ies = NULL; + rtwvif_link->scan_req = NULL; + rtwvif_link->scan_ies = NULL; scan_info->last_chan_idx = 0; scan_info->scanning_vif = NULL; scan_info->abort = false; @@ -6624,11 +6630,11 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; - rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { /* This variable implies connected or during attempt to connect */ - if (!is_zero_ether_addr(rtwvif->bssid)) + if (!is_zero_ether_addr(rtwvif_link->bssid)) return true; } @@ -6640,19 +6646,19 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_scan_option opt = {0}; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; bool connected; int ret = 0; - rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; - if (!rtwvif) + rtwvif_link = vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; + if (!rtwvif_link) return -EINVAL; connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); opt.enable = enable; opt.target_ch_mode = connected; if (enable) { - ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected); + ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, connected); if (ret) goto out; } @@ -6667,7 +6673,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID; } - ret = mac->scan_offload(rtwdev, &opt, rtwvif, false); + ret = mac->scan_offload(rtwdev, &opt, rtwvif_link, false); out: return ret; } @@ -6773,7 +6779,7 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, } #define H2C_KEEP_ALIVE_LEN 4 -int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable) { struct sk_buff *skb; @@ -6781,7 +6787,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, int ret; if (enable) { - ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id); if (ret) @@ -6799,7 +6805,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); - RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id); + RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -6821,7 +6827,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, return ret; } -int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_h2c_arp_offload *h2c; @@ -6831,7 +6837,7 @@ int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, int ret; if (enable) { - ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_ARP_RSP, &pkt_id); if (ret) @@ -6849,7 +6855,7 @@ int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) | le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) | - le32_encode_bits(rtwvif->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) | + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) | le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -6874,11 +6880,11 @@ int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, #define H2C_DISCONNECT_DETECT_LEN 8 int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable) + struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct sk_buff *skb; - u8 macid = rtwvif->mac_id; + u8 macid = rtwvif_link->mac_id; int ret; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); @@ -6917,7 +6923,7 @@ int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, return ret; } -int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; @@ -6938,7 +6944,7 @@ int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) | le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) | - le32_encode_bits(rtwvif->mac_id, RTW89_H2C_NLO_W0_MACID); + le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID); if (enable) { h2c->nlo_cnt = nd_config->n_match_sets; @@ -6968,12 +6974,12 @@ int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, return ret; } -int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_h2c_wow_global *h2c; - u8 macid = rtwvif->mac_id; + u8 macid = rtwvif_link->mac_id; u32 len = sizeof(*h2c); struct sk_buff *skb; int ret; @@ -7017,12 +7023,12 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, #define H2C_WAKEUP_CTRL_LEN 4 int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct sk_buff *skb; - u8 macid = rtwvif->mac_id; + u8 macid = rtwvif_link->mac_id; int ret; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); @@ -7115,13 +7121,13 @@ int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, } int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; struct rtw89_h2c_wow_gtk_ofld *h2c; - u8 macid = rtwvif->mac_id; + u8 macid = rtwvif_link->mac_id; u32 len = sizeof(*h2c); u8 pkt_id_sa_query = 0; struct sk_buff *skb; @@ -7143,14 +7149,14 @@ int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, if (!enable) goto hdr; - ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_EAPOL_KEY, &pkt_id_eapol); if (ret) goto fail; if (gtk_info->igtk_keyid) { - ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link, RTW89_PKT_OFLD_TYPE_SA_QUERY, &pkt_id_sa_query); if (ret) @@ -7188,7 +7194,7 @@ int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, return ret; } -int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable) { struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait; @@ -7204,7 +7210,7 @@ int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, skb_put(skb, len); h2c = (struct rtw89_h2c_fwips *)skb->data; - h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_FW_IPS_W0_MACID) | + h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) | le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 5b8d83d90a4e..29d7529d25fe 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4459,13 +4459,13 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, u8 type, u8 cat, u8 class, u8 func, bool rack, bool dack, u32 len); int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, @@ -4481,29 +4481,29 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta); int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); + struct rtw89_vif_link *rtwvif_link); int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); -int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, + struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif, struct rtw89_sta *rtwsta, const u8 *scan_mac_addr); int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta); void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); void rtw89_fw_c2h_work(struct work_struct *work); int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, enum rtw89_upd_mode upd_mode); -int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta, bool dis_conn); int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en); int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, bool pause); -int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u8 ac, u32 val); int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, @@ -4511,7 +4511,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, bool connect); int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, struct rtw89_rx_phy_ppdu *phy_ppdu); -int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type); int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type); @@ -4533,11 +4533,11 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, struct list_head *chan_list); int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, struct rtw89_scan_option *opt, - struct rtw89_vif *vif, + struct rtw89_vif_link *vif, bool wowlan); int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, struct rtw89_scan_option *opt, - struct rtw89_vif *vif, + struct rtw89_vif_link *vif, bool wowlan); int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, struct rtw89_fw_h2c_rf_reg_info *info, @@ -4563,10 +4563,11 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); -int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u8 macid); void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool notify_fw); + struct rtw89_vif_link *rtwvif_link, + bool notify_fw); void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params); @@ -4579,8 +4580,8 @@ int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, struct rtw89_lps_parm *lps_param); int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); -int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link); +int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len); struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len); @@ -4597,41 +4598,42 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool enable); void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected); + struct rtw89_vif_link *rtwvif_link, bool connected); int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); + struct rtw89_vif_link *rtwvif_link); int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected); + struct rtw89_vif_link *rtwvif_link, bool connected); int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); + struct rtw89_vif_link *rtwvif_link); int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, const struct rtw89_pkt_drop_params *params); int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_p2p_noa_desc *desc, u8 act, u8 noa_id); -int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool en); -int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); -int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); -int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); + struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); -int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool enable); +int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); + struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, struct rtw89_wow_cam_info *cam_info); int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool enable); int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, @@ -4676,32 +4678,32 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) } static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { const struct rtw89_chip_info *chip = rtwdev->chip; - return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta); + return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta); } static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_sta *rtwsta) { const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->ops->h2c_default_dmac_tbl) - return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta); + return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta); return 0; } static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chip_info *chip = rtwdev->chip; - return chip->ops->h2c_update_beacon(rtwdev, rtwvif); + return chip->ops->h2c_update_beacon(rtwdev, rtwvif_link); } static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index c70a23a763b0..e1956c722436 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4076,17 +4076,17 @@ static const struct rtw89_port_reg rtw89_port_base_ax = { }; static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u8 type) + struct rtw89_vif_link *rtwvif_link, u8 type) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port); + u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif_link->port); u32 reg_info, reg_ctrl; u32 val; int ret; - reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif->mac_idx); - reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif->mac_idx); + reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif_link->mac_idx); + reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type); rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN); @@ -4098,26 +4098,32 @@ static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev, rtw89_warn(rtwdev, "Polling beacon packet empty fail\n"); } -static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif->port)); - rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1); - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0); - rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0); - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2); - rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1); - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1); - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); + rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port)); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, + 1); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, + 0); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, + 0); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, 2); + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early, + B_AX_TBTTERLY_MASK, 1); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, + B_AX_BCN_SPACE_MASK, 1); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); - rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0); - if (rtwvif->port == RTW89_PORT_0) - rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1); + rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM0); + if (rtwvif_link->port == RTW89_PORT_0) + rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM1); - rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif->port)); - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN); + rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port)); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TBTT_PROHIB_EN); fsleep(2000); } @@ -4131,286 +4137,294 @@ static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvi #define BCN_ERLY_SET_DLY (10 * 2) static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; bool need_backup = false; u32 backup_val; - if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN)) + if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN)) return; - if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) { + if (chip->chip_id == RTL8852A && rtwvif_link->port != RTW89_PORT_0) { need_backup = true; - backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib); + backup_val = rtw89_read32_port(rtwdev, rtwvif_link, p->tbtt_prohib); } - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) - rtw89_mac_bcn_drop(rtwdev, rtwvif); + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + rtw89_mac_bcn_drop(rtwdev, rtwvif_link); if (chip->chip_id == RTL8852A) { - rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK); - rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1); - rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK); - rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_SETUP_MASK); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, + B_AX_TBTT_HOLD_MASK, 1); + rtw89_write16_port_clr(rtwdev, rtwvif_link, p->tbtt_early, + B_AX_TBTTERLY_MASK); + rtw89_write16_port_clr(rtwdev, rtwvif_link, p->bcn_early, + B_AX_BCNERLY_MASK); } msleep(vif->bss_conf.beacon_int + 1); - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN | + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN | B_AX_BRK_SETUP); - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST); - rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST); + rtw89_write32_port(rtwdev, rtwvif_link, p->bcn_cnt_tmr, 0); if (need_backup) - rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val); + rtw89_write32_port(rtwdev, rtwvif_link, p->tbtt_prohib, backup_val); } static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en) + struct rtw89_vif_link *rtwvif_link, bool en) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, + B_AX_TXBCN_RPT_EN); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, + B_AX_TXBCN_RPT_EN); } static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en) + struct rtw89_vif_link *rtwvif_link, bool en) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, + B_AX_RXBCN_RPT_EN); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, + B_AX_RXBCN_RPT_EN); } static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK, - rtwvif->net_type); + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_NET_TYPE_MASK, + rtwvif_link->net_type); } static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK; + bool en = rtwvif_link->net_type != RTW89_NET_TYPE_NO_LINK; u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bits); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bits); } static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || - rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; u32 bit = B_AX_RX_BSSID_FIT_EN; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bit); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bit); } void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en) + struct rtw89_vif_link *rtwvif_link, bool en) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN); } static void rtw89_mac_port_cfg_rx_sync_by_nettype(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || - rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; - rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, en); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, en); } static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en) + struct rtw89_vif_link *rtwvif_link, bool en) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; if (en) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN); } static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || - rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; + bool en = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || + rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC; - rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); } void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) - rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); } static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL; - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK, bcn_int); } static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { - u8 win = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0; + u8 win = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u32 reg; - reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif_link->mac_idx); rtw89_write8(rtwdev, reg, win); } static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); u32 addr; - addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif->mac_idx); + addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx); rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE); - rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK, + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK, vif->bss_conf.dtim_period); } static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF); } static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF); } static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF); } static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early, B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF); } static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); static const u32 masks[RTW89_PORT_NUM] = { B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK, B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK, B_AX_BSS_COLOB_AX_PORT_4_MASK, }; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u32 reg_base; u32 reg; u8 bss_color; bss_color = vif->bss_conf.he_bss_color.color; reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color; - reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, masks[port], bss_color); } static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u32 reg; - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) return; if (port == 0) { - reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif_link->mac_idx); rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK); } } static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; u32 reg; u32 val; - reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif_link->mac_idx); val = rtw89_read32(rtwdev, reg); val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port)); if (port == 0) @@ -4419,31 +4433,31 @@ static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, } static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable) + struct rtw89_vif_link *rtwvif_link, bool enable) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; if (enable) - rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, + rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN); else - rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, + rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN); } static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, + rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, BCN_ERLY_DEF); } static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; @@ -4452,20 +4466,20 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev, if (rtwdev->chip->chip_id != RTL8852C) return; - if (rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT && - rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) return; val = FIELD_PREP(B_AX_TBTT_SHIFT_OFST_MAG, 1) | B_AX_TBTT_SHIFT_OFST_SIGN; - rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_shift, + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_shift, B_AX_TBTT_SHIFT_OFST_MASK, val); } void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - struct rtw89_vif *rtwvif_src, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, u16 offset_tu) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; @@ -4473,8 +4487,8 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, u32 val, reg; val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu); - reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif->port * 4, - rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif_link->port * 4, + rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); @@ -4482,16 +4496,16 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, } static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - struct rtw89_vif *rtwvif_src, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, u8 offset, int *n_offset) { - if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) + if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif_link == rtwvif_src) return; /* adjust offset randomly to avoid beacon conflict */ offset = offset - offset / 4 + get_random_u32() % (offset / 2); - rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src, + rtw89_mac_port_tsf_sync(rtwdev, rtwvif_link, rtwvif_src, (*n_offset) * offset); (*n_offset)++; @@ -4499,7 +4513,7 @@ static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev, static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) { - struct rtw89_vif *src = NULL, *tmp; + struct rtw89_vif_link *src = NULL, *tmp; u8 offset = 100, vif_aps = 0; int n_offset = 1; @@ -4519,100 +4533,100 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset); } -int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { int ret; - ret = rtw89_mac_port_update(rtwdev, rtwvif); + ret = rtw89_mac_port_update(rtwdev, rtwvif_link); if (ret) return ret; - rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id); - rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id); + rtw89_mac_dmac_tbl_init(rtwdev, rtwvif_link->mac_id); + rtw89_mac_cmac_tbl_init(rtwdev, rtwvif_link->mac_id); - ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false); + ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif_link->mac_id, false); if (ret) return ret; - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE); + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_CREATE); if (ret) return ret; - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); if (ret) return ret; - ret = rtw89_cam_init(rtwdev, rtwvif); + ret = rtw89_cam_init(rtwdev, rtwvif_link); if (ret) return ret; - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); if (ret) return ret; - ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, NULL); + ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, NULL); if (ret) return ret; - ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, NULL); + ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, NULL); if (ret) return ret; return 0; } -int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { int ret; - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE); + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_REMOVE); if (ret) return ret; - rtw89_cam_deinit(rtwdev, rtwvif); + rtw89_cam_deinit(rtwdev, rtwvif_link); - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); if (ret) return ret; return 0; } -int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - u8 port = rtwvif->port; + u8 port = rtwvif_link->port; if (port >= RTW89_PORT_NUM) return -EINVAL; - rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif); - rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false); - rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false); - rtw89_mac_port_cfg_net_type(rtwdev, rtwvif); - rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif); - rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif); - rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif); - rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif); - rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif); - rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif); - rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif); - rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif); - rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif); - rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif); - rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif); - rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif); - rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif); - rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); - rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); - rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true); + rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif_link, false); + rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif_link, false); + rtw89_mac_port_cfg_net_type(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true); rtw89_mac_port_tsf_resync_all(rtwdev); fsleep(BCN_ERLY_SET_DLY); - rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); + rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif_link); return 0; } -int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u64 *tsf) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; @@ -4620,12 +4634,12 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 tsf_low, tsf_high; int ret; - ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL); + ret = rtw89_mac_check_mac_en(rtwdev, rtwvif_link->mac_idx, RTW89_CMAC_SEL); if (ret) return ret; - tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l); - tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h); + tsf_low = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_l); + tsf_high = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_h); *tsf = (u64)tsf_high << 32 | tsf_low; return 0; @@ -4653,7 +4667,7 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; bool tolerated = true; @@ -4670,44 +4684,44 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, &tolerated); reg = rtw89_mac_reg_by_idx(rtwdev, mac->narrow_bw_ru_dis.addr, - rtwvif->mac_idx); + rtwvif_link->mac_idx); if (tolerated) rtw89_write32_clr(rtwdev, reg, mac->narrow_bw_ru_dis.mask); else rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask); } -void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif); + rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link); } -int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { int ret; - rtwvif->mac_id = rtw89_acquire_mac_id(rtwdev); - if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM) + rtwvif_link->mac_id = rtw89_acquire_mac_id(rtwdev); + if (rtwvif_link->mac_id == RTW89_MAX_MAC_ID_NUM) return -ENOSPC; - ret = rtw89_mac_vif_init(rtwdev, rtwvif); + ret = rtw89_mac_vif_init(rtwdev, rtwvif_link); if (ret) goto release_mac_id; return 0; release_mac_id: - rtw89_release_mac_id(rtwdev, rtwvif->mac_id); + rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); return ret; } -int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { int ret; - ret = rtw89_mac_vif_deinit(rtwdev, rtwvif); - rtw89_release_mac_id(rtwdev, rtwvif->mac_id); + ret = rtw89_mac_vif_deinit(rtwdev, rtwvif_link); + rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); return ret; } @@ -4731,7 +4745,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, const struct rtw89_c2h_scanofld *c2h = (const struct rtw89_c2h_scanofld *)skb->data; struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct rtw89_chan new; u8 reason, status, tx_fail, band, actual_period, expect_period; u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf; @@ -4739,7 +4753,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, u16 chan; int ret; - if (!rtwvif) + if (!rtwvif_link) return; tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL); @@ -4781,8 +4795,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, if (rtwdev->scan_info.abort) return; - if (rtwvif && rtwvif->scan_req && - last_chan < rtwvif->scan_req->n_channels) { + if (rtwvif_link && rtwvif_link->scan_req && + last_chan < rtwvif_link->scan_req->n_channels) { ret = rtw89_hw_scan_offload(rtwdev, vif, true); if (ret) { rtw89_hw_scan_abort(rtwdev, vif); @@ -4795,14 +4809,14 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, case RTW89_SCAN_ENTER_OP_NOTIFY: case RTW89_SCAN_ENTER_CH_NOTIFY: if (rtw89_is_op_chan(rtwdev, band, chan)) { - rtw89_assign_entity_chan(rtwdev, rtwvif->chanctx_idx, + rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, &rtwdev->scan_info.op_chan); rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); ieee80211_wake_queues(rtwdev->hw); } else { rtw89_chan_create(&new, chan, chan, band, RTW89_CHANNEL_WIDTH_20); - rtw89_assign_entity_chan(rtwdev, rtwvif->chanctx_idx, + rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, &new); } break; @@ -4812,10 +4826,10 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, } static void -rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct sk_buff *skb) { - struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif_link); enum nl80211_cqm_rssi_threshold_event nl_event; const struct rtw89_c2h_mac_bcnfltr_rpt *c2h = (const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data; @@ -4827,7 +4841,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT); mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID); - if (mac_id != rtwvif->mac_id) + if (mac_id != rtwvif_link->mac_id) return; rtw89_debug(rtwdev, RTW89_DBG_FW, @@ -4836,7 +4850,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, switch (type) { case RTW89_BCN_FLTR_BEACON_LOSS: - if (!rtwdev->scanning && !rtwvif->offchan) + if (!rtwdev->scanning && !rtwvif_link->offchan) ieee80211_connection_loss(vif); else rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); @@ -4863,10 +4877,10 @@ static void rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif, c2h); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h); } static void @@ -5934,10 +5948,10 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - u8 mac_idx = rtwvif->mac_idx; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + u8 mac_idx = rtwvif_link->mac_idx; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; - u8 port_sel = rtwvif->port; + u8 port_sel = rtwvif_link->port; u8 sound_dim = 3, t; u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; u32 reg; @@ -5992,10 +6006,10 @@ static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); u32 reg; - u8 mac_idx = rtwvif->mac_idx; + u8 mac_idx = rtwvif_link->mac_idx; int ret; ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); @@ -6031,12 +6045,12 @@ static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; if (rtw89_sta_has_beamformer_cap(sta)) { rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); - rtw89_mac_init_bfee_ax(rtwdev, rtwvif->mac_idx); + rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx); rtw89_mac_set_csi_para_reg_ax(rtwdev, vif, sta); rtw89_mac_csi_rrsc_ax(rtwdev, vif, sta); } @@ -6045,16 +6059,16 @@ static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false); + rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false); } void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - u8 mac_idx = rtwvif->mac_idx; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + u8 mac_idx = rtwvif_link->mac_idx; __le32 *p; rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n"); @@ -6121,7 +6135,7 @@ void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) { struct rtw89_traffic_stats *stats = &rtwdev->stats; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv; bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); bool keep_timer = true; @@ -6133,16 +6147,16 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) keep_timer = false; if (keep_timer != old_keep_timer) { - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_bfee_standby_timer(rtwdev, rtwvif->mac_idx, + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx, keep_timer); } if (en == old) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en); } static int @@ -6150,7 +6164,7 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, u32 tx_time) { #define MAC_AX_DFLT_TX_TIME 5280 - u8 mac_idx = rtwsta->rtwvif->mac_idx; + u8 mac_idx = rtwsta->rtwvif_link->mac_idx; u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time; u32 reg; int ret = 0; @@ -6192,7 +6206,7 @@ int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, u32 *tx_time) { - u8 mac_idx = rtwsta->rtwvif->mac_idx; + u8 mac_idx = rtwsta->rtwvif_link->mac_idx; u32 reg; int ret = 0; @@ -6234,7 +6248,7 @@ int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, u8 *tx_retry) { - u8 mac_idx = rtwsta->rtwvif->mac_idx; + u8 mac_idx = rtwsta->rtwvif_link->mac_idx; u32 reg; int ret = 0; @@ -6255,10 +6269,10 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, } int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en) + struct rtw89_vif_link *rtwvif_link, bool en) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; - u8 mac_idx = rtwvif->mac_idx; + u8 mac_idx = rtwvif_link->mac_idx; u16 set = mac->muedca_ctrl.mask; u32 reg; u32 ret; @@ -6334,15 +6348,15 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) RTW89_PKT_DROP_SEL_MACID_VI_ONCE, RTW89_PKT_DROP_SEL_MACID_VO_ONCE, }; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_pkt_drop_params params = {0}; int i; params.mac_band = RTW89_MAC_0; params.macid = rtwsta->mac_id; - params.port = rtwvif->port; + params.port = rtwvif_link->port; params.mbssid = 0; - params.tf_trs = rtwvif->trigger; + params.tf_trs = rtwvif_link->trigger; for (i = 0; i < ARRAY_SIZE(sels); i++) { params.sel = sels[i]; @@ -6353,21 +6367,21 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_dev *rtwdev = rtwvif->rtwdev; - struct rtw89_vif *target = data; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; + struct rtw89_vif_link *target = data; - if (rtwvif != target) + if (rtwvif_link != target) return; rtw89_mac_pkt_drop_sta(rtwdev, rtwsta); } -void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_mac_pkt_drop_vif_iter, - rtwvif); + rtwvif_link); } int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 67c2a4507124..6839028991d4 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1004,12 +1004,12 @@ struct rtw89_mac_gen_def { bool (*is_txq_empty)(struct rtw89_dev *rtwdev); int (*add_chan_list)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool connected); + struct rtw89_vif_link *rtwvif_link, bool connected); int (*add_chan_list_pno)(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif); + struct rtw89_vif_link *rtwvif_link); int (*scan_offload)(struct rtw89_dev *rtwdev, struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, bool wowlan); int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow); @@ -1033,81 +1033,89 @@ u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_id } static inline u32 -rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base) +rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); return rtw89_read32(rtwdev, reg); } static inline u32 -rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 mask) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); return rtw89_read32_mask(rtwdev, reg, mask); } static inline void -rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base, +rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 data) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write32(rtwdev, reg, data); } static inline void -rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 mask, u32 data) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, mask, data); } static inline void -rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 mask, u16 data) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write16_mask(rtwdev, reg, mask, data); } static inline void -rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 bit) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write32_clr(rtwdev, reg, bit); } static inline void -rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u16 bit) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write16_clr(rtwdev, reg, bit); } static inline void -rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base, u32 bit) { u32 reg; - reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port, + rtwvif_link->mac_idx); rtw89_write32_set(rtwdev, reg, bit); } @@ -1139,21 +1147,21 @@ int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_qempty *qempty); void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, enum mac_ax_err_info err); -int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); -int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); +int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - struct rtw89_vif *rtwvif_src, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_vif_link *rtwvif_src, u16 offset_tu); -int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u64 *tsf); void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en); + struct rtw89_vif_link *rtwvif_link, bool en); void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); -void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); -int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); +int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); @@ -1268,10 +1276,10 @@ void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, bool disconnect); void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev); void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en); -int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool en); + struct rtw89_vif_link *rtwvif_link, bool en); int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause); static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) @@ -1454,7 +1462,7 @@ int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val) return mac->read_xtal_si(rtwdev, offset, val); } -void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, enum rtw89_mac_idx band); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 48ad0d0f76bf..bc0ff64c1c98 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -23,12 +23,12 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_sta *sta = control->sta; u32 flags = IEEE80211_SKB_CB(skb)->flags; int ret, qsel; - if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { + if (rtwvif_link->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n"); @@ -109,7 +109,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; int ret = 0; rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", @@ -123,46 +123,46 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | IEEE80211_VIF_SUPPORTS_CQM_RSSI; - rtwvif->rtwdev = rtwdev; - rtwvif->roc.state = RTW89_ROC_IDLE; - rtwvif->offchan = false; - if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) - list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); + rtwvif_link->rtwdev = rtwdev; + rtwvif_link->roc.state = RTW89_ROC_IDLE; + rtwvif_link->offchan = false; + if (!rtw89_rtwvif_in_list(rtwdev, rtwvif_link)) + list_add_tail(&rtwvif_link->list, &rtwdev->rtwvifs_list); - INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work); - INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work); + INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); + INIT_DELAYED_WORK(&rtwvif_link->roc.roc_work, rtw89_roc_work); rtw89_leave_ps_mode(rtwdev); - rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); + rtw89_traffic_stats_init(rtwdev, &rtwvif_link->stats); rtw89_vif_type_mapping(vif, false); - rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port, - RTW89_PORT_NUM); - if (rtwvif->port == RTW89_PORT_NUM) { + rtwvif_link->port = rtw89_core_acquire_bit_map(rtwdev->hw_port, + RTW89_PORT_NUM); + if (rtwvif_link->port == RTW89_PORT_NUM) { ret = -ENOSPC; - list_del_init(&rtwvif->list); + list_del_init(&rtwvif_link->list); goto out; } - rtwvif->bcn_hit_cond = 0; - rtwvif->mac_idx = RTW89_MAC_0; - rtwvif->phy_idx = RTW89_PHY_0; - rtwvif->chanctx_idx = RTW89_CHANCTX_0; - rtwvif->chanctx_assigned = false; - rtwvif->hit_rule = 0; - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; - ether_addr_copy(rtwvif->mac_addr, vif->addr); - INIT_LIST_HEAD(&rtwvif->general_pkt_list); + rtwvif_link->bcn_hit_cond = 0; + rtwvif_link->mac_idx = RTW89_MAC_0; + rtwvif_link->phy_idx = RTW89_PHY_0; + rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; + rtwvif_link->chanctx_assigned = false; + rtwvif_link->hit_rule = 0; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + ether_addr_copy(rtwvif_link->mac_addr, vif->addr); + INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); - ret = rtw89_mac_add_vif(rtwdev, rtwvif); + ret = rtw89_mac_add_vif(rtwdev, rtwvif_link); if (ret) { - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - list_del_init(&rtwvif->list); + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + list_del_init(&rtwvif_link->list); goto out; } rtw89_core_txq_init(rtwdev, vif->txq); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START); + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START); rtw89_recalc_lps(rtwdev); out: @@ -175,20 +175,20 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", vif->addr, vif->type, vif->p2p); - cancel_work_sync(&rtwvif->update_beacon_work); - cancel_delayed_work_sync(&rtwvif->roc.roc_work); + cancel_work_sync(&rtwvif_link->update_beacon_work); + cancel_delayed_work_sync(&rtwvif_link->roc.roc_work); mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP); - rtw89_mac_remove_vif(rtwdev, rtwvif); - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - list_del_init(&rtwvif->list); + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP); + rtw89_mac_remove_vif(rtwdev, rtwvif_link); + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + list_del_init(&rtwvif_link->list); rtw89_recalc_lps(rtwdev); rtw89_enter_ips_by_hwflags(rtwdev); @@ -311,11 +311,11 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { }; static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u8 aifsn) + struct rtw89_vif_link *rtwvif_link, u8 aifsn) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); u8 slot_time; u8 sifs; @@ -326,9 +326,9 @@ static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, } static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u16 ac) + struct rtw89_vif_link *rtwvif_link, u16 ac) { - struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; + struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac]; u32 val; u8 ecw_max, ecw_min; u8 aifs; @@ -336,12 +336,12 @@ static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev, /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ ecw_max = ilog2(params->cw_max + 1); ecw_min = ilog2(params->cw_min + 1); - aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs); + aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, params->aifs); val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) | FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) | FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) | FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs); - rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val); + rtw89_fw_h2c_set_edca(rtwdev, rtwvif_link, ac_to_fw_idx[ac], val); } #define R_MUEDCA_ACS_PARAM(acs) {R_AX_MUEDCA_ ## acs ## _PARAM_0, \ @@ -355,9 +355,9 @@ static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS][RTW89_CHIP_GEN_NUM] = { }; static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u16 ac) + struct rtw89_vif_link *rtwvif_link, u16 ac) { - struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; + struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac]; struct ieee80211_he_mu_edca_param_ac_rec *mu_edca; int gen = rtwdev->chip->chip_gen; u8 aifs, aifsn; @@ -370,32 +370,33 @@ static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev, mu_edca = ¶ms->mu_edca_param_rec; aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn); - aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0; + aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, aifsn) : 0; timer_32us = mu_edca->mu_edca_timer << 8; val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) | FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) | FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs); - reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], + rtwvif_link->mac_idx); rtw89_write32(rtwdev, reg, val); - rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true); + rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif_link, true); } static void __rtw89_conf_tx(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, u16 ac) + struct rtw89_vif_link *rtwvif_link, u16 ac) { - ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac); - ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac); + ____rtw89_conf_tx_edca(rtwdev, rtwvif_link, ac); + ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif_link, ac); } static void rtw89_conf_tx(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { u16 ac; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - __rtw89_conf_tx(rtwdev, rtwvif, ac); + __rtw89_conf_tx(rtwdev, rtwvif_link, ac); } static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, @@ -421,7 +422,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 changed) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); @@ -431,7 +432,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, rtw89_station_mode_sta_assoc(rtwdev, vif); rtw89_phy_set_bss_color(rtwdev, vif); rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); - rtw89_mac_port_update(rtwdev, rtwvif); + rtw89_mac_port_update(rtwdev, rtwvif_link); rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif); rtw89_queue_chanctx_work(rtwdev); @@ -448,7 +449,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, rtw89_recalc_lps(rtwdev); if (changed & BSS_CHANGED_ARP_FILTER) - rtwvif->ip_addr = vif->cfg.arp_addr_list[0]; + rtwvif_link->ip_addr = vif->cfg.arp_addr_list[0]; mutex_unlock(&rtwdev->mutex); } @@ -459,23 +460,23 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, u64 changed) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); if (changed & BSS_CHANGED_BSSID) { - ether_addr_copy(rtwvif->bssid, conf->bssid); - rtw89_cam_bssid_changed(rtwdev, rtwvif); - rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); - WRITE_ONCE(rtwvif->sync_bcn_tsf, 0); + ether_addr_copy(rtwvif_link->bssid, conf->bssid); + rtw89_cam_bssid_changed(rtwdev, rtwvif_link); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); + WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0); } if (changed & BSS_CHANGED_BEACON) - rtw89_chip_h2c_update_beacon(rtwdev, rtwvif); + rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); if (changed & BSS_CHANGED_ERP_SLOT) - rtw89_conf_tx(rtwdev, rtwvif); + rtw89_conf_tx(rtwdev, rtwvif_link); if (changed & BSS_CHANGED_HE_BSS_COLOR) rtw89_phy_set_bss_color(rtwdev, vif); @@ -490,7 +491,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); if (changed & BSS_CHANGED_TPE) - rtw89_reg_6ghz_recalc(rtwdev, rtwvif, true); + rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); mutex_unlock(&rtwdev->mutex); } @@ -500,12 +501,12 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_bss_conf *link_conf) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chan *chan; mutex_lock(&rtwdev->mutex); - chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); if (chan->band_type == RTW89_BAND_6G) { mutex_unlock(&rtwdev->mutex); return -EOPNOTSUPP; @@ -514,14 +515,14 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, if (rtwdev->scanning) rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); - ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid); - rtw89_cam_bssid_changed(rtwdev, rtwvif); - rtw89_mac_port_update(rtwdev, rtwvif); + ether_addr_copy(rtwvif_link->bssid, vif->bss_conf.bssid); + rtw89_cam_bssid_changed(rtwdev, rtwvif_link); + rtw89_mac_port_update(rtwdev, rtwvif_link); rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); - rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE); - rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); - rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL); - rtw89_chip_rfk_channel(rtwdev, rtwvif); + rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE); + rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); rtw89_queue_chanctx_work(rtwdev); mutex_unlock(&rtwdev->mutex); @@ -534,12 +535,12 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); - rtw89_mac_stop_ap(rtwdev, rtwvif); + rtw89_mac_stop_ap(rtwdev, rtwvif_link); rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); - rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); + rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); mutex_unlock(&rtwdev->mutex); } @@ -548,9 +549,9 @@ static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, { struct rtw89_dev *rtwdev = hw->priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; - ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work); + ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work); return 0; } @@ -561,12 +562,12 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, const struct ieee80211_tx_queue_params *params) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); - rtwvif->tx_params[ac] = *params; - __rtw89_conf_tx(rtwdev, rtwvif, ac); + rtwvif_link->tx_params[ac] = *params; + __rtw89_conf_tx(rtwdev, rtwvif_link, ac); mutex_unlock(&rtwdev->mutex); return 0; @@ -740,14 +741,14 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, static void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; if (vif) { - rtwvif = (struct rtw89_vif *)vif->drv_priv; - rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); + rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif_link); } else { - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif_link); } } @@ -778,7 +779,7 @@ static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta { struct rtw89_iter_bitrate_mask_data *br_data = data; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif_link); if (vif != br_data->vif || vif->p2p) return; @@ -854,10 +855,10 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, const u8 *mac_addr) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); - rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false); + rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false); mutex_unlock(&rtwdev->mutex); } @@ -884,13 +885,13 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); int ret = 0; if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return 1; - if (rtwdev->scanning || rtwvif->offchan) + if (rtwdev->scanning || rtwvif_link->offchan) return -EBUSY; mutex_lock(&rtwdev->mutex); @@ -970,11 +971,11 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; int ret; mutex_lock(&rtwdev->mutex); - ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif, ctx); + ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx); mutex_unlock(&rtwdev->mutex); return ret; @@ -986,10 +987,10 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; mutex_lock(&rtwdev->mutex); - rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif, ctx); + rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx); mutex_unlock(&rtwdev->mutex); } @@ -1000,8 +1001,8 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, enum ieee80211_roc_type type) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); - struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct rtw89_roc *roc = &rtwvif_link->roc; if (!vif) return -EINVAL; @@ -1025,7 +1026,7 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, roc->chan = *chan; roc->type = type; - rtw89_roc_start(rtwdev, rtwvif); + rtw89_roc_start(rtwdev, rtwvif_link); mutex_unlock(&rtwdev->mutex); @@ -1036,15 +1037,15 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - if (!rtwvif) + if (!rtwvif_link) return -EINVAL; - cancel_delayed_work_sync(&rtwvif->roc.roc_work); + cancel_delayed_work_sync(&rtwvif_link->roc.roc_work); mutex_lock(&rtwdev->mutex); - rtw89_roc_end(rtwdev, rtwvif); + rtw89_roc_end(rtwdev, rtwvif_link); mutex_unlock(&rtwdev->mutex); return 0; @@ -1054,7 +1055,7 @@ static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta) { struct cfg80211_tid_config *tid_config = data; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta->rtwvif->rtwdev; + struct rtw89_dev *rtwdev = rtwsta->rtwvif_link->rtwdev; rtw89_core_set_tid_config(rtwdev, sta, tid_config); } diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index 31f0a5225b11..bc3215939f37 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -2094,10 +2094,10 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; - u8 mac_idx = rtwvif->mac_idx; - u8 port_sel = rtwvif->port; + u8 mac_idx = rtwvif_link->mac_idx; + u8 port_sel = rtwvif_link->port; u8 sound_dim = 3, t; u8 *phy_cap; u32 reg; @@ -2158,9 +2158,9 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); - u8 mac_idx = rtwvif->mac_idx; + u8 mac_idx = rtwvif_link->mac_idx; int ret; u32 reg; @@ -2198,12 +2198,12 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; if (rtw89_sta_has_beamformer_cap(sta)) { rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); - rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx); + rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx); rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta); rtw89_mac_csi_rrsc_be(rtwdev, vif, sta); } diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 87719b22381d..f5e5deba853e 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -298,12 +298,12 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, bool csi) { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; struct rtw89_ra_info *ra = &rtwsta->ra; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif); + rtwvif_link->chanctx_idx); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif_link); const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi); u64 ra_mask = 0; @@ -458,7 +458,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra->fixed_csi_rate_en = false; ra->ra_csi_rate_en = true; ra->cr_tbl_sel = false; - ra->band_num = rtwvif->phy_idx; + ra->band_num = rtwvif_link->phy_idx; ra->csi_bw = bw_mode; ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32; ra->csi_mcs_ss_idx = 5; @@ -528,10 +528,10 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, const struct cfg80211_bitrate_mask *mask) { struct ieee80211_supported_band *sband; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_phy_rate_pattern next_pattern = {0}; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = { RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0), RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0), @@ -600,7 +600,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, if (!next_pattern.enable) goto out; - rtwvif->rate_pattern = next_pattern; + rtwvif_link->rate_pattern = next_pattern; rtw89_debug(rtwdev, RTW89_DBG_RA, "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n", next_pattern.rate, @@ -609,7 +609,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, return; out: - rtwvif->rate_pattern.enable = false; + rtwvif_link->rate_pattern.enable = false; rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n"); } @@ -4429,33 +4429,33 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, cfo->packet_count++; } -void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, - rtwvif->chanctx_idx); + rtwvif_link->chanctx_idx); struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; if (!chip->ul_tb_waveform_ctrl) return; - rtwvif->def_tri_idx = + rtwvif_link->def_tri_idx = rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG); if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV) - rtwvif->dyn_tb_bedge_en = false; + rtwvif_link->dyn_tb_bedge_en = false; else if (chan->band_type >= RTW89_BAND_5G && chan->band_width >= RTW89_CHANNEL_WIDTH_40) - rtwvif->dyn_tb_bedge_en = true; + rtwvif_link->dyn_tb_bedge_en = true; else - rtwvif->dyn_tb_bedge_en = false; + rtwvif_link->dyn_tb_bedge_en = false; rtw89_debug(rtwdev, RTW89_DBG_UL_TB, "[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n", - ul_tb_info->def_if_bandedge, rtwvif->def_tri_idx); + ul_tb_info->def_if_bandedge, rtwvif_link->def_tri_idx); rtw89_debug(rtwdev, RTW89_DBG_UL_TB, "[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n", - rtwvif->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en); + rtwvif_link->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en); } struct rtw89_phy_ul_tb_check_data { @@ -4477,7 +4477,7 @@ struct rtw89_phy_power_diff { }; static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { static const struct rtw89_phy_power_diff table[2] = { {0x0, 0x0, 0x0, 0x0, 0xf4, 0x3, 0x3}, @@ -4489,13 +4489,13 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev, if (!rtwdev->chip->ul_tb_pwr_diff) return; - if (rtwvif->pwr_diff_en == rtwvif->pre_pwr_diff_en) { - rtwvif->pwr_diff_en = false; + if (rtwvif_link->pwr_diff_en == rtwvif_link->pre_pwr_diff_en) { + rtwvif_link->pwr_diff_en = false; return; } - rtwvif->pre_pwr_diff_en = rtwvif->pwr_diff_en; - param = &table[rtwvif->pwr_diff_en]; + rtwvif_link->pre_pwr_diff_en = rtwvif_link->pwr_diff_en; + param = &table[rtwvif_link->pwr_diff_en]; rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_00, B_Q_MATRIX_00_REAL, param->q_00); @@ -4504,32 +4504,32 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev, rtw89_phy_write32_mask(rtwdev, R_CUSTOMIZE_Q_MATRIX, B_CUSTOMIZE_Q_MATRIX_EN, param->q_matrix_en); - reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_NORM_BW160, param->ultb_1t_norm_160); - reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_NORM_BW160, param->ultb_2t_norm_160); - reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM1_NORM_1STS, param->com1_norm_1sts); - reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif->mac_idx); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM2_RESP_1STS_PATH, param->com2_resp_1sts_path); } static void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct rtw89_phy_ul_tb_check_data *ul_tb_data) { struct rtw89_traffic_stats *stats = &rtwdev->stats; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) return; if (!vif->cfg.assoc) @@ -4542,11 +4542,11 @@ void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, ul_tb_data->low_tf_client = true; ul_tb_data->valid = true; - ul_tb_data->def_tri_idx = rtwvif->def_tri_idx; - ul_tb_data->dyn_tb_bedge_en = rtwvif->dyn_tb_bedge_en; + ul_tb_data->def_tri_idx = rtwvif_link->def_tri_idx; + ul_tb_data->dyn_tb_bedge_en = rtwvif_link->dyn_tb_bedge_en; } - rtw89_phy_ofdma_power_diff(rtwdev, rtwvif); + rtw89_phy_ofdma_power_diff(rtwdev, rtwvif_link); } static void rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev *rtwdev, @@ -4592,7 +4592,7 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_phy_ul_tb_check_data ul_tb_data = {}; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff) return; @@ -4600,8 +4600,8 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) if (rtwdev->total_sta_assoc != 1) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif, &ul_tb_data); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data); if (!ul_tb_data.valid) return; @@ -5896,13 +5896,13 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta { struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; struct rtw89_dev *rtwdev = rtwsta->rtwdev; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; struct rtw89_hal *hal = &rtwdev->hal; bool *done = data; u8 rssi_a, rssi_b; u32 candidate; - if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION || sta->tdls) + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION || sta->tdls) return; if (*done) diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index d00faf151d39..7b6ccf2f933e 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -957,7 +957,7 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, enum rtw89_tssi_bandedge_cfg bandedge_cfg); -void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index aebd6404f802..42a73bba7f5c 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -62,9 +62,9 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter) rtw89_mac_power_mode_change(rtwdev, enter); } -void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) return; if (!rtwdev->ps_mode) @@ -85,23 +85,25 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) rtw89_ps_power_mode_change(rtwdev, false); } -static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_lps_parm lps_param = { - .macid = rtwvif->mac_id, + .macid = rtwvif_link->mac_id, .psmode = RTW89_MAC_AX_PS_MODE_LEGACY, .lastrpwm = RTW89_LAST_RPWM_PS, }; rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL); rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); - rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif); + rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif_link); } -static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_lps_parm lps_param = { - .macid = rtwvif->mac_id, + .macid = rtwvif_link->mac_id, .psmode = RTW89_MAC_AX_PS_MODE_ACTIVE, .lastrpwm = RTW89_LAST_RPWM_ACTIVE, }; @@ -109,7 +111,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); rtw89_fw_leave_lps_check(rtwdev, 0); rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); - rtw89_chip_digital_pwr_comp(rtwdev, rtwvif->phy_idx); + rtw89_chip_digital_pwr_comp(rtwdev, rtwvif_link->phy_idx); } void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) @@ -119,7 +121,7 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) __rtw89_leave_ps_mode(rtwdev); } -void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool ps_mode) { lockdep_assert_held(&rtwdev->mutex); @@ -127,23 +129,24 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) return; - __rtw89_enter_lps(rtwdev, rtwvif); + __rtw89_enter_lps(rtwdev, rtwvif_link); if (ps_mode) - __rtw89_enter_ps_mode(rtwdev, rtwvif); + __rtw89_enter_ps_mode(rtwdev, rtwvif_link); } -static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && - rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) return; - __rtw89_leave_lps(rtwdev, rtwvif); + __rtw89_leave_lps(rtwdev, rtwvif_link); } void rtw89_leave_lps(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; lockdep_assert_held(&rtwdev->mutex); @@ -152,28 +155,28 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev) __rtw89_leave_ps_mode(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_leave_lps_vif(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_leave_lps_vif(rtwdev, rtwvif_link); } void rtw89_enter_ips(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_vif_deinit(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_vif_deinit(rtwdev, rtwvif_link); rtw89_core_stop(rtwdev); } void rtw89_leave_ips(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; int ret; if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) @@ -185,8 +188,8 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev) rtw89_set_channel(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_vif_init(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_mac_vif_init(rtwdev, rtwvif_link); clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); } @@ -197,34 +200,35 @@ void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl) rtw89_leave_lps(rtwdev); } -static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, enum rtw89_p2pps_action act) { if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE) return; if (act == RTW89_P2P_ACT_INIT) - rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, true); + rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, true); else if (act == RTW89_P2P_ACT_TERMINATE) - rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, false); + rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false); } static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; enum rtw89_p2pps_action act; u8 noa_id; - if (rtwvif->last_noa_nr == 0) + if (rtwvif_link->last_noa_nr == 0) return; - for (noa_id = 0; noa_id < rtwvif->last_noa_nr; noa_id++) { - if (noa_id == rtwvif->last_noa_nr - 1) + for (noa_id = 0; noa_id < rtwvif_link->last_noa_nr; noa_id++) { + if (noa_id == rtwvif_link->last_noa_nr - 1) act = RTW89_P2P_ACT_TERMINATE; else act = RTW89_P2P_ACT_REMOVE; - rtw89_tsf32_toggle(rtwdev, rtwvif, act); + rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id); } } @@ -232,7 +236,7 @@ static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_p2p_noa_desc *desc; enum rtw89_p2pps_action act; u8 noa_id; @@ -246,10 +250,10 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev, act = RTW89_P2P_ACT_INIT; else act = RTW89_P2P_ACT_UPDATE; - rtw89_tsf32_toggle(rtwdev, rtwvif, act); + rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id); } - rtwvif->last_noa_nr = noa_id; + rtwvif_link->last_noa_nr = noa_id; } void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) @@ -261,7 +265,7 @@ void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) void rtw89_recalc_lps(struct rtw89_dev *rtwdev) { struct ieee80211_vif *vif, *found_vif = NULL; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; enum rtw89_entity_mode mode; int count = 0; @@ -269,8 +273,8 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev) if (mode == RTW89_ENTITY_MODE_MCC) goto disable_lps; - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - vif = rtwvif_to_vif(rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + vif = rtwvif_to_vif(rtwvif_link); if (vif->type != NL80211_IFTYPE_STATION) { count = 0; @@ -291,9 +295,9 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev) rtwdev->lps_enabled = false; } -void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif) +void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link) { - struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa; + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; struct rtw89_p2p_noa_ie *ie = &setter->ie; struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head; struct rtw89_noa_attr_head *noa_head = &ie->noa_head; @@ -318,10 +322,10 @@ void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif) noa_head->oppps_ctwindow = 0; } -void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif, +void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link, const struct ieee80211_p2p_noa_desc *desc) { - struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa; + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; struct rtw89_p2p_noa_ie *ie = &setter->ie; struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head; struct rtw89_noa_attr_head *noa_head = &ie->noa_head; @@ -338,9 +342,9 @@ void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif, ie->noa_desc[setter->noa_count++] = *desc; } -u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data) +u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data) { - struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa; + struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa; struct rtw89_p2p_noa_ie *ie = &setter->ie; void *tail; diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h index 54486e4550b6..d0be56ee16a2 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.h +++ b/drivers/net/wireless/realtek/rtw89/ps.h @@ -5,21 +5,21 @@ #ifndef __RTW89_PS_H_ #define __RTW89_PS_H_ -void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool ps_mode); void rtw89_leave_lps(struct rtw89_dev *rtwdev); void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); -void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); void rtw89_enter_ips(struct rtw89_dev *rtwdev); void rtw89_leave_ips(struct rtw89_dev *rtwdev); void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_recalc_lps(struct rtw89_dev *rtwdev); -void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif); -void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif, +void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link); +void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link, const struct ieee80211_p2p_noa_desc *desc); -u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data); +u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data); static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev) { diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index a7720a1f17a7..0fd8e132fdf0 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -793,18 +793,18 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev) { struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; struct rtw89_reg_6ghz_tpe new = {}; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; bool changed = false; - rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { const struct rtw89_reg_6ghz_tpe *tmp; const struct rtw89_chan *chan; - chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); if (chan->band_type != RTW89_BAND_6G) continue; - tmp = &rtwvif->reg_6ghz_tpe; + tmp = &rtwvif_link->reg_6ghz_tpe; if (!tmp->valid) continue; @@ -831,16 +831,16 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev) } static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool active, + struct rtw89_vif_link *rtwvif_link, bool active, unsigned int *changed) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct rtw89_reg_6ghz_tpe *tpe = &rtwvif->reg_6ghz_tpe; + struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe; memset(tpe, 0, sizeof(*tpe)); - if (!active || rtwvif->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD) + if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD) goto bottom; rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe); @@ -867,19 +867,19 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) const struct rtw89_regd *regd = regulatory->regd; enum rtw89_reg_6ghz_power sel; const struct rtw89_chan *chan; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; int count = 0; u8 index; - rtw89_for_each_rtwvif(rtwdev, rtwvif) { - chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); if (chan->band_type != RTW89_BAND_6G) continue; - if (count != 0 && rtwvif->reg_6ghz_power == sel) + if (count != 0 && rtwvif_link->reg_6ghz_power == sel) continue; - sel = rtwvif->reg_6ghz_power; + sel = rtwvif_link->reg_6ghz_power; count++; } @@ -908,35 +908,35 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) } static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool active, + struct rtw89_vif_link *rtwvif_link, bool active, unsigned int *changed) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); if (active) { switch (vif->bss_conf.power_type) { case IEEE80211_REG_VLP_AP: - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; break; case IEEE80211_REG_LPI_AP: - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI; break; case IEEE80211_REG_SP_AP: - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD; break; default: - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; break; } } else { - rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; } *changed += __rtw89_reg_6ghz_power_recalc(rtwdev); return 0; } -int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active) { unsigned int changed = 0; @@ -948,11 +948,11 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc(). */ - ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, active, &changed); + ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed); if (ret) return ret; - ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif, active, &changed); + ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed); if (ret) return ret; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 1679bd408ef3..f9766bf30e71 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -1590,10 +1590,11 @@ static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev) rtw8851b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); } -static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx); @@ -1608,10 +1609,12 @@ static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev, rtw8851b_tssi_scan(rtwdev, phy_idx, chan); } -static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { - rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx); + rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); } static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index dde96bd63021..42d369d2e916 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -1350,10 +1350,11 @@ static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev) rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true, RTW89_CHANCTX_0); } -static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx); rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx); @@ -1368,10 +1369,11 @@ static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev, rtw8852a_tssi_scan(rtwdev, phy_idx, chan); } -static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { - rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx); + rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx); } static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 12be52f76427..364aa21cbd44 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -562,10 +562,11 @@ static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev) rtw8852b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); } -static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx); @@ -580,10 +581,12 @@ static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, rtw8852b_tssi_scan(rtwdev, phy_idx, chan); } -static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { - rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx); + rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); } static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index 7dfdcb5964e1..dab7e71ec6a1 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -535,10 +535,11 @@ static void rtw8852bt_rfk_init(struct rtw89_dev *rtwdev) rtw8852bt_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0); } -static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx); rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx); @@ -553,10 +554,12 @@ static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev, rtw8852bt_tssi_scan(rtwdev, phy_idx, chan); } -static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { - rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx); + rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx, + rtwvif_link->chanctx_idx); } static void rtw8852bt_rfk_track(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 1c6e89ab0f4b..dbe77abb2c48 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1846,10 +1846,11 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false); } -static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; rtw8852c_mcc_get_ch_info(rtwdev, phy_idx); rtw8852c_rx_dck(rtwdev, phy_idx, false); @@ -1866,10 +1867,11 @@ static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev, rtw8852c_tssi_scan(rtwdev, phy_idx, chan); } -static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { - rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx); + rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx); } static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index c2be460f6238..2aff7e29992f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2020,11 +2020,12 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) } } -static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx; + enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); - enum rtw89_phy_idx phy_idx = rtwvif->phy_idx; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); u32 tx_en; @@ -2050,7 +2051,8 @@ static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev, rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6); } -static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, +static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool start) { } diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 5fc2faa9ba5a..2058f4bf271d 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -298,25 +298,25 @@ static void drv_resume_rx(struct rtw89_ser *ser) clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags); } -static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; - rtwvif->trigger = false; - rtwvif->tdls_peer = 0; + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; + rtwvif_link->trigger = false; + rtwvif_link->tdls_peer = 0; } static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data; + struct rtw89_vif_link *target_rtwvif = (struct rtw89_vif_link *)data; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; - if (rtwvif != target_rtwvif) + if (rtwvif_link != target_rtwvif) return; - if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); if (sta->tdls) rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); @@ -324,28 +324,28 @@ static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) INIT_LIST_HEAD(&rtwsta->ba_cam_list); } -static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { ieee80211_iterate_stations_atomic(rtwdev->hw, ser_sta_deinit_cam_iter, - rtwvif); + rtwvif_link); - rtw89_cam_deinit(rtwdev, rtwvif); + rtw89_cam_deinit(rtwdev, rtwvif_link); bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM); } static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; rtw89_cam_reset_keys(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - ser_deinit_cam(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + ser_deinit_cam(rtwdev, rtwvif_link); rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - ser_reset_vif(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + ser_reset_vif(rtwdev, rtwvif_link); rtwdev->total_sta_assoc = 0; } diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h index e669544cafd3..a5e87a8d8642 100644 --- a/drivers/net/wireless/realtek/rtw89/util.h +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -21,14 +21,14 @@ * twice cause the list to be added twice. */ static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev, - struct rtw89_vif *new) + struct rtw89_vif_link *new) { - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; lockdep_assert_held(&rtwdev->mutex); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - if (rtwvif == new) + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + if (rtwvif_link == new) return true; return false; diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 86e24e07780d..5902eb37d618 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -682,26 +682,26 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; - __rtw89_enter_ps_mode(rtwdev, rtwvif); + __rtw89_enter_ps_mode(rtwdev, rtwvif_link); } static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; if (rtw89_wow_mgd_linked(rtwdev)) - rtw89_enter_lps(rtwdev, rtwvif, false); + rtw89_enter_lps(rtwdev, rtwvif_link, false); else if (rtw89_wow_no_link(rtwdev)) - rtw89_fw_h2c_fwips(rtwdev, rtwvif, true); + rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true); } static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; if (rtw89_wow_mgd_linked(rtwdev)) { rtw89_leave_lps(rtwdev); @@ -709,7 +709,7 @@ static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) if (enable_wow) rtw89_leave_ips(rtwdev); else - rtw89_fw_h2c_fwips(rtwdev, rtwvif, false); + rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false); } } @@ -789,10 +789,11 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) GFP_KERNEL); } -static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); /* Current WoWLAN function support setting of only vif in * infra mode or no link mode. When one suitable vif is found, @@ -801,7 +802,7 @@ static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvi if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION) return; - switch (rtwvif->net_type) { + switch (rtwvif_link->net_type) { case RTW89_NET_TYPE_INFRA: if (rtw_wow_has_mgd_features(rtwdev)) rtw_wow->wow_vif = vif; @@ -865,7 +866,7 @@ static u16 rtw89_calc_crc(u8 *pdata, int length) return ~crc; } -static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif, +static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link, struct rtw89_wow_cam_info *rtw_pattern, const u8 *pattern, u8 da_mask) { @@ -885,7 +886,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif, rtw_pattern->bc = true; else if (is_multicast_ether_addr(da)) rtw_pattern->mc = true; - else if (ether_addr_equal(da, rtwvif->mac_addr) && + else if (ether_addr_equal(da, rtwvif_link->mac_addr) && da_mask == GENMASK(5, 0)) rtw_pattern->uc = true; else if (!da_mask) /*da_mask == 0 mean wildcard*/ @@ -897,7 +898,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif, } static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, const struct cfg80211_pkt_pattern *pkt_pattern, struct rtw89_wow_cam_info *rtw_pattern) { @@ -916,7 +917,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, mask_len = DIV_ROUND_UP(len, 8); memset(rtw_pattern, 0, sizeof(*rtw_pattern)); - ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern, + ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern, mask[0] & GENMASK(5, 0)); if (ret) return ret; @@ -970,7 +971,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, } static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, + struct rtw89_vif_link *rtwvif_link, struct cfg80211_wowlan *wowlan) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; @@ -983,7 +984,7 @@ static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev, for (i = 0; i < wowlan->n_patterns; i++) { rtw_pattern = &rtw_wow->patterns[i]; - ret = rtw89_wow_pattern_generate(rtwdev, rtwvif, + ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link, &wowlan->patterns[i], rtw_pattern); if (ret) { @@ -1066,7 +1067,7 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct rtw89_vif *rtwvif; + struct rtw89_vif_link *rtwvif_link; if (wowlan->disconnect) set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); @@ -1078,36 +1079,36 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, if (wowlan->nd_config) rtw89_wow_init_pno(rtwdev, wowlan->nd_config); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_wow_vif_iter(rtwdev, rtwvif); + rtw89_for_each_rtwvif(rtwdev, rtwvif_link) + rtw89_wow_vif_iter(rtwdev, rtwvif_link); if (!rtw_wow->wow_vif) return -EPERM; - rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; - return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan); + rtwvif_link = (struct rtw89_vif_link *)rtw_wow->wow_vif->drv_priv; + return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan); } static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; int ret; - ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, true); + ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true); if (ret) { rtw89_err(rtwdev, "failed to config pno\n"); return ret; } - ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow); + ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); if (ret) { rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); return ret; } - ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow); + ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); if (ret) { rtw89_err(rtwdev, "failed to fw wow global\n"); return ret; @@ -1120,33 +1121,33 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; struct ieee80211_sta *wow_sta; struct rtw89_sta *rtwsta = NULL; int ret; - wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); + wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); if (wow_sta) rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; if (wow) { if (rtw_wow->pattern_cnt) - rtwvif->wowlan_pattern = true; + rtwvif_link->wowlan_pattern = true; if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) - rtwvif->wowlan_magic = true; + rtwvif_link->wowlan_magic = true; } else { - rtwvif->wowlan_pattern = false; - rtwvif->wowlan_magic = false; + rtwvif_link->wowlan_pattern = false; + rtwvif_link->wowlan_magic = false; } - ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow); + ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); if (ret) { rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); return ret; } if (wow) { - ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); + ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta); if (ret) { rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", ret); @@ -1154,13 +1155,13 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) } } - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; } - ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow); + ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); if (ret) { rtw89_err(rtwdev, "failed to fw wow global\n"); return ret; @@ -1191,7 +1192,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; const struct rtw89_chip_info *chip = rtwdev->chip; bool include_bb = !!chip->bbmcu_nr; @@ -1204,7 +1205,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) if (chip_id == RTL8852C || chip_id == RTL8922A) disable_intr_for_dlfw = true; - wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); + wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); if (wow_sta) rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; else @@ -1224,7 +1225,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) rtw89_phy_init_rf_reg(rtwdev, true); - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, RTW89_ROLE_FW_RESTORE); if (ret) { rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); @@ -1240,20 +1241,20 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) if (!is_conn) rtw89_cam_reset_keys(rtwdev); - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, !is_conn); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; } if (is_conn) { - ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta->mac_id); if (ret) { rtw89_warn(rtwdev, "failed to send h2c general packet\n"); return ret; @@ -1377,7 +1378,7 @@ static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) } static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct list_head *pkt_list = &rtw_wow->pno_pkt_list; @@ -1391,7 +1392,7 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, } static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; @@ -1401,7 +1402,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, int ret; for (i = 0; i < num; i++) { - skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, nd_config->match_sets[i].ssid.ssid, nd_config->match_sets[i].ssid.ssid_len, nd_config->ie_len); @@ -1413,7 +1414,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { kfree_skb(skb); - rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif); + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); return -ENOMEM; } @@ -1421,7 +1422,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, if (ret) { kfree_skb(skb); kfree(info); - rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif); + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); return ret; } @@ -1437,19 +1438,19 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; int interval = rtw_wow->nd_config->scan_plans[0].interval; struct rtw89_scan_option opt = {}; int ret; if (enable) { - ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif); + ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link); if (ret) { rtw89_err(rtwdev, "Update probe request failed\n"); return ret; } - ret = mac->add_chan_list_pno(rtwdev, rtwvif); + ret = mac->add_chan_list_pno(rtwdev, rtwvif_link); if (ret) { rtw89_err(rtwdev, "Update channel list failed\n"); return ret; @@ -1471,7 +1472,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) opt.opch_end = RTW89_CHAN_INVALID; } - mac->scan_offload(rtwdev, &opt, rtwvif, true); + mac->scan_offload(rtwdev, &opt, rtwvif_link, true); return 0; } @@ -1480,7 +1481,7 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; int ret; if (rtw89_wow_no_link(rtwdev)) { @@ -1499,25 +1500,25 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) rtw89_wow_pattern_write(rtwdev); rtw89_wow_construct_key_info(rtwdev); - ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true); + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true); if (ret) { rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); return ret; } - ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true); + ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true); if (ret) { rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n"); return ret; } - ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, true); + ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true); if (ret) { rtw89_err(rtwdev, "wow: failed to enable GTK offload\n"); return ret; } - ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, true); + ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true); if (ret) rtw89_warn(rtwdev, "wow: failed to enable arp offload\n"); } @@ -1549,7 +1550,7 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; int ret; if (rtw89_wow_no_link(rtwdev)) { @@ -1559,35 +1560,35 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) return ret; } - ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, false); + ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false); if (ret) { rtw89_err(rtwdev, "wow: failed to disable pno\n"); return ret; } - rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif); + rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); } else { rtw89_wow_pattern_clear(rtwdev); - ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false); + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false); if (ret) { rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); return ret; } - ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); + ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false); if (ret) { rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); return ret; } - ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, false); + ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false); if (ret) { rtw89_err(rtwdev, "wow: failed to disable GTK offload\n"); return ret; } - ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, false); + ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false); if (ret) rtw89_warn(rtwdev, "wow: failed to disable arp offload\n"); diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h index 3fbc2b87c058..a80b4b84587d 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.h +++ b/drivers/net/wireless/realtek/rtw89/wow.h @@ -98,17 +98,17 @@ static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev) static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; - return rtwvif->net_type == RTW89_NET_TYPE_INFRA; + return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA; } static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; - return rtwvif->net_type == RTW89_NET_TYPE_NO_LINK; + return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK; } static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev) From 9ee282193440527a20c9b40d47db8abaa73ecd49 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:53 +0800 Subject: [PATCH 020/126] wifi: rtw89: rename rtw89_sta to rtw89_sta_link ahead for MLO This is an intermediate version that is separated from subsequent major MLO changes, so some functions' namings are not really determined here. e.g. struct rtw89_sta_link *sta_to_rtwsta_safe(struct ieee80211_sta *sta) No logic is changed. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 43 ++-- drivers/net/wireless/realtek/rtw89/cam.h | 8 +- drivers/net/wireless/realtek/rtw89/chan.c | 6 +- drivers/net/wireless/realtek/rtw89/coex.c | 57 +++--- drivers/net/wireless/realtek/rtw89/coex.h | 3 +- drivers/net/wireless/realtek/rtw89/core.c | 193 +++++++++--------- drivers/net/wireless/realtek/rtw89/core.h | 48 ++--- drivers/net/wireless/realtek/rtw89/debug.c | 50 ++--- drivers/net/wireless/realtek/rtw89/fw.c | 102 ++++----- drivers/net/wireless/realtek/rtw89/fw.h | 36 ++-- drivers/net/wireless/realtek/rtw89/mac.c | 60 +++--- drivers/net/wireless/realtek/rtw89/mac.h | 8 +- drivers/net/wireless/realtek/rtw89/mac80211.c | 39 ++-- drivers/net/wireless/realtek/rtw89/phy.c | 80 ++++---- drivers/net/wireless/realtek/rtw89/ser.c | 10 +- drivers/net/wireless/realtek/rtw89/wow.c | 20 +- 16 files changed, 392 insertions(+), 371 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index a3e6d40b3078..80deb0712b83 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -217,7 +217,7 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, 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 = sta_to_rtwsta_safe(sta); struct rtw89_vif_link *rtwvif_link; struct rtw89_addr_cam_entry *addr_cam; unsigned int i; @@ -229,7 +229,7 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, } rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - addr_cam = rtw89_get_addr_cam_of(rtwvif_link, 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 +239,11 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, } if (inform_fw) { - ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, 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_link, 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); } @@ -257,7 +257,7 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, 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 = sta_to_rtwsta_safe(sta); struct rtw89_vif_link *rtwvif_link; struct rtw89_addr_cam_entry *addr_cam; u8 key_idx = 0; @@ -269,7 +269,7 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, } rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - addr_cam = rtw89_get_addr_cam_of(rtwvif_link, 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 +285,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_link, 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_link, 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); @@ -653,11 +653,11 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, u8 *cmd) + struct rtw89_sta_link *rtwsta_link, u8 *cmd) { struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, - rtwsta); + rtwsta_link); u8 bss_color = vif->bss_conf.he_bss_color.color; u8 bss_mask; @@ -697,14 +697,14 @@ 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_link *rtwvif_link, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, u8 *cmd) { struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_addr_cam_entry *addr_cam = - rtw89_get_addr_cam_of(rtwvif_link, rtwsta); - struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta); + rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); + struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta_link); 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; @@ -757,7 +757,8 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, 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 ? rtwsta->mac_id : rtwvif_link->mac_id); + 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_link->net_type == RTW89_NET_TYPE_AP_MODE) @@ -787,15 +788,16 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, + 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_link, rtwsta); + 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_link->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); @@ -867,15 +869,16 @@ 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_link *rtwvif_link, - struct rtw89_sta *rtwsta, + 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_link, rtwsta); + 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_link->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); diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h index 18ede69144b6..a6f72edd30fe 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.h +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -541,19 +541,19 @@ 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_link *vif, - struct rtw89_sta *rtwsta, + 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_link *rtwvif_link, - struct rtw89_sta *rtwsta, + 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_link *rtwvif_link, - struct rtw89_sta *rtwsta, + 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_link *rtwvif_link, - struct rtw89_sta *rtwsta, u8 *cmd); + 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, diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index f20431c3e201..2f14ac668716 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -522,15 +522,15 @@ u32 rtw89_mcc_role_fw_macid_bitmap_to_u32(struct rtw89_mcc_role *mcc_role) static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_mcc_role *mcc_role = data; struct rtw89_vif_link *target = mcc_role->rtwvif_link; if (rtwvif_link != target) return; - rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta->mac_id); + rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id); } static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index af9f975983ae..174e79b73352 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4991,11 +4991,11 @@ struct rtw89_txtime_data { static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_txtime_data *iter_data = (struct rtw89_txtime_data *)data; struct rtw89_dev *rtwdev = iter_data->rtwdev; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; @@ -5023,8 +5023,8 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) /* backup the original tx time before tx-limit on */ if (reenable) { - rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time); - rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry); + rtw89_mac_get_tx_time(rtwdev, rtwsta_link, &plink->tx_time); + rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, &plink->tx_retry); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n", __func__, plink->tx_time, plink->tx_retry); @@ -5032,16 +5032,16 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) /* restore the original tx time if no tx-limit */ if (!enable) { - rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time); - rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true, + rtw89_mac_set_tx_time(rtwdev, rtwsta_link, true, plink->tx_time); + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, true, plink->tx_retry); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): restore, tx_time=%d tx_retry= %d\n", __func__, plink->tx_time, plink->tx_retry); } else { - rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time); - rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry); + rtw89_mac_set_tx_time(rtwdev, rtwsta_link, false, tx_time); + rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, tx_retry); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): set, tx_time=%d tx_retry= %d\n", __func__, tx_time, tx_retry); @@ -7481,12 +7481,13 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, enum btc_role_state state) + struct rtw89_sta_link *rtwsta_link, + enum btc_role_state state) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_wl_info *wl = &btc->cx.wl; @@ -7507,9 +7508,9 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, "[BTC], bcn_period=%d dtim_period=%d\n", vif->bss_conf.beacon_int, vif->bss_conf.dtim_period); - if (rtwsta) { + if (rtwsta_link) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", - rtwsta->mac_id); + rtwsta_link->mac_id); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA support HE=%d VHT=%d HT=%d\n", @@ -7548,8 +7549,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, r.chdef.chan = chan->primary_channel; ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr); - if (rtwsta && vif->type == NL80211_IFTYPE_STATION) - r.mac_id = rtwsta->mac_id; + if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION) + r.mac_id = rtwsta_link->mac_id; btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++; @@ -7790,9 +7791,9 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_link_info *link_info = NULL; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_traffic_stats *link_info_t = NULL; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_traffic_stats *stats = &rtwvif_link->stats; const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc_wl_role_info *r; @@ -7807,7 +7808,7 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) u8 i = 0; bool is_sta_change = false, is_traffic_change = false; - rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; + rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); link_info = &wl->link_info[port]; @@ -7859,19 +7860,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) iter_data->busy_all |= busy; iter_data->dir_all |= BIT(dir); - if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 && + if (rtwsta_link->rx_hw_rate <= RTW89_HW_RATE_CCK2 && last_rx_rate > RTW89_HW_RATE_CCK2 && link_info_t->rx_tfc_lv > RTW89_TFC_IDLE) link_info->rx_rate_drop_cnt++; - if (last_tx_rate != rtwsta->ra_report.hw_rate || - last_rx_rate != rtwsta->rx_hw_rate || + if (last_tx_rate != rtwsta_link->ra_report.hw_rate || + last_rx_rate != rtwsta_link->rx_hw_rate || last_tx_lvl != link_info_t->tx_tfc_lv || last_rx_lvl != link_info_t->rx_tfc_lv) is_traffic_change = true; - link_info_t->tx_rate = rtwsta->ra_report.hw_rate; - link_info_t->rx_rate = rtwsta->rx_hw_rate; + link_info_t->tx_rate = rtwsta_link->ra_report.hw_rate; + link_info_t->rx_rate = rtwsta_link->rx_hw_rate; if (link_info->role == RTW89_WIFI_ROLE_STATION || link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) { @@ -7883,19 +7884,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) r = &wl->role_info; r->active_role[port].tx_lvl = stats->tx_tfc_lv; r->active_role[port].rx_lvl = stats->rx_tfc_lv; - r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate; - r->active_role[port].rx_rate = rtwsta->rx_hw_rate; + r->active_role[port].tx_rate = rtwsta_link->ra_report.hw_rate; + r->active_role[port].rx_rate = rtwsta_link->rx_hw_rate; } else if (ver->fwlrole == 1) { r1 = &wl->role_info_v1; r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv; r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv; - r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate; - r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate; + r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate; + r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate; } else if (ver->fwlrole == 2) { dm->trx_info.tx_lvl = stats->tx_tfc_lv; dm->trx_info.rx_lvl = stats->rx_tfc_lv; - dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate; - dm->trx_info.rx_rate = rtwsta->rx_hw_rate; + dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate; + dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate; } dm->trx_info.tx_tp = link_info_t->tx_throughput; diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h index 2a3bd1ead7c3..dbdb56e063ef 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.h +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -273,7 +273,8 @@ void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work); void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work); void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, enum btc_role_state state); + struct rtw89_sta_link *rtwsta_link, + enum btc_role_state state); void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, enum btc_wl_rfk_type type, diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 314c2e2ef8e9..2b6a8fe0e53b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -466,7 +466,7 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta = tx_req->sta; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; - struct rtw89_sta *rtwsta; + struct rtw89_sta_link *rtwsta_link; u8 ampdu_num; u8 tid; @@ -484,10 +484,10 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, } tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - rtwsta = (struct rtw89_sta *)sta->drv_priv; + rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? - rtwsta->ampdu_params[tid].agg_num : + ampdu_num = (u8)((rtwsta_link->ampdu_params[tid].agg_num ? + rtwsta_link->ampdu_params[tid].agg_num : 4 << sta->deflink.ht_cap.ampdu_factor) - 1); desc_info->agg_en = true; @@ -593,13 +593,13 @@ static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif = tx_req->vif; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta *rtwsta; + struct rtw89_sta_link *rtwsta_link; if (!sta) return rtwvif_link->mac_id; - rtwsta = (struct rtw89_sta *)sta->drv_priv; - return rtwsta->mac_id; + rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + return rtwsta_link->mac_id; } static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev, @@ -702,7 +702,7 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, enum btc_pkt_type pkt_type) { struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); struct sk_buff *skb = tx_req->skb; struct ieee80211_hdr *hdr = (void *)skb->data; __le16 fc = hdr->frame_control; @@ -720,7 +720,7 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN) return false; - if (rtwsta && rtwsta->ra_report.might_fallback_legacy) + if (rtwsta_link && rtwsta_link->ra_report.might_fallback_legacy) return false; return true; @@ -731,7 +731,7 @@ __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct sk_buff *skb = tx_req->skb; struct ieee80211_hdr *hdr = (void *)skb->data; __le16 fc = hdr->frame_control; @@ -747,7 +747,7 @@ __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, hdr = data; htc = data + hdr_len; hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER); - *htc = rtwsta->htc_template ? rtwsta->htc_template : + *htc = rtwsta_link->htc_template ? rtwsta_link->htc_template : le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID); @@ -814,7 +814,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_sta *sta = tx_req->sta; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; u8 tid, tid_indicate; @@ -830,9 +830,9 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, desc_info->qsel = qsel; desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; - desc_info->er_cap = rtwsta ? rtwsta->er_cap : false; - desc_info->stbc = rtwsta ? rtwsta->ra.stbc_cap : false; - desc_info->ldpc = rtwsta ? rtwsta->ra.ldpc_cap : false; + desc_info->er_cap = rtwsta_link ? rtwsta_link->er_cap : false; + desc_info->stbc = rtwsta_link ? rtwsta_link->ra.stbc_cap : false; + desc_info->ldpc = rtwsta_link ? rtwsta_link->ra.ldpc_cap : false; /* enable wd_info for AMPDU */ desc_info->en_wd_info = true; @@ -1514,16 +1514,16 @@ static u8 rtw89_get_data_rate_nss(struct rtw89_dev *rtwdev, u16 data_rate) static void rtw89_core_rx_process_phy_ppdu_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; u8 ant_pos = U8_MAX; u8 evm_pos = 0; int i; - if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) + if (rtwsta_link->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) return; if (hal->ant_diversity && hal->antenna_rx) { @@ -1531,22 +1531,24 @@ static void rtw89_core_rx_process_phy_ppdu_iter(void *data, evm_pos = ant_pos; } - ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); + ewma_rssi_add(&rtwsta_link->avg_rssi, phy_ppdu->rssi_avg); if (ant_pos < ant_num) { - ewma_rssi_add(&rtwsta->rssi[ant_pos], phy_ppdu->rssi[0]); + ewma_rssi_add(&rtwsta_link->rssi[ant_pos], phy_ppdu->rssi[0]); } else { for (i = 0; i < rtwdev->chip->rf_path_num; i++) - ewma_rssi_add(&rtwsta->rssi[i], phy_ppdu->rssi[i]); + ewma_rssi_add(&rtwsta_link->rssi[i], phy_ppdu->rssi[i]); } if (phy_ppdu->ofdm.has && (phy_ppdu->has_data || phy_ppdu->has_bcn)) { - ewma_snr_add(&rtwsta->avg_snr, phy_ppdu->ofdm.avg_snr); + ewma_snr_add(&rtwsta_link->avg_snr, phy_ppdu->ofdm.avg_snr); if (rtw89_get_data_rate_nss(rtwdev, phy_ppdu->rate) == 1) { - ewma_evm_add(&rtwsta->evm_1ss, phy_ppdu->ofdm.evm_min); + ewma_evm_add(&rtwsta_link->evm_1ss, phy_ppdu->ofdm.evm_min); } else { - ewma_evm_add(&rtwsta->evm_min[evm_pos], phy_ppdu->ofdm.evm_min); - ewma_evm_add(&rtwsta->evm_max[evm_pos], phy_ppdu->ofdm.evm_max); + ewma_evm_add(&rtwsta_link->evm_min[evm_pos], + phy_ppdu->ofdm.evm_min); + ewma_evm_add(&rtwsta_link->evm_max[evm_pos], + phy_ppdu->ofdm.evm_max); } } } @@ -2432,15 +2434,15 @@ void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) struct rtw89_core_iter_rx_status *iter_data = (struct rtw89_core_iter_rx_status *)data; struct ieee80211_rx_status *rx_status = iter_data->rx_status; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; u8 mac_id = iter_data->mac_id; - if (mac_id != rtwsta->mac_id) + if (mac_id != rtwsta_link->mac_id) return; - rtwsta->rx_status = *rx_status; - rtwsta->rx_hw_rate = desc_info->data_rate; + rtwsta_link->rx_status = *rx_status; + rtwsta_link->rx_hw_rate = desc_info->data_rate; } static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev, @@ -2658,7 +2660,8 @@ static void rtw89_core_ba_work(struct work_struct *work) list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; + struct rtw89_sta_link *rtwsta_link = + sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; u8 tid = txq->tid; if (!sta) { @@ -2666,7 +2669,7 @@ static void rtw89_core_ba_work(struct work_struct *work) goto skip_ba_work; } - if (rtwsta->disassoc) { + if (rtwsta_link->disassoc) { rtw89_debug(rtwdev, RTW89_DBG_TXRX, "cannot start BA with disassoc sta\n"); goto skip_ba_work; @@ -2721,11 +2724,11 @@ static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct sk_buff *skb, *tmp; - skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { - skb_unlink(skb, &rtwsta->roc_queue); + skb_queue_walk_safe(&rtwsta_link->roc_queue, skb, tmp) { + skb_unlink(skb, &rtwsta_link->roc_queue); dev_kfree_skb_any(skb); } } @@ -2735,9 +2738,9 @@ static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, { struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); - if (unlikely(!rtwsta) || unlikely(rtwsta->disassoc)) + if (unlikely(!rtwsta_link) || unlikely(rtwsta_link->disassoc)) return; if (!test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags) || @@ -2762,7 +2765,8 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; + struct rtw89_sta_link *rtwsta_link = + sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) return; @@ -2784,7 +2788,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, } spin_lock_bh(&rtwdev->ba_lock); - if (!rtwsta->disassoc && list_empty(&rtwtxq->list)) { + if (!rtwsta_link->disassoc && list_empty(&rtwtxq->list)) { list_add_tail(&rtwtxq->list, &rtwdev->ba_list); ieee80211_queue_work(hw, &rtwdev->ba_work); } @@ -2839,9 +2843,10 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, { struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; + struct rtw89_sta_link *rtwsta_link = + sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; - if (!sta || rtwsta->max_agg_wait <= 0) + if (!sta || rtwsta_link->max_agg_wait <= 0) return false; if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) @@ -2855,7 +2860,7 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, return false; } - if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) { + if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta_link->max_agg_wait) { *reinvoke = true; rtwtxq->wait_cnt++; return true; @@ -2955,9 +2960,9 @@ static void rtw89_forbid_ba_work(struct work_struct *w) static void rtw89_core_sta_pending_tx_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_vif_link *rtwvif_target = data; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct sk_buff *skb, *tmp; @@ -2966,11 +2971,11 @@ static void rtw89_core_sta_pending_tx_iter(void *data, if (rtwvif_link->chanctx_idx != rtwvif_target->chanctx_idx) return; - if (skb_queue_len(&rtwsta->roc_queue) == 0) + if (skb_queue_len(&rtwsta_link->roc_queue) == 0) return; - skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { - skb_unlink(skb, &rtwsta->roc_queue); + skb_queue_walk_safe(&rtwsta_link->roc_queue, skb, tmp) { + skb_unlink(skb, &rtwsta_link->roc_queue); ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); if (ret) { @@ -3328,7 +3333,8 @@ void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits) } int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx) { const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_cam_info *cam_info = &rtwdev->cam_info; @@ -3365,7 +3371,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, } entry->tid = tid; - list_add_tail(&entry->list, &rtwsta->ba_cam_list); + list_add_tail(&entry->list, &rtwsta_link->ba_cam_list); *cam_idx = idx; @@ -3373,7 +3379,8 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, } int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx) { struct rtw89_cam_info *cam_info = &rtwdev->cam_info; struct rtw89_ba_cam_entry *entry = NULL, *tmp; @@ -3381,7 +3388,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, lockdep_assert_held(&rtwdev->mutex); - list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) { + list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) { if (entry->tid != tid) continue; @@ -3459,67 +3466,67 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; int i; int ret; - rtwsta->rtwdev = rtwdev; - rtwsta->rtwvif_link = rtwvif_link; - rtwsta->prev_rssi = 0; - INIT_LIST_HEAD(&rtwsta->ba_cam_list); - skb_queue_head_init(&rtwsta->roc_queue); + rtwsta_link->rtwdev = rtwdev; + rtwsta_link->rtwvif_link = rtwvif_link; + rtwsta_link->prev_rssi = 0; + INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); + skb_queue_head_init(&rtwsta_link->roc_queue); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) rtw89_core_txq_init(rtwdev, sta->txq[i]); - ewma_rssi_init(&rtwsta->avg_rssi); - ewma_snr_init(&rtwsta->avg_snr); - ewma_evm_init(&rtwsta->evm_1ss); + ewma_rssi_init(&rtwsta_link->avg_rssi); + ewma_snr_init(&rtwsta_link->avg_snr); + ewma_evm_init(&rtwsta_link->evm_1ss); for (i = 0; i < ant_num; i++) { - ewma_rssi_init(&rtwsta->rssi[i]); - ewma_evm_init(&rtwsta->evm_min[i]); - ewma_evm_init(&rtwsta->evm_max[i]); + ewma_rssi_init(&rtwsta_link->rssi[i]); + ewma_evm_init(&rtwsta_link->evm_min[i]); + ewma_evm_init(&rtwsta_link->evm_max[i]); } if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { /* for station mode, assign the mac_id from itself */ - rtwsta->mac_id = rtwvif_link->mac_id; + rtwsta_link->mac_id = rtwvif_link->mac_id; /* must do rtw89_reg_6ghz_recalc() before rfk channel */ ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); if (ret) return ret; - rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, BTC_ROLE_MSTS_STA_CONN_START); rtw89_chip_rfk_channel(rtwdev, rtwvif_link); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtwsta->mac_id = rtw89_acquire_mac_id(rtwdev); - if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) + rtwsta_link->mac_id = rtw89_acquire_mac_id(rtwdev); + if (rtwsta_link->mac_id == RTW89_MAX_MAC_ID_NUM) return -ENOSPC; - ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false); + ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false); if (ret) { - rtw89_release_mac_id(rtwdev, rtwsta->mac_id); + rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); return ret; } - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, RTW89_ROLE_CREATE); if (ret) { - rtw89_release_mac_id(rtwdev, rtwsta->mac_id); + rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); rtw89_warn(rtwdev, "failed to send h2c role info\n"); return ret; } - ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta); + ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) return ret; - ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta); + ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) return ret; @@ -3534,7 +3541,7 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; if (vif->type == NL80211_IFTYPE_STATION) rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, false); @@ -3542,7 +3549,7 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, rtwdev->total_sta_assoc--; if (sta->tdls) rtwvif_link->tdls_peer--; - rtwsta->disassoc = true; + rtwsta_link->disassoc = true; return 0; } @@ -3552,7 +3559,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; int ret; rtw89_mac_bf_monitor_calc(rtwdev, sta, true); @@ -3562,9 +3569,9 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); if (vif->type == NL80211_IFTYPE_AP || sta->tdls) - rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); if (sta->tdls) - rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { rtw89_vif_type_mapping(vif, false); @@ -3577,14 +3584,14 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, true); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, true); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } /* update cam aid mac_id net_type */ - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; @@ -3598,9 +3605,9 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, - rtwsta); + rtwsta_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); int ret; @@ -3615,7 +3622,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, } } - ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta->addr_cam, bssid_cam); + ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta_link->addr_cam, bssid_cam); if (ret) { rtw89_warn(rtwdev, "failed to send h2c init addr cam\n"); return ret; @@ -3628,14 +3635,14 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, false); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, false); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } /* update cam aid mac_id net_type */ - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; @@ -3653,14 +3660,14 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, if (bss_conf->he_support && !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) - rtwsta->er_cap = true; + rtwsta_link->er_cap = true; - rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, BTC_ROLE_MSTS_STA_CONN_END); - rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template, chan); + rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan); rtw89_phy_ul_tb_assoc(rtwdev, rtwvif_link); - ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta->mac_id); + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); if (ret) { rtw89_warn(rtwdev, "failed to send h2c general packet\n"); return ret; @@ -3677,17 +3684,17 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; int ret; if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, BTC_ROLE_MSTS_STA_DIS_CONN); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtw89_release_mac_id(rtwdev, rtwsta->mac_id); + rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, RTW89_ROLE_REMOVE); if (ret) { rtw89_warn(rtwdev, "failed to send h2c role info\n"); @@ -4703,7 +4710,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) int tx_headroom = IEEE80211_HT_CTL_LEN; hw->vif_data_size = sizeof(struct rtw89_vif_link); - hw->sta_data_size = sizeof(struct rtw89_sta); + hw->sta_data_size = sizeof(struct rtw89_sta_link); hw->txq_data_size = sizeof(struct rtw89_txq); hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 21e0099d6324..aa0627ce4cd1 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3354,7 +3354,7 @@ struct rtw89_sec_cam_entry { u8 key[32]; }; -struct rtw89_sta { +struct rtw89_sta_link { u8 mac_id; bool disassoc; bool er_cap; @@ -3647,10 +3647,10 @@ struct rtw89_chip_ops { int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en); int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -3659,10 +3659,10 @@ struct rtw89_chip_ops { struct ieee80211_sta *sta); int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int (*h2c_update_beacon)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); - int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, + int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); void (*btc_set_rfe)(struct rtw89_dev *rtwdev); @@ -5978,21 +5978,21 @@ static inline struct rtw89_vif_link *vif_to_rtwvif_safe(struct ieee80211_vif *vi return vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; } -static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) +static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta_link *rtwsta_link) { - void *p = rtwsta; + void *p = rtwsta_link; return container_of(p, struct ieee80211_sta, drv_priv); } -static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta) +static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta_link *rtwsta_link) { - return rtwsta ? rtwsta_to_sta(rtwsta) : NULL; + return rtwsta_link ? rtwsta_to_sta(rtwsta_link) : NULL; } -static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta) +static inline struct rtw89_sta_link *sta_to_rtwsta_safe(struct ieee80211_sta *sta) { - return sta ? (struct rtw89_sta *)sta->drv_priv : NULL; + return sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; } static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw) @@ -6080,26 +6080,26 @@ enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua) static inline struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { - if (rtwsta) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); + if (rtwsta_link) { + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) - return &rtwsta->addr_cam; + return &rtwsta_link->addr_cam; } return &rtwvif_link->addr_cam; } static inline struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { - if (rtwsta) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); + if (rtwsta_link) { + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); if (sta->tdls) - return &rtwsta->bssid_cam; + return &rtwsta_link->bssid_cam; } return &rtwvif_link->bssid_cam; } @@ -6459,13 +6459,13 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en) static inline int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; if (!chip->ops->h2c_dctl_sec_cam) return 0; - return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta); + return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); } static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) @@ -6647,9 +6647,11 @@ u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx); + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx); int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx); + struct rtw89_sta_link *rtwsta_link, u8 tid, + u8 *cam_idx); void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate); diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 26327e4b071d..f09f1a251b16 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3518,11 +3518,11 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) [NL80211_RATE_INFO_EHT_GI_1_6] = "1.6", [NL80211_RATE_INFO_EHT_GI_3_2] = "3.2", }; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rate_info *rate = &rtwsta->ra_report.txrate; - struct ieee80211_rx_status *status = &rtwsta->rx_status; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rate_info *rate = &rtwsta_link->ra_report.txrate; + struct ieee80211_rx_status *status = &rtwsta_link->rx_status; struct seq_file *m = (struct seq_file *)data; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; @@ -3531,7 +3531,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) u8 snr; int i; - seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id); + seq_printf(m, "TX rate [%d]: ", rtwsta_link->mac_id); if (rate->flags & RATE_INFO_FLAGS_MCS) seq_printf(m, "HT MCS-%d%s", rate->mcs, @@ -3549,13 +3549,13 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) eht_gi_str[rate->eht_gi] : "N/A"); else seq_printf(m, "Legacy %d", rate->legacy); - seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : ""); + seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); - seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate); - seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait, + seq_printf(m, "\t(hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); + seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, sta->deflink.agg.max_rc_amsdu_len); - seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id); + seq_printf(m, "RX rate [%d]: ", rtwsta_link->mac_id); switch (status->encoding) { case RX_ENC_LEGACY: @@ -3582,24 +3582,24 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) break; } seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); - seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate); + seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate); - rssi = ewma_rssi_read(&rtwsta->avg_rssi); + rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [", - RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi); + RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta_link->prev_rssi); for (i = 0; i < ant_num; i++) { - rssi = ewma_rssi_read(&rtwsta->rssi[i]); + rssi = ewma_rssi_read(&rtwsta_link->rssi[i]); seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi), ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", i + 1 == ant_num ? "" : ", "); } seq_puts(m, "]\n"); - evm_1ss = ewma_evm_read(&rtwsta->evm_1ss); + evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss); seq_printf(m, "EVM: [%2u.%02u, ", evm_1ss >> 2, (evm_1ss & 0x3) * 25); for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) { - evm_min = ewma_evm_read(&rtwsta->evm_min[i]); - evm_max = ewma_evm_read(&rtwsta->evm_max[i]); + evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]); + evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]); seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ", evm_min >> 2, (evm_min & 0x3) * 25, @@ -3607,7 +3607,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) } seq_puts(m, "]\t"); - snr = ewma_snr_read(&rtwsta->avg_snr); + snr = ewma_snr_read(&rtwsta_link->avg_snr); seq_printf(m, "SNR: %u\n", snr); } @@ -3752,14 +3752,14 @@ void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) "\tpkt_ofld[GENERAL]: "); } -static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) +static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct rtw89_ba_cam_entry *entry; bool first = true; - list_for_each_entry(entry, &rtwsta->ba_cam_list, list) { + list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) { if (first) { seq_puts(m, "\tba_cam "); first = false; @@ -3774,14 +3774,14 @@ static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; struct seq_file *m = (struct seq_file *)data; - seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr, + seq_printf(m, "STA [%d] %pM %s\n", rtwsta_link->mac_id, sta->addr, sta->tdls ? "(TDLS)" : ""); - rtw89_dump_addr_cam(m, rtwdev, &rtwsta->addr_cam); - rtw89_dump_ba_cam(m, rtwsta); + rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam); + rtw89_dump_ba_cam(m, rtwsta_link); } static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 5284dcecef85..59325a6995e6 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1743,7 +1743,7 @@ void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len) #define H2C_CAM_LEN 60 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, const u8 *scan_mac_addr) + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr) { struct sk_buff *skb; int ret; @@ -1754,9 +1754,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_lin return -ENOMEM; } skb_put(skb, H2C_CAM_LEN); - rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta, scan_mac_addr, + rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr, skb->data); - rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta, skb->data); + rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1779,7 +1779,7 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_lin int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { struct rtw89_h2c_dctlinfo_ud_v1 *h2c; u32 len = sizeof(*h2c); @@ -1794,7 +1794,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data; - rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta, h2c); + rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1818,7 +1818,7 @@ EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1); int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { struct rtw89_h2c_dctlinfo_ud_v2 *h2c; u32 len = sizeof(*h2c); @@ -1833,7 +1833,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data; - rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta, h2c); + rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, @@ -1857,9 +1857,9 @@ EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_dctlinfo_ud_v2 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -1910,21 +1910,23 @@ int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); -int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_h2c_ba_cam *h2c; - u8 macid = rtwsta->mac_id; + u8 macid = rtwsta_link->mac_id; u32 len = sizeof(*h2c); struct sk_buff *skb; u8 entry_idx; int ret; ret = valid ? - rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) : - rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx); + rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx) : + rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx); if (ret) { /* it still works even if we don't have static BA CAM, because * hardware can create dynamic BA CAM automatically. @@ -2042,13 +2044,13 @@ void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) } } -int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_h2c_ba_cam_v1 *h2c; - u8 macid = rtwsta->mac_id; + u8 macid = rtwsta_link->mac_id; u32 len = sizeof(*h2c); struct sk_buff *skb; u8 entry_idx; @@ -2056,8 +2058,10 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, int ret; ret = valid ? - rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) : - rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx); + rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx) : + rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid, + &entry_idx); if (ret) { /* it still works even if we don't have static BA CAM, because * hardware can create dynamic BA CAM automatically. @@ -2628,10 +2632,10 @@ static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, #define H2C_CMC_TBL_LEN 68 int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; - u8 macid = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct sk_buff *skb; int ret; @@ -2677,9 +2681,9 @@ EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl); int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -2818,13 +2822,13 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); struct sk_buff *skb; u8 pads[RTW89_PPE_BW_NUM]; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; u16 lowest_rate; int ret; @@ -2955,9 +2959,9 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u8 pads[RTW89_PPE_BW_NUM]; u32 len = sizeof(*h2c); @@ -3070,7 +3074,7 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -3087,11 +3091,11 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; - for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { + for_each_set_bit(tid, rtwsta_link->ampdu_map, IEEE80211_NUM_TIDS) { if (agg_num == 0) - agg_num = rtwsta->ampdu_params[tid].agg_num; + agg_num = rtwsta_link->ampdu_params[tid].agg_num; else - agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); + agg_num = min(agg_num, rtwsta_link->ampdu_params[tid].agg_num); } if (agg_num <= 0x20) @@ -3107,7 +3111,7 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, else if (agg_num > 0x200 && agg_num <= 0x400) ba_bmap = 5; - h2c->c0 = le32_encode_bits(rtwsta->mac_id, CCTLINFO_G7_C0_MACID) | + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) | le32_encode_bits(1, CCTLINFO_G7_C0_OP); h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP); @@ -3133,7 +3137,7 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7); int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; struct sk_buff *skb; @@ -3145,15 +3149,15 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, return -ENOMEM; } skb_put(skb, H2C_CMC_TBL_LEN); - SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); + SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); SET_CTRL_INFO_OPERATION(skb->data, 1); - if (rtwsta->cctl_tx_time) { + if (rtwsta_link->cctl_tx_time) { SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); - SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time); + SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time); } - if (rtwsta->cctl_tx_retry_limit) { + if (rtwsta_link->cctl_tx_retry_limit) { SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); - SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt); + SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt); } rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -3175,7 +3179,7 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, } int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; struct sk_buff *skb; @@ -3190,7 +3194,7 @@ int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, return -ENOMEM; } skb_put(skb, H2C_CMC_TBL_LEN); - SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); + SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id); SET_CTRL_INFO_OPERATION(skb->data, 1); __rtw89_fw_h2c_set_tx_path(rtwdev, skb); @@ -3379,16 +3383,16 @@ EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be); #define H2C_ROLE_MAINTAIN_LEN 4 int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, enum rtw89_upd_mode upd_mode) { struct sk_buff *skb; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; u8 self_role; int ret; if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { - if (rtwsta) + if (rtwsta_link) self_role = RTW89_SELF_ROLE_AP_CLIENT; else self_role = rtwvif_link->self_role; @@ -3427,9 +3431,9 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, static enum rtw89_fw_sta_type rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta); + struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta_link); struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); if (!sta) @@ -3452,10 +3456,10 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li } int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, bool dis_conn) + struct rtw89_sta_link *rtwsta_link, bool dis_conn) { struct sk_buff *skb; - u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif_link->mac_id; + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; u8 self_role = rtwvif_link->self_role; enum rtw89_fw_sta_type sta_type; u8 net_type = rtwvif_link->net_type; @@ -3470,7 +3474,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv format_v1 = true; } - if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) { + if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) { self_role = RTW89_SELF_ROLE_AP_CLIENT; net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type; } @@ -3503,7 +3507,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data; - sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta); + sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link); h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE); h2c_v1->w2 = 0; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 29d7529d25fe..7cce4e71a36a 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4460,13 +4460,13 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, bool rack, bool dack, u32 len); int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -4477,29 +4477,29 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif, - struct rtw89_sta *rtwsta, const u8 *scan_mac_addr); + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr); int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta); + struct rtw89_sta_link *rtwsta_link); void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); void rtw89_fw_c2h_work(struct work_struct *work); int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, enum rtw89_upd_mode upd_mode); int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta, bool dis_conn); + struct rtw89_sta_link *rtwsta_link, bool dis_conn); int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en); int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, bool pause); @@ -4569,9 +4569,9 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool notify_fw); void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); -int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); -int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, @@ -4679,21 +4679,21 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; - return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta); + return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); } static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_sta *rtwsta) + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->ops->h2c_default_dmac_tbl) - return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta); + return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link); return 0; } @@ -4728,12 +4728,12 @@ static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev, } static inline -int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - return chip->ops->h2c_ba_cam(rtwdev, rtwsta, valid, params); + return chip->ops->h2c_ba_cam(rtwdev, rtwsta_link, valid, params); } /* must consider compatibility; don't insert new in the mid */ diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index e1956c722436..d6cd3ed1e7fc 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -6160,18 +6160,18 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) } static int -__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, u32 tx_time) { #define MAC_AX_DFLT_TX_TIME 5280 - u8 mac_idx = rtwsta->rtwvif_link->mac_idx; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time; u32 reg; int ret = 0; - if (rtwsta->cctl_tx_time) { - rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9; - ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); + if (rtwsta_link->cctl_tx_time) { + rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9; + ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); } else { ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); if (ret) { @@ -6187,31 +6187,31 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, return ret; } -int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool resume, u32 tx_time) { int ret = 0; if (!resume) { - rtwsta->cctl_tx_time = true; - ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); + rtwsta_link->cctl_tx_time = true; + ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time); } else { - ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); - rtwsta->cctl_tx_time = false; + ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time); + rtwsta_link->cctl_tx_time = false; } return ret; } -int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, u32 *tx_time) { - u8 mac_idx = rtwsta->rtwvif_link->mac_idx; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; u32 reg; int ret = 0; - if (rtwsta->cctl_tx_time) { - *tx_time = (rtwsta->ampdu_max_time + 1) << 9; + if (rtwsta_link->cctl_tx_time) { + *tx_time = (rtwsta_link->ampdu_max_time + 1) << 9; } else { ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); if (ret) { @@ -6227,33 +6227,33 @@ int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, } int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, bool resume, u8 tx_retry) { int ret = 0; - rtwsta->data_tx_cnt_lmt = tx_retry; + rtwsta_link->data_tx_cnt_lmt = tx_retry; if (!resume) { - rtwsta->cctl_tx_retry_limit = true; - ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); + rtwsta_link->cctl_tx_retry_limit = true; + ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); } else { - ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); - rtwsta->cctl_tx_retry_limit = false; + ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link); + rtwsta_link->cctl_tx_retry_limit = false; } return ret; } int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 *tx_retry) + struct rtw89_sta_link *rtwsta_link, u8 *tx_retry) { - u8 mac_idx = rtwsta->rtwvif_link->mac_idx; + u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx; u32 reg; int ret = 0; - if (rtwsta->cctl_tx_retry_limit) { - *tx_retry = rtwsta->data_tx_cnt_lmt; + if (rtwsta_link->cctl_tx_retry_limit) { + *tx_retry = rtwsta_link->data_tx_cnt_lmt; } else { ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); if (ret) { @@ -6340,7 +6340,7 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val) } static -void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) +void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) { static const enum rtw89_pkt_drop_sel sels[] = { RTW89_PKT_DROP_SEL_MACID_BE_ONCE, @@ -6348,12 +6348,12 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) RTW89_PKT_DROP_SEL_MACID_VI_ONCE, RTW89_PKT_DROP_SEL_MACID_VO_ONCE, }; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_pkt_drop_params params = {0}; int i; params.mac_band = RTW89_MAC_0; - params.macid = rtwsta->mac_id; + params.macid = rtwsta_link->mac_id; params.port = rtwvif_link->port; params.mbssid = 0; params.tf_trs = rtwvif_link->trigger; @@ -6366,15 +6366,15 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct rtw89_vif_link *target = data; if (rtwvif_link != target) return; - rtw89_mac_pkt_drop_sta(rtwdev, rtwsta); + rtw89_mac_pkt_drop_sta(rtwdev, rtwsta_link); } void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 6839028991d4..3ea2dcbfa5b8 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1384,15 +1384,15 @@ static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev) return !!val; } -int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, bool resume, u32 tx_time); -int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, u32 *tx_time); int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, bool resume, u8 tx_retry); int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, u8 *tx_retry); + struct rtw89_sta_link *rtwsta_link, u8 *tx_retry); enum rtw89_mac_xtal_si_offset { XTAL0 = 0x0, diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index bc0ff64c1c98..392a38fcf461 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -29,10 +29,11 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw, int ret, qsel; if (rtwvif_link->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = + (struct rtw89_sta_link *)sta->drv_priv; rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n"); - skb_queue_tail(&rtwsta->roc_queue, skb); + skb_queue_tail(&rtwsta_link->roc_queue, skb); return; } @@ -548,8 +549,8 @@ static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work); @@ -668,7 +669,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; struct ieee80211_sta *sta = params->sta; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u16 tid = params->tid; struct ieee80211_txq *txq = sta->txq[tid]; struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; @@ -681,7 +682,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mutex_lock(&rtwdev->mutex); clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); - clear_bit(tid, rtwsta->ampdu_map); + clear_bit(tid, rtwsta_link->ampdu_map); rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta); mutex_unlock(&rtwdev->mutex); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -689,21 +690,21 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_OPERATIONAL: mutex_lock(&rtwdev->mutex); set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); - rtwsta->ampdu_params[tid].agg_num = params->buf_size; - rtwsta->ampdu_params[tid].amsdu = params->amsdu; - set_bit(tid, rtwsta->ampdu_map); + rtwsta_link->ampdu_params[tid].agg_num = params->buf_size; + rtwsta_link->ampdu_params[tid].amsdu = params->amsdu; + set_bit(tid, rtwsta_link->ampdu_map); rtw89_leave_ps_mode(rtwdev); rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta); mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_START: mutex_lock(&rtwdev->mutex); - rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta_link, true, params); mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_STOP: mutex_lock(&rtwdev->mutex); - rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta_link, false, params); mutex_unlock(&rtwdev->mutex); break; default: @@ -732,9 +733,9 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct station_info *sinfo) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - sinfo->txrate = rtwsta->ra_report.txrate; + sinfo->txrate = rtwsta_link->ra_report.txrate; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } @@ -778,14 +779,14 @@ struct rtw89_iter_bitrate_mask_data { static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_iter_bitrate_mask_data *br_data = data; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif_link); + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta_link->rtwvif_link); if (vif != br_data->vif || vif->p2p) return; - rtwsta->use_cfg_mask = true; - rtwsta->mask = *br_data->mask; + rtwsta_link->use_cfg_mask = true; + rtwsta_link->mask = *br_data->mask; rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED); } @@ -1054,8 +1055,8 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta) { struct cfg80211_tid_config *tid_config = data; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta->rtwvif_link->rtwdev; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_dev *rtwdev = rtwsta_link->rtwvif_link->rtwdev; rtw89_core_set_tid_config(rtwdev, sta, tid_config); } diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index f5e5deba853e..f056fdc6262b 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -195,15 +195,16 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak) return ra_mask; } -static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link, const struct rtw89_chan *chan) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); - struct cfg80211_bitrate_mask *mask = &rtwsta->mask; + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; enum nl80211_band band; u64 cfg_mask; - if (!rtwsta->use_cfg_mask) + if (!rtwsta_link->use_cfg_mask) return -1; switch (chan->band_type) { @@ -261,17 +262,17 @@ rtw89_ra_mask_eht_rates[4] = {RA_MASK_EHT_1SS_RATES, RA_MASK_EHT_2SS_RATES, RA_MASK_EHT_3SS_RATES, RA_MASK_EHT_4SS_RATES}; static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, - struct rtw89_sta *rtwsta, + struct rtw89_sta_link *rtwsta_link, const struct rtw89_chan *chan, bool *fix_giltf_en, u8 *fix_giltf) { - struct cfg80211_bitrate_mask *mask = &rtwsta->mask; + struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; u8 band = chan->band_type; enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); u8 he_gi = mask->control[nl_band].he_gi; u8 he_ltf = mask->control[nl_band].he_ltf; - if (!rtwsta->use_cfg_mask) + if (!rtwsta_link->use_cfg_mask) return; if (he_ltf == 2 && he_gi == 2) { @@ -297,15 +298,15 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, bool csi) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; - struct rtw89_ra_info *ra = &rtwsta->ra; + struct rtw89_ra_info *ra = &rtwsta_link->ra; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif_link); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta_link->rtwvif_link); const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; - u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi); + u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); u64 ra_mask = 0; u64 ra_mask_bak; u8 mode = 0; @@ -335,7 +336,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) ldpc_en = 1; - rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, chan, &fix_giltf_en, &fix_giltf); + rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, chan, &fix_giltf_en, &fix_giltf); } else if (sta->deflink.vht_cap.vht_supported) { u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); @@ -405,7 +406,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0); ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak); - ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan); + ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, chan); switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: @@ -435,15 +436,15 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra->dcm_cap = 1; if (rate_pattern->enable && !vif->p2p) { - ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan); + ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, chan); ra_mask &= rate_pattern->ra_mask; mode = rate_pattern->ra_mode; } ra->bw_cap = bw_mode; - ra->er_cap = rtwsta->er_cap; + ra->er_cap = rtwsta_link->er_cap; ra->mode_ctrl = mode; - ra->macid = rtwsta->mac_id; + ra->macid = rtwsta_link->mac_id; ra->stbc_cap = stbc_en; ra->ldpc_cap = ldpc_en; ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; @@ -468,8 +469,8 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, u32 changed) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_ra_info *ra = &rtwsta->ra; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_ra_info *ra = &rtwsta_link->ra; rtw89_phy_ra_sta_update(rtwdev, sta, false); @@ -629,9 +630,9 @@ void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_ra_info *ra = &rtwsta->ra; - u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_ra_info *ra = &rtwsta_link->ra; + u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; bool csi = rtw89_sta_has_beamformer_cap(sta); rtw89_phy_ra_sta_update(rtwdev, sta, csi); @@ -2557,10 +2558,10 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; struct rtw89_dev *rtwdev = ra_data->rtwdev; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; const struct rtw89_c2h_ra_rpt *c2h = (const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data; - struct rtw89_ra_report *ra_report = &rtwsta->ra_report; + struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report; const struct rtw89_chip_info *chip = rtwdev->chip; bool format_v1 = chip->chip_gen == RTW89_CHIP_BE; u8 mode, rate, bw, giltf, mac_id; @@ -2570,7 +2571,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) u8 t; mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID); - if (mac_id != rtwsta->mac_id) + if (mac_id != rtwsta_link->mac_id) return; rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS); @@ -2662,7 +2663,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL); ra_report->might_fallback_legacy = mcs <= 2; sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); - rtwsta->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1; + rtwsta_link->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1; } static void @@ -4768,23 +4769,24 @@ struct rtw89_phy_iter_rssi_data { static void rtw89_phy_stat_rssi_update_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_phy_iter_rssi_data *rssi_data = (struct rtw89_phy_iter_rssi_data *)data; struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info; unsigned long rssi_curr; - rssi_curr = ewma_rssi_read(&rtwsta->avg_rssi); + rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi); if (rssi_curr < ch_info->rssi_min) { ch_info->rssi_min = rssi_curr; - ch_info->rssi_min_macid = rtwsta->mac_id; + ch_info->rssi_min_macid = rtwsta_link->mac_id; } - if (rtwsta->prev_rssi == 0) { - rtwsta->prev_rssi = rssi_curr; - } else if (abs((int)rtwsta->prev_rssi - (int)rssi_curr) > (3 << RSSI_FACTOR)) { - rtwsta->prev_rssi = rssi_curr; + if (rtwsta_link->prev_rssi == 0) { + rtwsta_link->prev_rssi = rssi_curr; + } else if (abs((int)rtwsta_link->prev_rssi - (int)rssi_curr) > + (3 << RSSI_FACTOR)) { + rtwsta_link->prev_rssi = rssi_curr; rssi_data->rssi_changed = true; } } @@ -5894,9 +5896,9 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_hal *hal = &rtwdev->hal; bool *done = data; u8 rssi_a, rssi_b; @@ -5910,8 +5912,8 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta *done = true; - rssi_a = ewma_rssi_read(&rtwsta->rssi[RF_PATH_A]); - rssi_b = ewma_rssi_read(&rtwsta->rssi[RF_PATH_B]); + rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]); + rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]); if (rssi_a > rssi_b + RTW89_TX_DIV_RSSI_RAW_TH) candidate = RF_A; @@ -5924,7 +5926,7 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta return; hal->antenna_tx = candidate; - rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta); + rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta_link); if (hal->antenna_tx == RF_A) { rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x12); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 2058f4bf271d..50b66eaf9bd0 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -309,19 +309,19 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_vif_link *target_rtwvif = (struct rtw89_vif_link *)data; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; if (rtwvif_link != target_rtwvif) return; if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) - rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); if (sta->tdls) - rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); - INIT_LIST_HEAD(&rtwsta->ba_cam_list); + INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); } static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 5902eb37d618..5046fef55222 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1123,12 +1123,12 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; struct ieee80211_sta *wow_sta; - struct rtw89_sta *rtwsta = NULL; + struct rtw89_sta_link *rtwsta_link = NULL; int ret; wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); if (wow_sta) - rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; + rtwsta_link = (struct rtw89_sta_link *)wow_sta->drv_priv; if (wow) { if (rtw_wow->pattern_cnt) @@ -1147,7 +1147,7 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) } if (wow) { - ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, 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); @@ -1155,7 +1155,7 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) } } - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; @@ -1198,7 +1198,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) bool include_bb = !!chip->bbmcu_nr; bool disable_intr_for_dlfw = false; struct ieee80211_sta *wow_sta; - struct rtw89_sta *rtwsta = NULL; + struct rtw89_sta_link *rtwsta_link = NULL; bool is_conn = true; int ret; @@ -1207,7 +1207,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); if (wow_sta) - rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; + rtwsta_link = (struct rtw89_sta_link *)wow_sta->drv_priv; else is_conn = false; @@ -1225,7 +1225,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) rtw89_phy_init_rf_reg(rtwdev, true); - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta, + ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, RTW89_ROLE_FW_RESTORE); if (ret) { rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); @@ -1241,20 +1241,20 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) if (!is_conn) rtw89_cam_reset_keys(rtwdev); - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta, !is_conn); + ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn); if (ret) { rtw89_warn(rtwdev, "failed to send h2c join info\n"); return ret; } - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta, NULL); + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); return ret; } if (is_conn) { - ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta->mac_id); + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); if (ret) { rtw89_warn(rtwdev, "failed to send h2c general packet\n"); return ret; From 89bac818bbd2ccced29d4b888ba1a4cf3e1ede4e Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:54 +0800 Subject: [PATCH 021/126] wifi: rtw89: read bss_conf corresponding to the link Tweak code to not always access vif->bss_conf directly. Instead, according to link_id, read target bss_conf from vif->link_conf[]. For now, rtwvif_link->link_id keeps 0. When driver starts to support MLO, the link_id will be assigned. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 13 ++- drivers/net/wireless/realtek/rtw89/chan.c | 22 ++++- drivers/net/wireless/realtek/rtw89/coex.c | 17 +++- drivers/net/wireless/realtek/rtw89/core.c | 98 +++++++++++++++---- drivers/net/wireless/realtek/rtw89/core.h | 52 +++++++--- drivers/net/wireless/realtek/rtw89/fw.c | 96 ++++++++++++------ drivers/net/wireless/realtek/rtw89/fw.h | 4 +- drivers/net/wireless/realtek/rtw89/mac.c | 68 ++++++++++--- drivers/net/wireless/realtek/rtw89/mac80211.c | 24 ++++- drivers/net/wireless/realtek/rtw89/phy.c | 15 ++- drivers/net/wireless/realtek/rtw89/ps.c | 24 +++-- drivers/net/wireless/realtek/rtw89/ps.h | 4 +- drivers/net/wireless/realtek/rtw89/regd.c | 19 +++- drivers/net/wireless/realtek/rtw89/wow.c | 12 ++- 14 files changed, 357 insertions(+), 111 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 80deb0712b83..757f7633b079 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -655,17 +655,24 @@ int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, u8 *cmd) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, rtwsta_link); - u8 bss_color = vif->bss_conf.he_bss_color.color; + 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); diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index 2f14ac668716..2968c299203b 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -564,8 +564,9 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev, static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *mcc_role) { - struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif_link); + struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link; struct ieee80211_p2p_noa_desc *noa_desc; + struct ieee80211_bss_conf *bss_conf; u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval); u32 max_toa_us, max_tob_us, max_dur_us; u32 start_time, interval, duration; @@ -576,13 +577,18 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, if (!mcc_role->is_go && !mcc_role->is_gc) return; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + /* find the first periodic NoA */ for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) { - noa_desc = &vif->bss_conf.p2p_noa_attr.desc[i]; + noa_desc = &bss_conf->p2p_noa_attr.desc[i]; if (noa_desc->count == 255) goto fill; } + rcu_read_unlock(); return; fill: @@ -590,6 +596,8 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, interval = le32_to_cpu(noa_desc->interval); duration = le32_to_cpu(noa_desc->duration); + rcu_read_unlock(); + if (interval != bcn_intvl_us) { rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC role limit: mismatch interval: %d vs. %d\n", @@ -635,12 +643,18 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_mcc_role *role) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_bss_conf *bss_conf; const struct rtw89_chan *chan; memset(role, 0, sizeof(*role)); role->rtwvif_link = rtwvif_link; - role->beacon_interval = vif->bss_conf.beacon_int; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + role->beacon_interval = bss_conf->beacon_int; + + rcu_read_unlock(); if (!role->beacon_interval) { rtw89_warn(rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 174e79b73352..591c24df1825 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -7488,6 +7488,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, rtwvif_link->chanctx_idx); struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct ieee80211_bss_conf *bss_conf; struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_wl_info *wl = &btc->cx.wl; @@ -7495,6 +7496,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_btc_wl_link_info *wlinfo = NULL; u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], role is STA=%d\n", @@ -7506,7 +7511,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, state == BTC_ROLE_MSTS_STA_CONN_END); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], bcn_period=%d dtim_period=%d\n", - vif->bss_conf.beacon_int, vif->bss_conf.dtim_period); + bss_conf->beacon_int, bss_conf->dtim_period); if (rtwsta_link) { rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", @@ -7527,8 +7532,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, r.mode = mode; } - if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) + if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) { + rcu_read_unlock(); return; + } rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role); @@ -7538,8 +7545,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, r.pid = rtwvif_link->port; r.active = true; r.connected = MLME_LINKED; - r.bcn_period = vif->bss_conf.beacon_int; - r.dtim_period = vif->bss_conf.dtim_period; + r.bcn_period = bss_conf->beacon_int; + r.dtim_period = bss_conf->dtim_period; r.band = chan->band_type; r.ch = chan->channel; r.bw = chan->band_width; @@ -7549,6 +7556,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, r.chdef.chan = chan->primary_channel; ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr); + rcu_read_unlock(); + if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION) r.mac_id = rtwsta_link->mac_id; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 2b6a8fe0e53b..f1db598c6004 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -571,7 +571,10 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, struct sk_buff *skb = tx_req->skb; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = tx_info->control.vif; + struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct ieee80211_bss_conf *bss_conf; u16 lowest_rate; + u16 rate; if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || (vif && vif->p2p)) @@ -581,10 +584,23 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, else lowest_rate = RTW89_HW_RATE_OFDM6; - if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta) + if (!rtwvif_link) return lowest_rate; - return __ffs(vif->bss_conf.basic_rates) + lowest_rate; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->basic_rates || !tx_req->sta) { + rate = lowest_rate; + goto out; + } + + rate = __ffs(bss_conf->basic_rates) + lowest_rate; + +out: + rcu_read_unlock(); + + return rate; } static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, @@ -1879,6 +1895,7 @@ struct rtw89_vif_rx_stats_iter_data { static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, struct sk_buff *skb) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; @@ -1886,7 +1903,7 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, u8 *pos, *end, type, tf_bw; u16 aid, tf_rua; - if (!ether_addr_equal(vif->bss_conf.bssid, tf->ta) || + if (!ether_addr_equal(bss_conf->bssid, tf->ta) || rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION || rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK) return; @@ -2010,6 +2027,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, struct sk_buff *skb = iter_data->skb; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu; + struct ieee80211_bss_conf *bss_conf; const u8 *bssid = iter_data->bssid; if (rtwdev->scanning && @@ -2017,16 +2035,19 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, ieee80211_is_probe_resp(hdr->frame_control))) rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb); - if (!vif->bss_conf.bssid) - return; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->bssid) + goto out; if (ieee80211_is_trigger(hdr->frame_control)) { - rtw89_stats_trigger_frame(rtwdev, vif, skb); - return; + rtw89_stats_trigger_frame(rtwdev, vif, bss_conf, skb); + goto out; } - if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) - return; + if (!ether_addr_equal(bss_conf->bssid, bssid)) + goto out; if (ieee80211_is_beacon(hdr->frame_control)) { if (vif->type == NL80211_IFTYPE_STATION && @@ -2037,13 +2058,16 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, pkt_stat->beacon_nr++; } - if (!ether_addr_equal(vif->addr, hdr->addr1)) - return; + if (!ether_addr_equal(bss_conf->addr, hdr->addr1)) + goto out; if (desc_info->data_rate < RTW89_HW_RATE_NR) pkt_stat->rx_rate_cnt[desc_info->data_rate]++; rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, false); + +out: + rcu_read_unlock(); } static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, @@ -3008,7 +3032,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, return 0; rcu_read_lock(); - sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); + sta = ieee80211_find_sta(vif, vif->cfg.ap_addr); if (!sta) { ret = -EINVAL; goto out; @@ -3241,14 +3265,16 @@ static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev) rtw89_chip_rfk_track(rtwdev); } -void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) { enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); if (mode == RTW89_ENTITY_MODE_MCC) rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_P2P_PS_CHANGE); else - rtw89_process_p2p_ps(rtwdev, vif); + rtw89_process_p2p_ps(rtwdev, rtwvif_link, bss_conf); } void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, @@ -3410,6 +3436,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + const struct ieee80211_bss_conf *bss_conf; switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3445,7 +3472,11 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) case NL80211_IFTYPE_STATION: if (assoc) { rtwvif_link->net_type = RTW89_NET_TYPE_INFRA; - rtwvif_link->trigger = vif->bss_conf.he_support; + + rcu_read_lock(); + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + rtwvif_link->trigger = bss_conf->he_support; + rcu_read_unlock(); } else { rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; rtwvif_link->trigger = false; @@ -3656,12 +3687,17 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, rtw89_mac_bf_monitor_calc(rtwdev, sta, false); if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ieee80211_bss_conf *bss_conf; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); if (bss_conf->he_support && !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) rtwsta_link->er_cap = true; + rcu_read_unlock(); + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, BTC_ROLE_MSTS_STA_CONN_END); rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan); @@ -4480,11 +4516,18 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, { struct rtw89_vif_link *rtwvif_link = vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; + struct ieee80211_bss_conf *bss_conf; if (!rtwvif_link) return; - ether_addr_copy(rtwvif_link->mac_addr, vif->addr); + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); + + rcu_read_unlock(); + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); @@ -4700,6 +4743,27 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) } EXPORT_SYMBOL(rtw89_chip_info_setup); +void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_bss_conf *bss_conf; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + if (!bss_conf->he_support || !vif->cfg.assoc) { + rcu_read_unlock(); + return; + } + + rcu_read_unlock(); + + if (chip->ops->set_txpwr_ul_tb_offset) + chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx); +} + static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index aa0627ce4cd1..3de9fae10959 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3461,6 +3461,8 @@ struct rtw89_p2p_noa_setter { }; struct rtw89_vif_link { + unsigned int link_id; + struct list_head list; struct rtw89_dev *rtwdev; struct rtw89_roc roc; @@ -5995,6 +5997,36 @@ static inline struct rtw89_sta_link *sta_to_rtwsta_safe(struct ieee80211_sta *st return sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; } +static inline struct ieee80211_bss_conf * +__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_bss_conf *bss_conf; + + bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]); + if (unlikely(!bss_conf)) { + *nolink = true; + return &vif->bss_conf; + } + + *nolink = false; + return bss_conf; +} + +#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert) \ +({ \ + typeof(rtwvif_link) p = rtwvif_link; \ + struct ieee80211_bss_conf *bss_conf; \ + bool nolink; \ + \ + bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \ + if (unlikely(nolink) && (assert)) \ + rtw89_err(p->rtwdev, \ + "%s: cannot find exact bss_conf for link_id %u\n",\ + __func__, p->link_id); \ + bss_conf; \ +}) + static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw) { if (hw_bw == RTW89_CHANNEL_WIDTH_160) @@ -6348,20 +6380,6 @@ static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev) chip->ops->cfg_txrx_path(rtwdev); } -static inline -void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif) -{ - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - const struct rtw89_chip_info *chip = rtwdev->chip; - - if (!vif->bss_conf.he_support || !vif->cfg.assoc) - return; - - if (chip->ops->set_txpwr_ul_tb_offset) - chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx); -} - static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -6654,6 +6672,8 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, u8 *cam_idx); void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); +void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate); int rtw89_regd_setup(struct rtw89_dev *rtwdev); int rtw89_regd_init(struct rtw89_dev *rtwdev, @@ -6676,7 +6696,9 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool hw_scan); int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active); -void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); +void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf); void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event); #endif diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 59325a6995e6..b2129164a6e1 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2209,11 +2209,10 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, { static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03}; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_eapol_2_of_2 *eapol_pkt; + struct ieee80211_bss_conf *bss_conf; struct ieee80211_hdr_3addr *hdr; struct sk_buff *skb; u8 key_des_ver; @@ -2235,10 +2234,17 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS | IEEE80211_FCTL_PROTECTED); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(hdr->addr1, bss_conf->bssid); - ether_addr_copy(hdr->addr2, vif->addr); + ether_addr_copy(hdr->addr2, bss_conf->addr); ether_addr_copy(hdr->addr3, bss_conf->bssid); + rcu_read_unlock(); + skb_put_zero(skb, sec_hdr_len); eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt)); @@ -2251,9 +2257,8 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev, static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); + struct ieee80211_bss_conf *bss_conf; struct ieee80211_hdr_3addr *hdr; struct rtw89_sa_query *sa_query; struct sk_buff *skb; @@ -2266,10 +2271,17 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION | IEEE80211_FCTL_PROTECTED); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(hdr->addr1, bss_conf->bssid); - ether_addr_copy(hdr->addr2, vif->addr); + ether_addr_copy(hdr->addr2, bss_conf->addr); ether_addr_copy(hdr->addr3, bss_conf->bssid); + rcu_read_unlock(); + skb_put_zero(skb, sec_hdr_len); sa_query = skb_put_zero(skb, sizeof(*sa_query)); @@ -2555,13 +2567,14 @@ int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rt } #define H2C_P2P_ACT_LEN 20 -int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf, struct ieee80211_p2p_noa_desc *desc, u8 act, u8 noa_id) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT; - u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; + u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow; struct sk_buff *skb; u8 *cmd; int ret; @@ -2963,6 +2976,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; + struct ieee80211_bss_conf *bss_conf; u8 pads[RTW89_PPE_BW_NUM]; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -2977,6 +2991,16 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, __get_sta_he_pkt_padding(rtwdev, sta, pads); } + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (vif->p2p) lowest_rate = RTW89_HW_RATE_OFDM6; else if (chan->band_type == RTW89_BAND_2G) @@ -2984,11 +3008,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, else lowest_rate = RTW89_HW_RATE_OFDM6; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n"); - return -ENOMEM; - } skb_put(skb, len); h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; @@ -3017,8 +3036,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM); } - if (vif->bss_conf.eht_support) { - u16 punct = vif->bss_conf.chanreq.oper.punctured; + if (bss_conf->eht_support) { + u16 punct = bss_conf->chanreq.oper.punctured; h2c->w4 |= le32_encode_bits(~punct, CCTLINFO_G7_W4_ACT_SUBCH_CBW); @@ -3051,6 +3070,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); } + rcu_read_unlock(); + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, @@ -3434,7 +3455,8 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li struct rtw89_sta_link *rtwsta_link) { struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta_link); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_bss_conf *bss_conf; + enum rtw89_fw_sta_type type; if (!sta) goto by_vif; @@ -3447,12 +3469,20 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li return RTW89_FW_N_AC_STA; by_vif: - if (vif->bss_conf.eht_support) - return RTW89_FW_BE_STA; - else if (vif->bss_conf.he_support) - return RTW89_FW_AX_STA; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (bss_conf->eht_support) + type = RTW89_FW_BE_STA; + else if (bss_conf->he_support) + type = RTW89_FW_AX_STA; else - return RTW89_FW_N_AC_STA; + type = RTW89_FW_N_AC_STA; + + rcu_read_unlock(); + + return type; } int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, @@ -3742,7 +3772,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, bool connect) { struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL; + struct ieee80211_bss_conf *bss_conf; s32 thold = RTW89_DEFAULT_CQM_THOLD; u32 hyst = RTW89_DEFAULT_CQM_HYST; struct rtw89_h2c_bcnfltr *h2c; @@ -3753,9 +3783,20 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) return -EINVAL; - if (!rtwvif_link || !bss_conf || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) + if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA) return -EINVAL; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); + + if (bss_conf->cqm_rssi_hyst) + hyst = bss_conf->cqm_rssi_hyst; + if (bss_conf->cqm_rssi_thold) + thold = bss_conf->cqm_rssi_thold; + + rcu_read_unlock(); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); @@ -3765,11 +3806,6 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_bcnfltr *)skb->data; - if (bss_conf->cqm_rssi_hyst) - hyst = bss_conf->cqm_rssi_hyst; - if (bss_conf->cqm_rssi_thold) - thold = bss_conf->cqm_rssi_thold; - h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | @@ -6565,7 +6601,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, get_random_mask_addr(mac_addr, req->mac_addr, req->mac_addr_mask); else - ether_addr_copy(mac_addr, vif->addr); + ether_addr_copy(mac_addr, rtwvif_link->mac_addr); rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true); rx_fltr &= ~B_AX_A_BCN_CHK_EN; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 7cce4e71a36a..896993d24c5b 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4608,7 +4608,9 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, const struct rtw89_pkt_drop_params *params); -int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf, struct ieee80211_p2p_noa_desc *desc, u8 act, u8 noa_id); int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index d6cd3ed1e7fc..d5097d3a3385 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4141,10 +4141,11 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_bss_conf *bss_conf; bool need_backup = false; u32 backup_val; + u16 beacon_int; if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN)) return; @@ -4168,7 +4169,14 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, B_AX_BCNERLY_MASK); } - msleep(vif->bss_conf.beacon_int + 1); + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + beacon_int = bss_conf->beacon_int; + + rcu_read_unlock(); + + msleep(beacon_int + 1); rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN | B_AX_BRK_SETUP); rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST); @@ -4301,8 +4309,18 @@ static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL; + struct ieee80211_bss_conf *bss_conf; + u16 bcn_int; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (bss_conf->beacon_int) + bcn_int = bss_conf->beacon_int; + else + bcn_int = BCN_INTERVAL; + + rcu_read_unlock(); rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK, bcn_int); @@ -4326,14 +4344,22 @@ static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_bss_conf *bss_conf; + u8 dtim_period; u32 addr; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + dtim_period = bss_conf->dtim_period; + + rcu_read_unlock(); + addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx); rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE); rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK, - vif->bss_conf.dtim_period); + dtim_period); } static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev, @@ -4381,18 +4407,24 @@ static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_port_reg *p = mac->port_base; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); static const u32 masks[RTW89_PORT_NUM] = { B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK, B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK, B_AX_BSS_COLOB_AX_PORT_4_MASK, }; + struct ieee80211_bss_conf *bss_conf; u8 port = rtwvif_link->port; u32 reg_base; u32 reg; u8 bss_color; - bss_color = vif->bss_conf.he_bss_color.color; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + bss_color = bss_conf->he_bss_color.color; + + rcu_read_unlock(); + reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color; reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx); rtw89_write32_mask(rtwdev, reg, masks[port], bss_color); @@ -4670,16 +4702,28 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_bss_conf *bss_conf; + struct cfg80211_chan_def oper; bool tolerated = true; u32 reg; - if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION) - return; + rcu_read_lock(); - if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR)) + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) { + rcu_read_unlock(); return; + } - cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper, + oper = bss_conf->chanreq.oper; + if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) { + rcu_read_unlock(); + return; + } + + rcu_read_unlock(); + + cfg80211_bss_iter(hw->wiphy, &oper, rtw89_mac_check_he_obss_narrow_bw_ru_iter, &tolerated); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 392a38fcf461..f04032a8a8ec 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -111,6 +111,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct ieee80211_bss_conf *bss_conf; int ret = 0; rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", @@ -151,7 +152,14 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, rtwvif_link->chanctx_assigned = false; rtwvif_link->hit_rule = 0; rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; - ether_addr_copy(rtwvif_link->mac_addr, vif->addr); + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); + + rcu_read_unlock(); + INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); ret = rtw89_mac_add_vif(rtwdev, rtwvif_link); @@ -314,13 +322,19 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u8 aifsn) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct ieee80211_bss_conf *bss_conf; u8 slot_time; u8 sifs; - slot_time = vif->bss_conf.use_short_slot ? 9 : 20; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + slot_time = bss_conf->use_short_slot ? 9 : 20; + + rcu_read_unlock(); + sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16; return aifsn * slot_time + sifs; @@ -486,7 +500,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, rtw89_mac_bf_set_gid_table(rtwdev, vif, conf); if (changed & BSS_CHANGED_P2P_PS) - rtw89_core_update_p2p_ps(rtwdev, vif); + rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf); if (changed & BSS_CHANGED_CQM) rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); @@ -516,7 +530,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, if (rtwdev->scanning) rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); - ether_addr_copy(rtwvif_link->bssid, vif->bss_conf.bssid); + ether_addr_copy(rtwvif_link->bssid, link_conf->bssid); rtw89_cam_bssid_changed(rtwdev, rtwvif_link); rtw89_mac_port_update(rtwdev, rtwvif_link); rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index f056fdc6262b..2fec179aba1b 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -6145,15 +6145,24 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld; enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + struct ieee80211_bss_conf *bss_conf; u8 bss_color; - if (!vif->bss_conf.he_support || !vif->cfg.assoc) - return; + rcu_read_lock(); - bss_color = vif->bss_conf.he_bss_color.color; + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (!bss_conf->he_support || !vif->cfg.assoc) { + rcu_read_unlock(); + return; + } + + bss_color = bss_conf->he_bss_color.color; + + rcu_read_unlock(); rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1, phy_idx); diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index 42a73bba7f5c..ded0b73bd678 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -214,9 +214,9 @@ static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, } static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif) + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; enum rtw89_p2pps_action act; u8 noa_id; @@ -229,20 +229,21 @@ static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev, else act = RTW89_P2P_ACT_REMOVE; rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); - rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id); + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf, + NULL, act, noa_id); } } static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif) + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_p2p_noa_desc *desc; enum rtw89_p2pps_action act; u8 noa_id; for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) { - desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id]; + desc = &bss_conf->p2p_noa_attr.desc[noa_id]; if (!desc->count || !desc->duration) break; @@ -251,15 +252,18 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev, else act = RTW89_P2P_ACT_UPDATE; rtw89_tsf32_toggle(rtwdev, rtwvif_link, act); - rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id); + rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf, + desc, act, noa_id); } rtwvif_link->last_noa_nr = noa_id; } -void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf) { - rtw89_p2p_disable_all_noa(rtwdev, vif); - rtw89_p2p_update_noa(rtwdev, vif); + rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf); + rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf); } void rtw89_recalc_lps(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h index d0be56ee16a2..cdd712966b09 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.h +++ b/drivers/net/wireless/realtek/rtw89/ps.h @@ -14,7 +14,9 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); void rtw89_enter_ips(struct rtw89_dev *rtwdev); void rtw89_leave_ips(struct rtw89_dev *rtwdev); void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); -void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); +void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_bss_conf *bss_conf); void rtw89_recalc_lps(struct rtw89_dev *rtwdev); void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link); void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link, diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 0fd8e132fdf0..aa5ae0244372 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -834,16 +834,21 @@ static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active, unsigned int *changed) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe; + struct ieee80211_bss_conf *bss_conf; memset(tpe, 0, sizeof(*tpe)); if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD) goto bottom; + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe); + + rcu_read_unlock(); + if (!tpe->valid) goto bottom; @@ -911,10 +916,14 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active, unsigned int *changed) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_bss_conf *bss_conf; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); if (active) { - switch (vif->bss_conf.power_type) { + switch (bss_conf->power_type) { case IEEE80211_REG_VLP_AP: rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; break; @@ -932,6 +941,8 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; } + rcu_read_unlock(); + *changed += __rtw89_reg_6ghz_power_recalc(rtwdev); return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 5046fef55222..17e2d5cbb1e6 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -633,10 +633,12 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; struct rtw89_set_key_info_iter_data data = {.error = false, .rx_ready = rx_ready}; + struct ieee80211_bss_conf *bss_conf; struct ieee80211_key_conf *key; rcu_read_lock(); @@ -669,9 +671,15 @@ static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready) return; rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn); - ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid, + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid, aoac_rpt->eapol_key_replay_count, - GFP_KERNEL); + GFP_ATOMIC); + + rcu_read_unlock(); } static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) From 04911c0fe874bb44e8ee0f5896a5a10c37a14cf2 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:55 +0800 Subject: [PATCH 022/126] wifi: rtw89: read link_sta corresponding to the link Tweak code to not always access sta->deflink directly. Instead, according to link_id, read target link_sta from sta->link[]. For now, rtwsta_link->link_id keeps 0. When driver starts to support MLO, the link_id will be assigned. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 14 +- drivers/net/wireless/realtek/rtw89/coex.c | 16 +- drivers/net/wireless/realtek/rtw89/core.c | 53 ++++++- drivers/net/wireless/realtek/rtw89/core.h | 43 +++++- drivers/net/wireless/realtek/rtw89/debug.c | 21 ++- drivers/net/wireless/realtek/rtw89/fw.c | 103 +++++++------ drivers/net/wireless/realtek/rtw89/mac.c | 61 ++++++-- drivers/net/wireless/realtek/rtw89/mac_be.c | 45 ++++-- drivers/net/wireless/realtek/rtw89/phy.c | 154 ++++++++++++-------- 9 files changed, 365 insertions(+), 145 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 757f7633b079..7efc6280feaf 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -712,11 +712,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); struct ieee80211_sta *sta = rtwsta_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_link->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); @@ -791,6 +801,8 @@ 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, diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 591c24df1825..e4ae80742ba3 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -7487,8 +7487,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; struct rtw89_btc *btc = &rtwdev->btc; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_wl_info *wl = &btc->cx.wl; @@ -7514,19 +7514,21 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, bss_conf->beacon_int, bss_conf->dtim_period); if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", rtwsta_link->mac_id); rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA support HE=%d VHT=%d HT=%d\n", - sta->deflink.he_cap.has_he, - sta->deflink.vht_cap.vht_supported, - sta->deflink.ht_cap.ht_supported); - if (sta->deflink.he_cap.has_he) + link_sta->he_cap.has_he, + link_sta->vht_cap.vht_supported, + link_sta->ht_cap.ht_supported); + if (link_sta->he_cap.has_he) mode |= BIT(BTC_WL_MODE_HE); - if (sta->deflink.vht_cap.vht_supported) + if (link_sta->vht_cap.vht_supported) mode |= BIT(BTC_WL_MODE_VHT); - if (sta->deflink.ht_cap.ht_supported) + if (link_sta->ht_cap.ht_supported) mode |= BIT(BTC_WL_MODE_HT); r.mode = mode; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index f1db598c6004..84c1952fbea8 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -465,6 +465,7 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, { struct ieee80211_sta *sta = tx_req->sta; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; + struct ieee80211_link_sta *link_sta; struct sk_buff *skb = tx_req->skb; struct rtw89_sta_link *rtwsta_link; u8 ampdu_num; @@ -486,13 +487,18 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); ampdu_num = (u8)((rtwsta_link->ampdu_params[tid].agg_num ? rtwsta_link->ampdu_params[tid].agg_num : - 4 << sta->deflink.ht_cap.ampdu_factor) - 1); + 4 << link_sta->ht_cap.ampdu_factor) - 1); desc_info->agg_en = true; - desc_info->ampdu_density = sta->deflink.ht_cap.ampdu_density; + desc_info->ampdu_density = link_sta->ht_cap.ampdu_density; desc_info->ampdu_num = ampdu_num; + + rcu_read_unlock(); } static void @@ -721,15 +727,26 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); struct sk_buff *skb = tx_req->skb; struct ieee80211_hdr *hdr = (void *)skb->data; + struct ieee80211_link_sta *link_sta; __le16 fc = hdr->frame_control; /* AP IOT issue with EAPoL, ARP and DHCP */ if (pkt_type < PACKET_MAX) return false; - if (!sta || !sta->deflink.he_cap.has_he) + if (!rtwsta_link) return false; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (!link_sta->he_cap.has_he) { + rcu_read_unlock(); + return false; + } + + rcu_read_unlock(); + if (!ieee80211_is_data_qos(fc)) return false; @@ -802,10 +819,13 @@ static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_sta *sta = tx_req->sta; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); + struct ieee80211_link_sta *link_sta; u16 lowest_rate; + u16 rate; if (rate_pattern->enable) return rate_pattern->rate; @@ -817,10 +837,23 @@ static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, else lowest_rate = RTW89_HW_RATE_OFDM6; - if (!sta || !sta->deflink.supp_rates[chan->band_type]) + if (!rtwsta_link) return lowest_rate; - return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (!link_sta->supp_rates[chan->band_type]) { + rate = lowest_rate; + goto out; + } + + rate = __ffs(link_sta->supp_rates[chan->band_type]) + lowest_rate; + +out: + rcu_read_unlock(); + + return rate; } static void @@ -3645,12 +3678,20 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { if (sta->tdls) { + struct ieee80211_link_sta *link_sta; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam, - sta->addr); + link_sta->addr); if (ret) { rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n"); + rcu_read_unlock(); return ret; } + + rcu_read_unlock(); } ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta_link->addr_cam, bssid_cam); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 3de9fae10959..16ada1be9a0b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3355,6 +3355,8 @@ struct rtw89_sec_cam_entry { }; struct rtw89_sta_link { + unsigned int link_id; + u8 mac_id; bool disassoc; bool er_cap; @@ -6027,6 +6029,36 @@ __rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolin bss_conf; \ }) +static inline struct ieee80211_link_sta * +__rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink) +{ + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct ieee80211_link_sta *link_sta; + + link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]); + if (unlikely(!link_sta)) { + *nolink = true; + return &sta->deflink; + } + + *nolink = false; + return link_sta; +} + +#define rtw89_sta_rcu_dereference_link(rtwsta_link, assert) \ +({ \ + typeof(rtwsta_link) p = rtwsta_link; \ + struct ieee80211_link_sta *link_sta; \ + bool nolink; \ + \ + link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \ + if (unlikely(nolink) && (assert)) \ + rtw89_err(p->rtwdev, \ + "%s: cannot find exact link_sta for link_id %u\n",\ + __func__, p->link_id); \ + link_sta; \ +}) + static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw) { if (hw_bw == RTW89_CHANNEL_WIDTH_160) @@ -6498,13 +6530,14 @@ static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) return hdr->addr3; } -static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta) +static inline +bool rtw89_sta_has_beamformer_cap(struct ieee80211_link_sta *link_sta) { - if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || - (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || - (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] & + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || + (link_sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || - (sta->deflink.he_cap.he_cap_elem.phy_cap_info[4] & + (link_sta->he_cap.he_cap_elem.phy_cap_info[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) return true; return false; diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index f09f1a251b16..cc7aaf6fa31f 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3526,11 +3526,20 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; + struct ieee80211_link_sta *link_sta; u8 evm_min, evm_max, evm_1ss; + u16 max_rc_amsdu_len; u8 rssi; u8 snr; int i; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + max_rc_amsdu_len = link_sta->agg.max_rc_amsdu_len; + + rcu_read_unlock(); + seq_printf(m, "TX rate [%d]: ", rtwsta_link->mac_id); if (rate->flags & RATE_INFO_FLAGS_MCS) @@ -3553,7 +3562,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); seq_printf(m, "\t(hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, - sta->deflink.agg.max_rc_amsdu_len); + max_rc_amsdu_len); seq_printf(m, "RX rate [%d]: ", rtwsta_link->mac_id); @@ -3777,9 +3786,17 @@ static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; struct seq_file *m = (struct seq_file *)data; + struct ieee80211_link_sta *link_sta; - seq_printf(m, "STA [%d] %pM %s\n", rtwsta_link->mac_id, sta->addr, + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + seq_printf(m, "STA [%d] %pM %s\n", rtwsta_link->mac_id, link_sta->addr, sta->tdls ? "(TDLS)" : ""); + + rcu_read_unlock(); + rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam); rtw89_dump_ba_cam(m, rtwsta_link); } diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index b2129164a6e1..b1bf5f0e78f7 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2777,24 +2777,25 @@ int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7); static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta, u8 *pads) + struct ieee80211_link_sta *link_sta, + u8 *pads) { bool ppe_th; u8 ppe16, ppe8; - u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; - u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0]; + u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; + u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0]; u8 ru_bitmap; u8 n, idx, sh; u16 ppe; int i; ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, - sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]); + link_sta->he_cap.he_cap_elem.phy_cap_info[6]); if (!ppe_th) { u8 pad; pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK, - sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]); + link_sta->he_cap.he_cap_elem.phy_cap_info[9]); for (i = 0; i < RTW89_PPE_BW_NUM; i++) pads[i] = pad; @@ -2816,7 +2817,7 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, sh = n & 7; n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; - ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx])); + ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx])); ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; @@ -2839,6 +2840,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + struct ieee80211_link_sta *link_sta; struct sk_buff *skb; u8 pads[RTW89_PPE_BW_NUM]; u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; @@ -2846,8 +2848,20 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, int ret; memset(pads, 0, sizeof(pads)); - if (sta && sta->deflink.he_cap.has_he) - __get_sta_he_pkt_padding(rtwdev, sta, pads); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + if (rtwsta_link) + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (rtwsta_link && link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); if (vif->p2p) lowest_rate = RTW89_HW_RATE_OFDM6; @@ -2856,11 +2870,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, else lowest_rate = RTW89_HW_RATE_OFDM6; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); - return -ENOMEM; - } skb_put(skb, H2C_CMC_TBL_LEN); SET_CTRL_INFO_MACID(skb->data, mac_id); SET_CTRL_INFO_OPERATION(skb->data, 1); @@ -2885,12 +2894,14 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]); } - if (sta) + if (rtwsta_link) SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, - sta->deflink.he_cap.has_he); + link_sta->he_cap.has_he); if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) SET_CMC_TBL_DATA_DCM(skb->data, 0); + rcu_read_unlock(); + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, chip->h2c_cctl_func_id, 0, 1, @@ -2911,9 +2922,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl); static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta, u8 *pads) + struct ieee80211_link_sta *link_sta, + u8 *pads) { - u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; + u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; u16 ppe_thres_hdr; u8 ppe16, ppe8; u8 n, idx, sh; @@ -2922,12 +2934,12 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, u16 ppe; int i; - ppe_th = !!u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5], + ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT); if (!ppe_th) { u8 pad; - pad = u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5], + pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5], IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); for (i = 0; i < RTW89_PPE_BW_NUM; i++) @@ -2936,7 +2948,7 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, return; } - ppe_thres_hdr = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres); + ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres); ru_bitmap = u16_get_bits(ppe_thres_hdr, IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); n = hweight8(ru_bitmap); @@ -2953,7 +2965,7 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, sh = n & 7; n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2; - ppe = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres + idx); + ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx); ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE; ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; @@ -2977,6 +2989,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; u8 pads[RTW89_PPE_BW_NUM]; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -2984,12 +2997,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, int ret; memset(pads, 0, sizeof(pads)); - if (sta) { - if (sta->deflink.eht_cap.has_eht) - __get_sta_eht_pkt_padding(rtwdev, sta, pads); - else if (sta->deflink.he_cap.has_he) - __get_sta_he_pkt_padding(rtwdev, sta, pads); - } skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { @@ -3001,6 +3008,15 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); + else if (link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); + } + if (vif->p2p) lowest_rate = RTW89_HW_RATE_OFDM6; else if (chan->band_type == RTW89_BAND_2G) @@ -3064,8 +3080,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, CCTLINFO_G7_W6_ULDL); h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ULDL); - if (sta) { - h2c->w8 = le32_encode_bits(sta->deflink.he_cap.has_he, + if (rtwsta_link) { + h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT); } @@ -3454,23 +3470,27 @@ static enum rtw89_fw_sta_type rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta_link); struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; enum rtw89_fw_sta_type type; - if (!sta) - goto by_vif; - - if (sta->deflink.eht_cap.has_eht) - return RTW89_FW_BE_STA; - else if (sta->deflink.he_cap.has_he) - return RTW89_FW_AX_STA; - else - return RTW89_FW_N_AC_STA; - -by_vif: rcu_read_lock(); + if (!rtwsta_link) + goto by_vif; + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + type = RTW89_FW_BE_STA; + else if (link_sta->he_cap.has_he) + type = RTW89_FW_AX_STA; + else + type = RTW89_FW_N_AC_STA; + + goto out; + +by_vif: bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); if (bss_conf->eht_support) @@ -3480,6 +3500,7 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li else type = RTW89_FW_N_AC_STA; +out: rcu_read_unlock(); return type; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index d5097d3a3385..7ab2aac3c3d2 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5993,11 +5993,13 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - u8 mac_idx = rtwvif_link->mac_idx; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; + struct ieee80211_link_sta *link_sta; + u8 mac_idx = rtwvif_link->mac_idx; u8 port_sel = rtwvif_link->port; u8 sound_dim = 3, t; - u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; + u8 *phy_cap; u32 reg; u16 val; int ret; @@ -6006,6 +6008,11 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, if (ret) return ret; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; + if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); @@ -6014,17 +6021,19 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, phy_cap[5]); sound_dim = min(sound_dim, t); } - if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || - (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { - ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); - stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, - sta->deflink.vht_cap.cap); + link_sta->vht_cap.cap); sound_dim = min(sound_dim, t); } nc = min(nc, sound_dim); nr = min(nr, sound_dim); + rcu_read_unlock(); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); @@ -6051,30 +6060,39 @@ static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); - u32 reg; + struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; + u32 reg; int ret; ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); if (ret) return ret; - if (sta->deflink.he_cap.has_he) { + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->he_cap.has_he) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); } - if (sta->deflink.vht_cap.vht_supported) { + if (link_sta->vht_cap.vht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); } - if (sta->deflink.ht_cap.ht_supported) { + if (link_sta->ht_cap.ht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); } + + rcu_read_unlock(); + reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN); @@ -6090,8 +6108,18 @@ static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_link_sta *link_sta; + bool has_beamformer_cap; - if (rtw89_sta_has_beamformer_cap(sta)) { + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta); + + rcu_read_unlock(); + + if (has_beamformer_cap) { rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx); @@ -6145,16 +6173,23 @@ struct rtw89_mac_bf_monitor_iter_data { static void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) { + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_mac_bf_monitor_iter_data *iter_data = (struct rtw89_mac_bf_monitor_iter_data *)data; struct ieee80211_sta *down_sta = iter_data->down_sta; + struct ieee80211_link_sta *link_sta; int *count = &iter_data->count; if (down_sta == sta) return; - if (rtw89_sta_has_beamformer_cap(sta)) + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (rtw89_sta_has_beamformer_cap(link_sta)) (*count)++; + + rcu_read_unlock(); } void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index bc3215939f37..184a014a56bf 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -2095,7 +2095,9 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; + struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; u8 port_sel = rtwvif_link->port; u8 sound_dim = 3, t; @@ -2108,7 +2110,10 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, if (ret) return ret; - phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { @@ -2119,11 +2124,11 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, sound_dim = min(sound_dim, t); } - if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || - (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { - ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); - stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); - t = u32_get_bits(sta->deflink.vht_cap.cap, + if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); + stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); + t = u32_get_bits(link_sta->vht_cap.cap, IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); sound_dim = min(sound_dim, t); } @@ -2131,6 +2136,8 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, nc = min(nc, sound_dim); nr = min(nr, sound_dim); + rcu_read_unlock(); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); @@ -2159,7 +2166,9 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); + struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; int ret; u32 reg; @@ -2168,22 +2177,28 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, if (ret) return ret; - if (sta->deflink.he_cap.has_he) { + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->he_cap.has_he) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); } - if (sta->deflink.vht_cap.vht_supported) { + if (link_sta->vht_cap.vht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); } - if (sta->deflink.ht_cap.ht_supported) { + if (link_sta->ht_cap.ht_supported) { rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); } + rcu_read_unlock(); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN); @@ -2199,8 +2214,18 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_link_sta *link_sta; + bool has_beamformer_cap; - if (rtw89_sta_has_beamformer_cap(sta)) { + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta); + + rcu_read_unlock(); + + if (has_beamformer_cap) { rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 2fec179aba1b..2da0f7bf286c 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -75,12 +75,12 @@ static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap) return ra_mask; } -static u64 get_he_ra_mask(struct ieee80211_sta *sta) +static u64 get_he_ra_mask(struct ieee80211_link_sta *link_sta) { - struct ieee80211_sta_he_cap cap = sta->deflink.he_cap; + struct ieee80211_sta_he_cap cap = link_sta->he_cap; u16 mcs_map; - switch (sta->deflink.bandwidth) { + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_160: if (cap.he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) @@ -118,14 +118,14 @@ static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss) return mask; } -static u64 get_eht_ra_mask(struct ieee80211_sta *sta) +static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta) { - struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap; + struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap; struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz; struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss; - u8 *he_phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; + u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info; - switch (sta->deflink.bandwidth) { + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_320: mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._320; /* MCS 9, 11, 13 */ @@ -197,9 +197,9 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak) static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, const struct rtw89_chan *chan) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; enum nl80211_band band; u64 cfg_mask; @@ -228,17 +228,17 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, return -1; } - if (sta->deflink.he_cap.has_he) { + if (link_sta->he_cap.has_he) { cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], RA_MASK_HE_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], RA_MASK_HE_2SS_RATES); - } else if (sta->deflink.vht_cap.vht_supported) { + } else if (link_sta->vht_cap.vht_supported) { cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], RA_MASK_VHT_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], RA_MASK_VHT_2SS_RATES); - } else if (sta->deflink.ht_cap.ht_supported) { + } else if (link_sta->ht_cap.ht_supported) { cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], RA_MASK_HT_1SS_RATES); cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], @@ -296,15 +296,15 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, } static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta, bool csi) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + bool p2p, bool csi) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; struct rtw89_ra_info *ra = &rtwsta_link->ra; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta_link->rtwvif_link); const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); u64 ra_mask = 0; @@ -321,65 +321,65 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, memset(ra, 0, sizeof(*ra)); /* Set the ra mask from sta's capability */ - if (sta->deflink.eht_cap.has_eht) { + if (link_sta->eht_cap.has_eht) { mode |= RTW89_RA_MODE_EHT; - ra_mask |= get_eht_ra_mask(sta); + ra_mask |= get_eht_ra_mask(link_sta); high_rate_masks = rtw89_ra_mask_eht_rates; - } else if (sta->deflink.he_cap.has_he) { + } else if (link_sta->he_cap.has_he) { mode |= RTW89_RA_MODE_HE; csi_mode = RTW89_RA_RPT_MODE_HE; - ra_mask |= get_he_ra_mask(sta); + ra_mask |= get_he_ra_mask(link_sta); high_rate_masks = rtw89_ra_mask_he_rates; - if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[2] & + if (link_sta->he_cap.he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) stbc_en = 1; - if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] & + if (link_sta->he_cap.he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) ldpc_en = 1; rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, chan, &fix_giltf_en, &fix_giltf); - } else if (sta->deflink.vht_cap.vht_supported) { - u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); + } else if (link_sta->vht_cap.vht_supported) { + u16 mcs_map = le16_to_cpu(link_sta->vht_cap.vht_mcs.rx_mcs_map); mode |= RTW89_RA_MODE_VHT; csi_mode = RTW89_RA_RPT_MODE_VHT; /* MCS9 (non-20MHz), MCS8, MCS7 */ - if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) + if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20) ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1); else ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1); high_rate_masks = rtw89_ra_mask_vht_rates; - if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) stbc_en = 1; - if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ldpc_en = 1; - } else if (sta->deflink.ht_cap.ht_supported) { + } else if (link_sta->ht_cap.ht_supported) { mode |= RTW89_RA_MODE_HT; csi_mode = RTW89_RA_RPT_MODE_HT; - ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 48) | - ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 36) | - ((u64)sta->deflink.ht_cap.mcs.rx_mask[1] << 24) | - ((u64)sta->deflink.ht_cap.mcs.rx_mask[0] << 12); + ra_mask |= ((u64)link_sta->ht_cap.mcs.rx_mask[3] << 48) | + ((u64)link_sta->ht_cap.mcs.rx_mask[2] << 36) | + ((u64)link_sta->ht_cap.mcs.rx_mask[1] << 24) | + ((u64)link_sta->ht_cap.mcs.rx_mask[0] << 12); high_rate_masks = rtw89_ra_mask_ht_rates; - if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) + if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = 1; - if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) + if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ldpc_en = 1; } switch (chan->band_type) { case RTW89_BAND_2G: - ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; - if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xf) + ra_mask |= link_sta->supp_rates[NL80211_BAND_2GHZ]; + if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xf) mode |= RTW89_RA_MODE_CCK; - if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xff0) + if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xff0) mode |= RTW89_RA_MODE_OFDM; break; case RTW89_BAND_5G: - ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; + ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_5GHZ] << 4; mode |= RTW89_RA_MODE_OFDM; break; case RTW89_BAND_6G: - ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_6GHZ] << 4; + ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_6GHZ] << 4; mode |= RTW89_RA_MODE_OFDM; break; default: @@ -406,37 +406,37 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0); ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak); - ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, chan); + ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan); - switch (sta->deflink.bandwidth) { + switch (link_sta->bandwidth) { case IEEE80211_STA_RX_BW_160: bw_mode = RTW89_CHANNEL_WIDTH_160; - sgi = sta->deflink.vht_cap.vht_supported && - (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); + sgi = link_sta->vht_cap.vht_supported && + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); break; case IEEE80211_STA_RX_BW_80: bw_mode = RTW89_CHANNEL_WIDTH_80; - sgi = sta->deflink.vht_cap.vht_supported && - (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + sgi = link_sta->vht_cap.vht_supported && + (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); break; case IEEE80211_STA_RX_BW_40: bw_mode = RTW89_CHANNEL_WIDTH_40; - sgi = sta->deflink.ht_cap.ht_supported && - (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + sgi = link_sta->ht_cap.ht_supported && + (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); break; default: bw_mode = RTW89_CHANNEL_WIDTH_20; - sgi = sta->deflink.ht_cap.ht_supported && - (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + sgi = link_sta->ht_cap.ht_supported && + (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); break; } - if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] & + if (link_sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM) ra->dcm_cap = 1; - if (rate_pattern->enable && !vif->p2p) { - ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, chan); + if (rate_pattern->enable && !p2p) { + ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan); ra_mask &= rate_pattern->ra_mask; mode = rate_pattern->ra_mode; } @@ -447,7 +447,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra->macid = rtwsta_link->mac_id; ra->stbc_cap = stbc_en; ra->ldpc_cap = ldpc_en; - ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1; + ra->ss_num = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1; ra->en_sgi = sgi; ra->ra_mask = ra_mask; ra->fix_giltf_en = fix_giltf_en; @@ -470,9 +470,18 @@ void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta u32 changed) { struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_ra_info *ra = &rtwsta_link->ra; + struct ieee80211_link_sta *link_sta; - rtw89_phy_ra_sta_update(rtwdev, sta, false); + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link, + link_sta, vif->p2p, false); + + rcu_read_unlock(); if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) ra->upd_mask = 1; @@ -631,11 +640,22 @@ void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_ra_info *ra = &rtwsta_link->ra; u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; - bool csi = rtw89_sta_has_beamformer_cap(sta); + struct ieee80211_link_sta *link_sta; + bool csi; - rtw89_phy_ra_sta_update(rtwdev, sta, csi); + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + csi = rtw89_sta_has_beamformer_cap(link_sta); + + rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link, + link_sta, vif->p2p, csi); + + rcu_read_unlock(); if (rssi > 40) ra->init_rate_lv = 1; @@ -2554,11 +2574,11 @@ struct rtw89_phy_iter_ra_data { struct sk_buff *c2h; }; -static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) +static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link, + struct ieee80211_link_sta *link_sta, + struct rtw89_phy_iter_ra_data *ra_data) { - struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; struct rtw89_dev *rtwdev = ra_data->rtwdev; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; const struct rtw89_c2h_ra_rpt *c2h = (const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data; struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report; @@ -2662,8 +2682,22 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) | u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL); ra_report->might_fallback_legacy = mcs <= 2; - sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); - rtwsta_link->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1; + link_sta->agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); + rtwsta_link->max_agg_wait = link_sta->agg.max_rc_amsdu_len / 1500 - 1; +} + +static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_link_sta *link_sta; + + rcu_read_lock(); + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data); + + rcu_read_unlock(); } static void From 26d460e13f84426fa7dd2c0c369676034c206161 Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:56 +0800 Subject: [PATCH 023/126] wifi: rtw89: refactor VIF related func ahead for MLO Refactor VIF related functions, e.g. add/remove/assoc/mapping to separate most link stuffs into sub-functions for MLO reuse. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 10 +- drivers/net/wireless/realtek/rtw89/core.h | 4 +- drivers/net/wireless/realtek/rtw89/mac.c | 28 +--- drivers/net/wireless/realtek/rtw89/mac.h | 2 +- drivers/net/wireless/realtek/rtw89/mac80211.c | 139 ++++++++++++------ drivers/net/wireless/realtek/rtw89/phy.c | 5 +- drivers/net/wireless/realtek/rtw89/phy.h | 3 +- drivers/net/wireless/realtek/rtw89/wow.c | 4 +- 8 files changed, 113 insertions(+), 82 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 84c1952fbea8..c6d3b8fd98b6 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3466,9 +3466,9 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, case NL80211_IFTYPE_ ## _type: \ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ break -void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) +void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + const struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct ieee80211_bss_conf *bss_conf; switch (vif->type) { @@ -3638,7 +3638,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - rtw89_vif_type_mapping(vif, false); + rtw89_vif_type_mapping(rtwvif_link, false); rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true); } @@ -4785,9 +4785,9 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) EXPORT_SYMBOL(rtw89_chip_info_setup); void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif) + struct rtw89_vif_link *rtwvif_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_bss_conf *bss_conf; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 16ada1be9a0b..102fb6eba427 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -6703,10 +6703,10 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, u8 tid, u8 *cam_idx); -void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); +void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc); int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); + struct rtw89_vif_link *rtwvif_link); bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate); int rtw89_regd_setup(struct rtw89_dev *rtwdev); int rtw89_regd_init(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 7ab2aac3c3d2..a7b89a25d7c4 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4697,9 +4697,9 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, } void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif) + struct rtw89_vif_link *rtwvif_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif_link); const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_bss_conf *bss_conf; @@ -4742,32 +4742,12 @@ void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - int ret; - - rtwvif_link->mac_id = rtw89_acquire_mac_id(rtwdev); - if (rtwvif_link->mac_id == RTW89_MAX_MAC_ID_NUM) - return -ENOSPC; - - ret = rtw89_mac_vif_init(rtwdev, rtwvif_link); - if (ret) - goto release_mac_id; - - return 0; - -release_mac_id: - rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); - - return ret; + return rtw89_mac_vif_init(rtwdev, rtwvif_link); } int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - int ret; - - ret = rtw89_mac_vif_deinit(rtwdev, rtwvif_link); - rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); - - return ret; + return rtw89_mac_vif_deinit(rtwdev, rtwvif_link); } static void diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 3ea2dcbfa5b8..f2a31cba226e 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1158,7 +1158,7 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool en); void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); + struct rtw89_vif_link *rtwvif_link); void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index f04032a8a8ec..d3fad66e56cd 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -106,12 +106,60 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) return 0; } +static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_bss_conf *bss_conf; + int ret; + + rtw89_leave_ps_mode(rtwdev); + + rtw89_vif_type_mapping(rtwvif_link, false); + + INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); + INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); + + rtwvif_link->hit_rule = 0; + rtwvif_link->bcn_hit_cond = 0; + rtwvif_link->chanctx_assigned = false; + rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; + rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); + + rcu_read_unlock(); + + ret = rtw89_mac_add_vif(rtwdev, rtwvif_link); + if (ret) + return ret; + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START); + return 0; +} + +static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + mutex_unlock(&rtwdev->mutex); + cancel_work_sync(&rtwvif_link->update_beacon_work); + mutex_lock(&rtwdev->mutex); + + rtw89_leave_ps_mode(rtwdev); + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP); + + rtw89_mac_remove_vif(rtwdev, rtwvif_link); +} + static int rtw89_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct ieee80211_bss_conf *bss_conf; + u8 mac_id, port; int ret = 0; rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", @@ -128,53 +176,47 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, rtwvif_link->rtwdev = rtwdev; rtwvif_link->roc.state = RTW89_ROC_IDLE; rtwvif_link->offchan = false; - if (!rtw89_rtwvif_in_list(rtwdev, rtwvif_link)) - list_add_tail(&rtwvif_link->list, &rtwdev->rtwvifs_list); - - INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work); INIT_DELAYED_WORK(&rtwvif_link->roc.roc_work, rtw89_roc_work); - rtw89_leave_ps_mode(rtwdev); rtw89_traffic_stats_init(rtwdev, &rtwvif_link->stats); - rtw89_vif_type_mapping(vif, false); - rtwvif_link->port = rtw89_core_acquire_bit_map(rtwdev->hw_port, - RTW89_PORT_NUM); - if (rtwvif_link->port == RTW89_PORT_NUM) { + + mac_id = rtw89_acquire_mac_id(rtwdev); + if (mac_id == RTW89_MAX_MAC_ID_NUM) { ret = -ENOSPC; - list_del_init(&rtwvif_link->list); - goto out; + goto err; + } + + port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM); + if (port == RTW89_PORT_NUM) { + ret = -ENOSPC; + goto release_macid; } - rtwvif_link->bcn_hit_cond = 0; rtwvif_link->mac_idx = RTW89_MAC_0; rtwvif_link->phy_idx = RTW89_PHY_0; - rtwvif_link->chanctx_idx = RTW89_CHANCTX_0; - rtwvif_link->chanctx_assigned = false; - rtwvif_link->hit_rule = 0; - rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; - - rcu_read_lock(); - - bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); - ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr); - - rcu_read_unlock(); - - INIT_LIST_HEAD(&rtwvif_link->general_pkt_list); - - ret = rtw89_mac_add_vif(rtwdev, rtwvif_link); - if (ret) { - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); - list_del_init(&rtwvif_link->list); - goto out; - } + rtwvif_link->mac_id = mac_id; + rtwvif_link->port = port; rtw89_core_txq_init(rtwdev, vif->txq); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START); + if (!rtw89_rtwvif_in_list(rtwdev, rtwvif_link)) + list_add_tail(&rtwvif_link->list, &rtwdev->rtwvifs_list); + + ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link); + if (ret) + goto release_port; rtw89_recalc_lps(rtwdev); -out: + + mutex_unlock(&rtwdev->mutex); + return 0; + +release_port: + list_del_init(&rtwvif_link->list); + rtw89_core_release_bit_map(rtwdev->hw_port, port); +release_macid: + rtw89_release_mac_id(rtwdev, mac_id); +err: mutex_unlock(&rtwdev->mutex); return ret; @@ -189,14 +231,14 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", vif->addr, vif->type, vif->p2p); - cancel_work_sync(&rtwvif_link->update_beacon_work); cancel_delayed_work_sync(&rtwvif_link->roc.roc_work); mutex_lock(&rtwdev->mutex); - rtw89_leave_ps_mode(rtwdev); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP); - rtw89_mac_remove_vif(rtwdev, rtwvif_link); + + __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link); + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); list_del_init(&rtwvif_link->list); rtw89_recalc_lps(rtwdev); rtw89_enter_ips_by_hwflags(rtwdev); @@ -417,6 +459,7 @@ static void rtw89_conf_tx(struct rtw89_dev *rtwdev, static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_sta *sta; if (vif->type != NL80211_IFTYPE_STATION) @@ -428,11 +471,20 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, return; } - rtw89_vif_type_mapping(vif, true); + rtw89_vif_type_mapping(rtwvif_link, true); rtw89_core_sta_assoc(rtwdev, vif, sta); } +static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); + rtw89_mac_port_update(rtwdev, rtwvif_link); + rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link); +} + static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 changed) { @@ -445,10 +497,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { if (vif->cfg.assoc) { rtw89_station_mode_sta_assoc(rtwdev, vif); - rtw89_phy_set_bss_color(rtwdev, vif); - rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); - rtw89_mac_port_update(rtwdev, rtwvif_link); - rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif); + __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); rtw89_queue_chanctx_work(rtwdev); } else { @@ -494,7 +543,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, rtw89_conf_tx(rtwdev, rtwvif_link); if (changed & BSS_CHANGED_HE_BSS_COLOR) - rtw89_phy_set_bss_color(rtwdev, vif); + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); if (changed & BSS_CHANGED_MU_GROUPS) rtw89_mac_bf_set_gid_table(rtwdev, vif, conf); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 2da0f7bf286c..3cc5e94058b4 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -6177,9 +6177,10 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) rtw89_chip_cfg_txrx_path(rtwdev); } -void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld; enum rtw89_phy_idx phy_idx = RTW89_PHY_0; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 7b6ccf2f933e..310ef0570e7a 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -953,7 +953,8 @@ void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, struct rtw89_rx_phy_ppdu *phy_ppdu); void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev); void rtw89_phy_antdiv_work(struct work_struct *work); -void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); +void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, enum rtw89_tssi_bandedge_cfg bandedge_cfg); diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 17e2d5cbb1e6..20b776ae634e 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1268,8 +1268,8 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) return ret; } rtw89_phy_ra_assoc(rtwdev, wow_sta); - rtw89_phy_set_bss_color(rtwdev, wow_vif); - rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); + rtw89_phy_set_bss_color(rtwdev, rtwvif_link); + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); } if (chip_gen == RTW89_CHIP_BE) From 72e9457c1954dc39a7059bd6d6346b60a24aa55e Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:57 +0800 Subject: [PATCH 024/126] wifi: rtw89: refactor STA related func ahead for MLO Refactor STA related functions, e.g. add/assoc/disassoc/disconnect/remove to separate most link stuffs into sub-functions for MLO reuse. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-7-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 112 +++++-------- drivers/net/wireless/realtek/rtw89/core.h | 40 +++-- drivers/net/wireless/realtek/rtw89/fw.c | 17 +- drivers/net/wireless/realtek/rtw89/fw.h | 16 +- drivers/net/wireless/realtek/rtw89/mac.c | 42 +++-- drivers/net/wireless/realtek/rtw89/mac.h | 20 ++- drivers/net/wireless/realtek/rtw89/mac80211.c | 152 ++++++++++++++++-- drivers/net/wireless/realtek/rtw89/mac_be.c | 22 +-- drivers/net/wireless/realtek/rtw89/phy.c | 3 +- drivers/net/wireless/realtek/rtw89/phy.h | 2 +- drivers/net/wireless/realtek/rtw89/wow.c | 7 +- 11 files changed, 261 insertions(+), 172 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index c6d3b8fd98b6..8d2cca0b0a18 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2746,8 +2746,8 @@ static void rtw89_core_ba_work(struct work_struct *work) spin_unlock_bh(&rtwdev->ba_lock); } -static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta) +void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) { struct rtw89_txq *rtwtxq, *tmp; @@ -2761,8 +2761,8 @@ static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, spin_unlock_bh(&rtwdev->ba_lock); } -static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta) +void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) { struct rtw89_txq *rtwtxq, *tmp; @@ -2778,8 +2778,8 @@ static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, spin_unlock_bh(&rtwdev->ba_lock); } -static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta) +void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta) { struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct sk_buff *skb, *tmp; @@ -3525,26 +3525,19 @@ void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc) } } -int rtw89_core_sta_add(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; int i; int ret; - rtwsta_link->rtwdev = rtwdev; - rtwsta_link->rtwvif_link = rtwvif_link; rtwsta_link->prev_rssi = 0; INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); - skb_queue_head_init(&rtwsta_link->roc_queue); - - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - rtw89_core_txq_init(rtwdev, sta->txq[i]); - ewma_rssi_init(&rtwsta_link->avg_rssi); ewma_snr_init(&rtwsta_link->avg_snr); ewma_evm_init(&rtwsta_link->evm_1ss); @@ -3555,9 +3548,6 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, } if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - /* for station mode, assign the mac_id from itself */ - rtwsta_link->mac_id = rtwvif_link->mac_id; - /* must do rtw89_reg_6ghz_recalc() before rfk channel */ ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); if (ret) @@ -3567,13 +3557,8 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, BTC_ROLE_MSTS_STA_CONN_START); rtw89_chip_rfk_channel(rtwdev, rtwvif_link); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtwsta_link->mac_id = rtw89_acquire_mac_id(rtwdev); - if (rtwsta_link->mac_id == RTW89_MAX_MAC_ID_NUM) - return -ENOSPC; - ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false); if (ret) { - rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); return ret; } @@ -3581,7 +3566,6 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, RTW89_ROLE_CREATE); if (ret) { - rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); rtw89_warn(rtwdev, "failed to send h2c role info\n"); return ret; } @@ -3593,44 +3577,33 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) return ret; - - rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); } return 0; } -int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); if (vif->type == NL80211_IFTYPE_STATION) - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, false); - - rtwdev->total_sta_assoc--; - if (sta->tdls) - rtwvif_link->tdls_peer--; - rtwsta_link->disassoc = true; + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, false); return 0; } -int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); int ret; - rtw89_mac_bf_monitor_calc(rtwdev, sta, true); - rtw89_mac_bf_disassoc(rtwdev, vif, sta); - rtw89_core_free_sta_pending_ba(rtwdev, sta); - rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); - rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); + rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, true); + rtw89_mac_bf_disassoc(rtwdev, rtwvif_link, rtwsta_link); if (vif->type == NL80211_IFTYPE_AP || sta->tdls) rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); @@ -3642,7 +3615,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true); } - ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta); + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); return ret; @@ -3664,12 +3637,12 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, return ret; } -int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, rtwsta_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, @@ -3701,7 +3674,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, } } - ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta); + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); return ret; @@ -3720,12 +3693,9 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, return ret; } - rtwdev->total_sta_assoc++; - if (sta->tdls) - rtwvif_link->tdls_peer++; - rtw89_phy_ra_assoc(rtwdev, sta); - rtw89_mac_bf_assoc(rtwdev, vif, sta); - rtw89_mac_bf_monitor_calc(rtwdev, sta, false); + rtw89_phy_ra_assoc(rtwdev, rtwsta_link); + rtw89_mac_bf_assoc(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, false); if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { struct ieee80211_bss_conf *bss_conf; @@ -3750,18 +3720,18 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, return ret; } - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); } return ret; } -int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); int ret; if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { @@ -3769,16 +3739,12 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link, BTC_ROLE_MSTS_STA_DIS_CONN); } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtw89_release_mac_id(rtwdev, rtwsta_link->mac_id); - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, RTW89_ROLE_REMOVE); if (ret) { rtw89_warn(rtwdev, "failed to send h2c role info\n"); return ret; } - - rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); } return 0; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 102fb6eba427..1d3b987d66ad 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3656,8 +3656,8 @@ struct rtw89_chip_ops { struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -6657,21 +6657,21 @@ void rtw89_core_napi_start(struct rtw89_dev *rtwdev); void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); int rtw89_core_napi_init(struct rtw89_dev *rtwdev); void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev); -int rtw89_core_sta_add(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); +int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); +int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, struct cfg80211_tid_config *tid_config); @@ -6703,6 +6703,12 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, u8 tid, u8 *cam_idx); +void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); +void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); +void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta); void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc); int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index b1bf5f0e78f7..56f67f77b496 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2832,12 +2832,11 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, } int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); struct ieee80211_link_sta *link_sta; @@ -2980,11 +2979,10 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev, } int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; @@ -3789,10 +3787,9 @@ int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) } int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, + struct rtw89_vif_link *rtwvif_link, bool connect) { - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct ieee80211_bss_conf *bss_conf; s32 thold = RTW89_DEFAULT_CQM_THOLD; u32 hyst = RTW89_DEFAULT_CQM_HYST; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 896993d24c5b..c4239bb943e1 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4468,11 +4468,11 @@ int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -4507,7 +4507,7 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi u8 ac, u32 val); int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, + struct rtw89_vif_link *rtwvif_link, bool connect); int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, struct rtw89_rx_phy_ppdu *phy_ppdu); @@ -4709,12 +4709,12 @@ static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev, } static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; - return chip->ops->h2c_assoc_cmac_tbl(rtwdev, vif, sta); + return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); } static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index a7b89a25d7c4..28cc4885105a 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4877,7 +4877,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l if (!rtwdev->scanning && !rtwvif_link->offchan) ieee80211_connection_loss(vif); else - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); return; case RTW89_BCN_FLTR_NOTIFY: nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; @@ -5969,11 +5969,9 @@ static int rtw89_mac_init_bfee_ax(struct rtw89_dev *rtwdev, u8 mac_idx) } static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; @@ -6036,11 +6034,9 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev, } static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; @@ -6084,11 +6080,9 @@ static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev, } static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct ieee80211_link_sta *link_sta; bool has_beamformer_cap; @@ -6103,16 +6097,15 @@ static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx); - rtw89_mac_set_csi_para_reg_ax(rtwdev, vif, sta); - rtw89_mac_csi_rrsc_ax(rtwdev, vif, sta); + rtw89_mac_set_csi_para_reg_ax(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_csi_rrsc_ax(rtwdev, rtwvif_link, rtwsta_link); } } -void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false); } @@ -6146,7 +6139,7 @@ void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif * struct rtw89_mac_bf_monitor_iter_data { struct rtw89_dev *rtwdev; - struct ieee80211_sta *down_sta; + struct rtw89_sta_link *down_rtwsta_link; int count; }; @@ -6156,11 +6149,11 @@ void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_mac_bf_monitor_iter_data *iter_data = (struct rtw89_mac_bf_monitor_iter_data *)data; - struct ieee80211_sta *down_sta = iter_data->down_sta; + struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link; struct ieee80211_link_sta *link_sta; int *count = &iter_data->count; - if (down_sta == sta) + if (down_rtwsta_link == rtwsta_link) return; rcu_read_lock(); @@ -6173,12 +6166,13 @@ void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) } void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta, bool disconnect) + struct rtw89_sta_link *rtwsta_link, + bool disconnect) { struct rtw89_mac_bf_monitor_iter_data data; data.rtwdev = rtwdev; - data.down_sta = disconnect ? sta : NULL; + data.down_rtwsta_link = disconnect ? rtwsta_link : NULL; data.count = 0; ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_mac_bf_monitor_calc_iter, diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index f2a31cba226e..b781b823496f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -951,8 +951,9 @@ struct rtw89_mac_gen_def { void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev); void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable); void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable); - void (*bf_assoc)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + void (*bf_assoc)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int (*typ_fltr_opt)(struct rtw89_dev *rtwdev, enum rtw89_machdr_frame_type type, @@ -1259,21 +1260,24 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter); void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev); static inline -void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; if (mac->bf_assoc) - mac->bf_assoc(rtwdev, vif, sta); + mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link); } -void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); +void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf); void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, - struct ieee80211_sta *sta, bool disconnect); + struct rtw89_sta_link *rtwsta_link, + bool disconnect); void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev); void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en); int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index d3fad66e56cd..fc05ad1b799b 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -456,10 +456,140 @@ static void rtw89_conf_tx(struct rtw89_dev *rtwdev, __rtw89_conf_tx(rtwdev, rtwvif_link, ac); } +static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + bool acquire_macid = false; + u8 macid; + int ret; + int i; + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + /* for station mode, assign the mac_id from itself */ + macid = rtwvif_link->mac_id; + } else { + macid = rtw89_acquire_mac_id(rtwdev); + if (macid == RTW89_MAX_MAC_ID_NUM) + return -ENOSPC; + + acquire_macid = true; + } + + rtwsta_link->rtwdev = rtwdev; + rtwsta_link->rtwvif_link = rtwvif_link; + rtwsta_link->mac_id = macid; + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw89_core_txq_init(rtwdev, sta->txq[i]); + + skb_queue_head_init(&rtwsta_link->roc_queue); + + ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + goto err; + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); + + return 0; + +err: + if (acquire_macid) + rtw89_release_mac_id(rtwdev, macid); + + return ret; +} + +static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + bool station_mode) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + int ret; + + if (station_mode) + rtw89_vif_type_mapping(rtwvif_link, true); + + ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + rtwdev->total_sta_assoc++; + if (sta->tdls) + rtwvif_link->tdls_peer++; + + return 0; +} + +static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + int ret; + + ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + rtwsta_link->disassoc = true; + + rtwdev->total_sta_assoc--; + if (sta->tdls) + rtwvif_link->tdls_peer--; + + return 0; +} + +static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + int ret; + + rtw89_core_free_sta_pending_ba(rtwdev, sta); + rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); + rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); + + ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + return 0; +} + +static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + u8 macid = rtwsta_link->mac_id; + int ret; + + ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + rtw89_release_mac_id(rtwdev, macid); + rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); + } + + return 0; +} + static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_sta *sta; if (vif->type != NL80211_IFTYPE_STATION) @@ -471,9 +601,7 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, return; } - rtw89_vif_type_mapping(rtwvif_link, true); - - rtw89_core_sta_assoc(rtwdev, vif, sta); + __rtw89_ops_sta_assoc(rtwdev, vif, sta, true); } static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev, @@ -552,7 +680,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf); if (changed & BSS_CHANGED_CQM) - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); if (changed & BSS_CHANGED_TPE) rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); @@ -582,7 +710,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, ether_addr_copy(rtwvif_link->bssid, link_conf->bssid); rtw89_cam_bssid_changed(rtwdev, rtwvif_link); rtw89_mac_port_update(rtwdev, rtwvif_link); - rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); + rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE); rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); @@ -603,7 +731,7 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&rtwdev->mutex); rtw89_mac_stop_ap(rtwdev, rtwvif_link); - rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); + rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); mutex_unlock(&rtwdev->mutex); } @@ -647,26 +775,26 @@ static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, if (old_state == IEEE80211_STA_NOTEXIST && new_state == IEEE80211_STA_NONE) - return rtw89_core_sta_add(rtwdev, vif, sta); + return __rtw89_ops_sta_add(rtwdev, vif, sta); if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC) { if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) return 0; /* defer to bss_info_changed to have vif info */ - return rtw89_core_sta_assoc(rtwdev, vif, sta); + return __rtw89_ops_sta_assoc(rtwdev, vif, sta, false); } if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH) - return rtw89_core_sta_disassoc(rtwdev, vif, sta); + return __rtw89_ops_sta_disassoc(rtwdev, vif, sta); if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_NONE) - return rtw89_core_sta_disconnect(rtwdev, vif, sta); + return __rtw89_ops_sta_disconnect(rtwdev, vif, sta); if (old_state == IEEE80211_STA_NONE && new_state == IEEE80211_STA_NOTEXIST) - return rtw89_core_sta_remove(rtwdev, vif, sta); + return __rtw89_ops_sta_remove(rtwdev, vif, sta); return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index 184a014a56bf..f22eaa83297f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -2091,11 +2091,9 @@ static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx) } static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; @@ -2162,11 +2160,9 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, } static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); struct ieee80211_link_sta *link_sta; u8 mac_idx = rtwvif_link->mac_idx; @@ -2210,11 +2206,9 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, } static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct ieee80211_link_sta *link_sta; bool has_beamformer_cap; @@ -2229,8 +2223,8 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_BF, "initialize bfee for new association\n"); rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx); - rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta); - rtw89_mac_csi_rrsc_be(rtwdev, vif, sta); + rtw89_mac_set_csi_para_reg_be(rtwdev, rtwvif_link, rtwsta_link); + rtw89_mac_csi_rrsc_be(rtwdev, rtwvif_link, rtwsta_link); } } diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 3cc5e94058b4..8f1f2c7f2c54 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -637,9 +637,8 @@ void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) rtwdev); } -void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) +void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); struct rtw89_ra_info *ra = &rtwsta_link->ra; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 310ef0570e7a..727b69c45a52 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -892,7 +892,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx); } -void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); +void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, u32 changed); diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 20b776ae634e..97b527d04ad7 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1240,7 +1240,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) return ret; } - ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta); + ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); if (ret) { rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n"); return ret; @@ -1267,7 +1267,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) rtw89_warn(rtwdev, "failed to send h2c general packet\n"); return ret; } - rtw89_phy_ra_assoc(rtwdev, wow_sta); + rtw89_phy_ra_assoc(rtwdev, rtwsta_link); rtw89_phy_set_bss_color(rtwdev, rtwvif_link); rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); } @@ -1374,13 +1374,14 @@ static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_vif *vif = rtw_wow->wow_vif; + struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; int ret; ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); if (ret) rtw89_err(rtwdev, "cfg ppdu status\n"); - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); return ret; } From aad0394e7a02fe933159be79d9d4595d2ad089dd Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Mon, 16 Sep 2024 13:31:58 +0800 Subject: [PATCH 025/126] wifi: rtw89: tweak driver architecture for impending MLO support The drv_priv hooked to mac80211 become as below. (drv_priv) (instance-0) +---------------+ +-----------+ +----------------+ | ieee80211_vif | <---> | rtw89_vif | -------> | rtw89_vif_link | +---------------+ +-----------+ | +----------------+ | | (instance-1) | +----------------+ +---> | rtw89_vif_link | +----------------+ (drv_priv) (instance-0) +---------------+ +-----------+ +----------------+ | ieee80211_sta | <---> | rtw89_sta | -------> | rtw89_sta_link | +---------------+ +-----------+ | +----------------+ | | (instance-1) | +----------------+ +---> | rtw89_sta_link | +----------------+ The relation bewteen mac80211 link_id and our link instance is like below. |\ (link_id) | \ 0 -------- | | 1 -------- | | ------ instance-0 (link_id: X) -> work on HW band 0 2 -------- | | ... | | ------ instance-1 (link_id: Y) -> work on HW band 1 14 -------- | | | / |/ N.B. For cases of non-MLD connection, we set our link instance-0 active with link_id 0. So, our code flow can be compatible between non-MLD connection and MLD connection. Based on above, we tweak entire driver architecture first. But, we don't dynamically enable multiple links here. That will be handled separately. Most of the things changed here are changing flows to iterate all active links and read bss_conf/link_sta data according to target link. And, for cases of scan, ROC, WOW, we use instance-0 to deal with the request. There are some things listed below, which work for now but need to extend before multiple active links. 1. tx path select suitable link instance among multiple active links 2. rx path determine rx link by PPDU instead of always link instance-0 3. CAM apply MLD pairwise key to any active links dynamically Besides, PS code cannot easily work along with tweaking architecture. With supporting MLO flag (currently false), we disable PS first and will fix it by another commit in the following. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240916053158.47350-8-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/cam.c | 126 ++++- drivers/net/wireless/realtek/rtw89/chan.c | 77 ++- drivers/net/wireless/realtek/rtw89/coex.c | 54 +- drivers/net/wireless/realtek/rtw89/core.c | 506 +++++++++++++----- drivers/net/wireless/realtek/rtw89/core.h | 240 +++++++-- drivers/net/wireless/realtek/rtw89/debug.c | 85 ++- drivers/net/wireless/realtek/rtw89/fw.c | 145 ++--- drivers/net/wireless/realtek/rtw89/fw.h | 72 ++- drivers/net/wireless/realtek/rtw89/mac.c | 137 +++-- drivers/net/wireless/realtek/rtw89/mac.h | 2 +- drivers/net/wireless/realtek/rtw89/mac80211.c | 423 +++++++++++---- drivers/net/wireless/realtek/rtw89/phy.c | 134 +++-- drivers/net/wireless/realtek/rtw89/ps.c | 33 +- drivers/net/wireless/realtek/rtw89/regd.c | 40 +- drivers/net/wireless/realtek/rtw89/ser.c | 63 ++- drivers/net/wireless/realtek/rtw89/util.h | 8 +- drivers/net/wireless/realtek/rtw89/wow.c | 101 ++-- drivers/net/wireless/realtek/rtw89/wow.h | 6 +- 18 files changed, 1616 insertions(+), 636 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 7efc6280feaf..8d140b94cb44 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -211,24 +211,16 @@ 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_link *rtwsta_link = sta_to_rtwsta_safe(sta); - struct rtw89_vif_link *rtwvif_link; 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_link = (struct rtw89_vif_link *)vif->drv_priv; 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) { @@ -251,24 +243,16 @@ 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_link *rtwsta_link = sta_to_rtwsta_safe(sta); - struct rtw89_vif_link *rtwvif_link; 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_link = (struct rtw89_vif_link *)vif->drv_priv; addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || @@ -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, @@ -708,10 +778,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, const u8 *scan_mac_addr, u8 *cmd) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + 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_to_sta_safe(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; diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index 2968c299203b..ba6332da8019 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -234,12 +234,24 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev) rtw89_config_default_chandef(rtwdev); } +static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + if (rtwvif_link->chanctx_assigned) + return true; + + return false; +} + static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev, struct rtw89_entity_weight *w) { struct rtw89_hal *hal = &rtwdev->hal; const struct rtw89_chanctx_cfg *cfg; - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; int idx; for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) { @@ -254,8 +266,8 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev, w->active_chanctxs++; } - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - if (rtwvif_link->chanctx_assigned) + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (rtw89_vif_is_active_role(rtwvif)) w->active_roles++; } } @@ -522,14 +534,22 @@ u32 rtw89_mcc_role_fw_macid_bitmap_to_u32(struct rtw89_mcc_role *mcc_role) static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_mcc_role *mcc_role = data; - struct rtw89_vif_link *target = mcc_role->rtwvif_link; + struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *rtwsta_link; - if (rtwvif_link != target) + if (rtwvif != target) return; + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) { + rtw89_err(rtwdev, "mcc sta macid: find no link on HW-0\n"); + return; + } + rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id); } @@ -605,7 +625,7 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev, return; } - ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif_link, &tsf); + ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf); if (ret) { rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret); return; @@ -727,12 +747,19 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev) { struct rtw89_mcc_fill_role_selector sel = {}; struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; int ret; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - if (!rtwvif_link->chanctx_assigned) + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (!rtw89_vif_is_active_role(rtwvif)) continue; + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n"); + continue; + } + if (sel.bind_vif[rtwvif_link->chanctx_idx]) { rtw89_warn(rtwdev, "MCC skip extra vif on chanctx[%d]\n", @@ -2384,12 +2411,30 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev) rtw89_queue_chanctx_work(rtwdev); } +static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif, + enum rtw89_chanctx_idx idx1, + enum rtw89_chanctx_idx idx2) +{ + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + if (!rtwvif_link->chanctx_assigned) + continue; + + if (rtwvif_link->chanctx_idx == idx1) + rtwvif_link->chanctx_idx = idx2; + else if (rtwvif_link->chanctx_idx == idx2) + rtwvif_link->chanctx_idx = idx1; + } +} + static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx idx1, enum rtw89_chanctx_idx idx2) { struct rtw89_hal *hal = &rtwdev->hal; - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; u8 cur; if (idx1 == idx2) @@ -2400,14 +2445,8 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, swap(hal->chanctx[idx1], hal->chanctx[idx2]); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - if (!rtwvif_link->chanctx_assigned) - continue; - if (rtwvif_link->chanctx_idx == idx1) - rtwvif_link->chanctx_idx = idx2; - else if (rtwvif_link->chanctx_idx == idx2) - rtwvif_link->chanctx_idx = idx1; - } + rtw89_for_each_rtwvif(rtwdev, rtwvif) + __rtw89_swap_chanctx(rtwvif, idx1, idx2); cur = atomic_read(&hal->roc_chanctx_idx); if (cur == idx1) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index e4ae80742ba3..3b3fd451e445 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4989,13 +4989,11 @@ struct rtw89_txtime_data { bool reenable; }; -static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) +static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_txtime_data *iter_data) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_txtime_data *iter_data = - (struct rtw89_txtime_data *)data; struct rtw89_dev *rtwdev = iter_data->rtwdev; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_cx *cx = &btc->cx; struct rtw89_btc_wl_info *wl = &cx->wl; @@ -5048,6 +5046,21 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) } } +static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_txtime_data *iter_data = + (struct rtw89_txtime_data *)data; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + __rtw89_tx_time_iter(rtwvif_link, rtwsta_link, iter_data); + } +} + static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; @@ -7486,7 +7499,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct ieee80211_bss_conf *bss_conf; struct ieee80211_link_sta *link_sta; struct rtw89_btc *btc = &rtwdev->btc; @@ -7792,20 +7805,20 @@ struct rtw89_btc_wl_sta_iter_data { bool is_traffic_change; }; -static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) +static +void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_btc_wl_sta_iter_data *iter_data) { - struct rtw89_btc_wl_sta_iter_data *iter_data = - (struct rtw89_btc_wl_sta_iter_data *)data; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; struct rtw89_dev *rtwdev = iter_data->rtwdev; struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; const struct rtw89_btc_ver *ver = btc->ver; struct rtw89_btc_wl_info *wl = &btc->cx.wl; struct rtw89_btc_wl_link_info *link_info = NULL; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_traffic_stats *link_info_t = NULL; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct rtw89_traffic_stats *stats = &rtwvif_link->stats; + struct rtw89_traffic_stats *stats = &rtwvif->stats; const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_btc_wl_role_info *r; struct rtw89_btc_wl_role_info_v1 *r1; @@ -7823,7 +7836,7 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); link_info = &wl->link_info[port]; - link_info->stat.traffic = rtwvif_link->stats; + link_info->stat.traffic = *stats; link_info_t = &link_info->stat.traffic; if (link_info->connected == MLME_NO_LINK) { @@ -7927,6 +7940,21 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) iter_data->is_traffic_change = true; } +static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_btc_wl_sta_iter_data *iter_data = + (struct rtw89_btc_wl_sta_iter_data *)data; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + __rtw89_btc_ntfy_wl_sta_iter(rtwvif_link, rtwsta_link, iter_data); + } +} + #define BTC_NHM_CHK_INTVL 20 void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 8d2cca0b0a18..5b8e65f6de6a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -436,15 +436,6 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev) return 0; } -void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_chan *chan) -{ - const struct cfg80211_chan_def *chandef; - - chandef = rtw89_chandef_get(rtwdev, rtwvif_link->chanctx_idx); - rtw89_get_channel_params(chandef, chan); -} - static enum rtw89_core_tx_type rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, struct sk_buff *skb) @@ -463,11 +454,11 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req, enum btc_pkt_type pkt_type) { - struct ieee80211_sta *sta = tx_req->sta; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct ieee80211_link_sta *link_sta; struct sk_buff *skb = tx_req->skb; - struct rtw89_sta_link *rtwsta_link; + struct rtw89_sta *rtwsta; u8 ampdu_num; u8 tid; @@ -479,19 +470,19 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU)) return; - if (!sta) { + if (!rtwsta_link) { rtw89_warn(rtwdev, "cannot set ampdu info without sta\n"); return; } tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + rtwsta = rtwsta_link->rtwsta; rcu_read_lock(); link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); - ampdu_num = (u8)((rtwsta_link->ampdu_params[tid].agg_num ? - rtwsta_link->ampdu_params[tid].agg_num : + ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? + rtwsta->ampdu_params[tid].agg_num : 4 << link_sta->ht_cap.ampdu_factor) - 1); desc_info->agg_en = true; @@ -575,9 +566,10 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) { struct sk_buff *skb = tx_req->skb; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = tx_info->control.vif; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct ieee80211_bss_conf *bss_conf; u16 lowest_rate; u16 rate; @@ -596,7 +588,7 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, rcu_read_lock(); bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); - if (!bss_conf->basic_rates || !tx_req->sta) { + if (!bss_conf->basic_rates || !rtwsta_link) { rate = lowest_rate; goto out; } @@ -612,15 +604,12 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { - struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta_link *rtwsta_link; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; - if (!sta) + if (!rtwsta_link) return rtwvif_link->mac_id; - rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; return rtwsta_link->mac_id; } @@ -640,8 +629,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); @@ -723,8 +711,7 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req, enum btc_pkt_type pkt_type) { - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; struct sk_buff *skb = tx_req->skb; struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_link_sta *link_sta; @@ -763,8 +750,7 @@ static void __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; struct sk_buff *skb = tx_req->skb; struct ieee80211_hdr *hdr = (void *)skb->data; __le16 fc = hdr->frame_control; @@ -794,8 +780,7 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, enum btc_pkt_type pkt_type) { struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; - struct ieee80211_vif *vif = tx_req->vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) goto desc_bk; @@ -816,10 +801,9 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { - struct ieee80211_vif *vif = tx_req->vif; - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern; enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); @@ -860,10 +844,8 @@ static void rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { - struct ieee80211_vif *vif = tx_req->vif; - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); + struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link; + struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; u8 tid, tid_indicate; @@ -1076,16 +1058,37 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev, int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) { + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_core_tx_request tx_req = {0}; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_vif_link *rtwvif_link; int ret; + /* By default, driver writes tx via the link on HW-0. And then, + * according to links' status, HW can change tx to another link. + */ + + if (rtwsta) { + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) { + rtw89_err(rtwdev, "tx: find no sta link on HW-0\n"); + return -ENOLINK; + } + } + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "tx: find no vif link on HW-0\n"); + return -ENOLINK; + } + tx_req.skb = skb; - tx_req.sta = sta; - tx_req.vif = vif; + tx_req.rtwvif_link = rtwvif_link; + tx_req.rtwsta_link = rtwsta_link; rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true); - rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, true); + rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true); rtw89_core_tx_update_desc_info(rtwdev, &tx_req); rtw89_core_tx_wake(rtwdev, &tx_req); @@ -1563,15 +1566,23 @@ static u8 rtw89_get_data_rate_nss(struct rtw89_dev *rtwdev, u16 data_rate) static void rtw89_core_rx_process_phy_ppdu_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; - struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_sta_link *rtwsta_link; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; u8 ant_pos = U8_MAX; u8 evm_pos = 0; int i; + /* FIXME: For single link, taking link on HW-0 here is okay. But, when + * enabling multiple active links, we should determine the right link. + */ + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) + return; + if (rtwsta_link->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) return; @@ -1927,12 +1938,13 @@ struct rtw89_vif_rx_stats_iter_data { }; static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_bss_conf *bss_conf, struct sk_buff *skb) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data; + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; u8 *pos, *end, type, tf_bw; u16 aid, tf_rua; @@ -1963,7 +1975,7 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, if (aid == vif->cfg.aid) { enum nl80211_he_ru_alloc rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1); - rtwvif_link->stats.rx_tf_acc++; + rtwvif->stats.rx_tf_acc++; rtwdev->stats.rx_tf_acc++; if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ && rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106) @@ -2052,15 +2064,16 @@ static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link, static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_vif_rx_stats_iter_data *iter_data = data; struct rtw89_dev *rtwdev = iter_data->rtwdev; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; struct sk_buff *skb = iter_data->skb; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu; struct ieee80211_bss_conf *bss_conf; + struct rtw89_vif_link *rtwvif_link; const u8 *bssid = iter_data->bssid; if (rtwdev->scanning && @@ -2070,12 +2083,19 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, rcu_read_lock(); + /* FIXME: For single link, taking link on HW-0 here is okay. But, when + * enabling multiple active links, we should determine the right link. + */ + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) + goto out; + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false); if (!bss_conf->bssid) goto out; if (ieee80211_is_trigger(hdr->frame_control)) { - rtw89_stats_trigger_frame(rtwdev, vif, bss_conf, skb); + rtw89_stats_trigger_frame(rtwdev, rtwvif_link, bss_conf, skb); goto out; } @@ -2097,7 +2117,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, if (desc_info->data_rate < RTW89_HW_RATE_NR) pkt_stat->rx_rate_cnt[desc_info->data_rate]++; - rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, false); + rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false); out: rcu_read_unlock(); @@ -2491,10 +2511,18 @@ void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) struct rtw89_core_iter_rx_status *iter_data = (struct rtw89_core_iter_rx_status *)data; struct ieee80211_rx_status *rx_status = iter_data->rx_status; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; u8 mac_id = iter_data->mac_id; + /* FIXME: For single link, taking link on HW-0 here is okay. But, when + * enabling multiple active links, we should determine the right link. + */ + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) + return; + if (mac_id != rtwsta_link->mac_id) return; @@ -2605,6 +2633,10 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; + /* FIXME: Fix __rtw89_enter_ps_mode() to consider MLO cases. */ + if (rtwdev->support_mlo) + return RTW89_PS_MODE_NONE; + if (rtw89_disable_ps_mode || !chip->ps_mode_supported || RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw)) return RTW89_PS_MODE_NONE; @@ -2717,8 +2749,7 @@ static void rtw89_core_ba_work(struct work_struct *work) list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta_link *rtwsta_link = - sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); u8 tid = txq->tid; if (!sta) { @@ -2726,7 +2757,7 @@ static void rtw89_core_ba_work(struct work_struct *work) goto skip_ba_work; } - if (rtwsta_link->disassoc) { + if (rtwsta->disassoc) { rtw89_debug(rtwdev, RTW89_DBG_TXRX, "cannot start BA with disassoc sta\n"); goto skip_ba_work; @@ -2781,11 +2812,11 @@ void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); struct sk_buff *skb, *tmp; - skb_queue_walk_safe(&rtwsta_link->roc_queue, skb, tmp) { - skb_unlink(skb, &rtwsta_link->roc_queue); + skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { + skb_unlink(skb, &rtwsta->roc_queue); dev_kfree_skb_any(skb); } } @@ -2795,9 +2826,9 @@ static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, { struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta_link *rtwsta_link = sta_to_rtwsta_safe(sta); + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - if (unlikely(!rtwsta_link) || unlikely(rtwsta_link->disassoc)) + if (unlikely(!rtwsta) || unlikely(rtwsta->disassoc)) return; if (!test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags) || @@ -2822,8 +2853,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta_link *rtwsta_link = - sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) return; @@ -2845,7 +2875,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, } spin_lock_bh(&rtwdev->ba_lock); - if (!rtwsta_link->disassoc && list_empty(&rtwtxq->list)) { + if (!rtwsta->disassoc && list_empty(&rtwtxq->list)) { list_add_tail(&rtwtxq->list, &rtwdev->ba_list); ieee80211_queue_work(hw, &rtwdev->ba_work); } @@ -2899,11 +2929,19 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, bool *sched_txq, bool *reinvoke) { struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; - struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta_link *rtwsta_link = - sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; + struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(txq->sta); + struct rtw89_sta_link *rtwsta_link; - if (!sta || rtwsta_link->max_agg_wait <= 0) + if (!rtwsta) + return false; + + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) { + rtw89_err(rtwdev, "agg wait: find no link on HW-0\n"); + return false; + } + + if (rtwsta_link->max_agg_wait <= 0) return false; if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) @@ -2931,7 +2969,7 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv { struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_txq *txq; - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; struct rtw89_txq *rtwtxq; unsigned long frame_cnt; unsigned long byte_cnt; @@ -2941,9 +2979,9 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv ieee80211_txq_schedule_start(hw, ac); while ((txq = ieee80211_next_txq(hw, ac))) { rtwtxq = (struct rtw89_txq *)txq->drv_priv; - rtwvif_link = (struct rtw89_vif_link *)txq->vif->drv_priv; + rtwvif = vif_to_rtwvif(txq->vif); - if (rtwvif_link->offchan) { + if (rtwvif->offchan) { ieee80211_return_txq(hw, txq, true); continue; } @@ -3017,22 +3055,28 @@ static void rtw89_forbid_ba_work(struct work_struct *w) static void rtw89_core_sta_pending_tx_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_target = data; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_vif_link *target = data; + struct rtw89_vif_link *rtwvif_link; struct sk_buff *skb, *tmp; + unsigned int link_id; int qsel, ret; - if (rtwvif_link->chanctx_idx != rtwvif_target->chanctx_idx) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + if (rtwvif_link->chanctx_idx == target->chanctx_idx) + goto bottom; + + return; + +bottom: + if (skb_queue_len(&rtwsta->roc_queue) == 0) return; - if (skb_queue_len(&rtwsta_link->roc_queue) == 0) - return; - - skb_queue_walk_safe(&rtwsta_link->roc_queue, skb, tmp) { - skb_unlink(skb, &rtwsta_link->roc_queue); + skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { + skb_unlink(skb, &rtwsta->roc_queue); ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); if (ret) { @@ -3055,7 +3099,7 @@ static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev, static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool qos, bool ps) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct sk_buff *skb; @@ -3098,19 +3142,27 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, return ret; } -void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; - struct rtw89_roc *roc = &rtwvif_link->roc; + struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link; struct cfg80211_chan_def roc_chan; - struct rtw89_vif_link *tmp; + struct rtw89_vif *tmp_vif; int ret; lockdep_assert_held(&rtwdev->mutex); rtw89_leave_ips_by_hwflags(rtwdev); rtw89_leave_lps(rtwdev); + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "roc start: find no link on HW-0\n"); + return; + } + rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC); ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true); @@ -3118,9 +3170,17 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_lin rtw89_debug(rtwdev, RTW89_DBG_TXRX, "roc send null-1 failed: %d\n", ret); - rtw89_for_each_rtwvif(rtwdev, tmp) - if (tmp->chanctx_idx == rtwvif_link->chanctx_idx) - tmp->offchan = true; + rtw89_for_each_rtwvif(rtwdev, tmp_vif) { + struct rtw89_vif_link *tmp_link; + unsigned int link_id; + + rtw89_vif_for_each_link(tmp_vif, tmp_link, link_id) { + if (tmp_link->chanctx_idx == rtwvif_link->chanctx_idx) { + tmp_vif->offchan = true; + break; + } + } + } cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT); rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, &roc_chan); @@ -3130,17 +3190,18 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_lin B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); ieee80211_ready_on_channel(hw); - cancel_delayed_work(&rtwvif_link->roc.roc_work); - ieee80211_queue_delayed_work(hw, &rtwvif_link->roc.roc_work, - msecs_to_jiffies(rtwvif_link->roc.duration)); + cancel_delayed_work(&rtwvif->roc.roc_work); + ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work, + msecs_to_jiffies(rtwvif->roc.duration)); } -void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; - struct rtw89_roc *roc = &rtwvif_link->roc; - struct rtw89_vif_link *tmp; + struct rtw89_roc *roc = &rtwvif->roc; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *tmp_vif; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -3150,6 +3211,12 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) rtw89_leave_ips_by_hwflags(rtwdev); rtw89_leave_lps(rtwdev); + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "roc end: find no link on HW-0\n"); + return; + } + rtw89_write32_mask(rtwdev, rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), B_AX_RX_FLTR_CFG_MASK, @@ -3163,9 +3230,8 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) rtw89_debug(rtwdev, RTW89_DBG_TXRX, "roc send null-0 failed: %d\n", ret); - rtw89_for_each_rtwvif(rtwdev, tmp) - if (tmp->chanctx_idx == rtwvif_link->chanctx_idx) - tmp->offchan = false; + rtw89_for_each_rtwvif(rtwdev, tmp_vif) + tmp_vif->offchan = false; rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif_link); queue_work(rtwdev->txq_wq, &rtwdev->txq_work); @@ -3177,10 +3243,10 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) void rtw89_roc_work(struct work_struct *work) { - struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link, - roc.roc_work.work); - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; - struct rtw89_roc *roc = &rtwvif_link->roc; + struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, + roc.roc_work.work); + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_roc *roc = &rtwvif->roc; mutex_lock(&rtwdev->mutex); @@ -3190,7 +3256,7 @@ void rtw89_roc_work(struct work_struct *work) break; case RTW89_ROC_MGMT: case RTW89_ROC_NORMAL: - rtw89_roc_end(rtwdev, rtwvif_link); + rtw89_roc_end(rtwdev, rtwvif); break; default: break; @@ -3252,12 +3318,17 @@ static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; bool tfc_changed; tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - rtw89_traffic_stats_calc(rtwdev, &rtwvif_link->stats); - rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link); + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats); + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link); } return tfc_changed; @@ -3266,25 +3337,32 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - if ((rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && - rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || - rtwvif_link->tdls_peer) + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) return; - if (rtwvif_link->offchan) - return; - - if (rtwvif_link->stats.tx_tfc_lv == RTW89_TFC_IDLE && - rtwvif_link->stats.rx_tfc_lv == RTW89_TFC_IDLE) - rtw89_enter_lps(rtwdev, rtwvif_link, true); + rtw89_enter_lps(rtwdev, rtwvif_link, true); } static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_vif_enter_lps(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (rtwvif->tdls_peer) + continue; + if (rtwvif->offchan) + continue; + + if (rtwvif->stats.tx_tfc_lv != RTW89_TFC_IDLE || + rtwvif->stats.rx_tfc_lv != RTW89_TFC_IDLE) + continue; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_vif_enter_lps(rtwdev, rtwvif_link); + } } static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev) @@ -3468,7 +3546,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, break void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc) { - const struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct ieee80211_bss_conf *bss_conf; switch (vif->type) { @@ -3529,8 +3607,8 @@ int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; int i; @@ -3586,7 +3664,7 @@ int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); if (vif->type == NL80211_IFTYPE_STATION) rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, false); @@ -3598,8 +3676,8 @@ int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); int ret; rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, true); @@ -3641,8 +3719,8 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, rtwsta_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, @@ -3730,8 +3808,8 @@ int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); int ret; if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { @@ -4212,7 +4290,8 @@ void rtw89_core_update_beacon_work(struct work_struct *work) if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE) return; - rtwdev = rtwvif_link->rtwdev; + rtwdev = rtwvif_link->rtwvif->rtwdev; + mutex_lock(&rtwdev->mutex); rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link); mutex_unlock(&rtwdev->mutex); @@ -4409,6 +4488,168 @@ void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id) clear_bit(mac_id, rtwdev->mac_id_map); } +void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u8 mac_id, u8 port) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 support_link_num = chip->support_link_num; + u8 support_mld_num = 0; + unsigned int link_id; + u8 index; + + bitmap_zero(rtwvif->links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) + rtwvif->links[link_id] = NULL; + + rtwvif->rtwdev = rtwdev; + + if (rtwdev->support_mlo) { + rtwvif->links_inst_valid_num = support_link_num; + support_mld_num = chip->support_macid_num / support_link_num; + } else { + rtwvif->links_inst_valid_num = 1; + } + + for (index = 0; index < rtwvif->links_inst_valid_num; index++) { + struct rtw89_vif_link *inst = &rtwvif->links_inst[index]; + + inst->rtwvif = rtwvif; + inst->mac_id = mac_id + index * support_mld_num; + inst->mac_idx = RTW89_MAC_0 + index; + inst->phy_idx = RTW89_PHY_0 + index; + + /* multi-link use the same port id on different HW bands */ + inst->port = port; + } +} + +void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, u8 mac_id) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u8 support_link_num = chip->support_link_num; + u8 support_mld_num = 0; + unsigned int link_id; + u8 index; + + bitmap_zero(rtwsta->links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) + rtwsta->links[link_id] = NULL; + + rtwsta->rtwdev = rtwdev; + rtwsta->rtwvif = rtwvif; + + if (rtwdev->support_mlo) { + rtwsta->links_inst_valid_num = support_link_num; + support_mld_num = chip->support_macid_num / support_link_num; + } else { + rtwsta->links_inst_valid_num = 1; + } + + for (index = 0; index < rtwsta->links_inst_valid_num; index++) { + struct rtw89_sta_link *inst = &rtwsta->links_inst[index]; + + inst->rtwvif_link = &rtwvif->links_inst[index]; + + inst->rtwsta = rtwsta; + inst->mac_id = mac_id + index * support_mld_num; + } +} + +struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif, + unsigned int link_id) +{ + struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id]; + u8 index; + int ret; + + if (rtwvif_link) + return rtwvif_link; + + index = find_first_zero_bit(rtwvif->links_inst_map, + rtwvif->links_inst_valid_num); + if (index == rtwvif->links_inst_valid_num) { + ret = -EBUSY; + goto err; + } + + rtwvif_link = &rtwvif->links_inst[index]; + rtwvif_link->link_id = link_id; + + set_bit(index, rtwvif->links_inst_map); + rtwvif->links[link_id] = rtwvif_link; + return rtwvif_link; + +err: + rtw89_err(rtwvif->rtwdev, "vif (link_id %u) failed to set link: %d\n", + link_id, ret); + return NULL; +} + +void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id) +{ + struct rtw89_vif_link **container = &rtwvif->links[link_id]; + struct rtw89_vif_link *link = *container; + u8 index; + + if (!link) + return; + + index = rtw89_vif_link_inst_get_index(link); + clear_bit(index, rtwvif->links_inst_map); + *container = NULL; +} + +struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta, + unsigned int link_id) +{ + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id]; + struct rtw89_sta_link *rtwsta_link = rtwsta->links[link_id]; + u8 index; + int ret; + + if (rtwsta_link) + return rtwsta_link; + + if (!rtwvif_link) { + ret = -ENOLINK; + goto err; + } + + index = rtw89_vif_link_inst_get_index(rtwvif_link); + if (test_bit(index, rtwsta->links_inst_map)) { + ret = -EBUSY; + goto err; + } + + rtwsta_link = &rtwsta->links_inst[index]; + rtwsta_link->link_id = link_id; + + set_bit(index, rtwsta->links_inst_map); + rtwsta->links[link_id] = rtwsta_link; + return rtwsta_link; + +err: + rtw89_err(rtwsta->rtwdev, "sta (link_id %u) failed to set link: %d\n", + link_id, ret); + return NULL; +} + +void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id) +{ + struct rtw89_sta_link **container = &rtwsta->links[link_id]; + struct rtw89_sta_link *link = *container; + u8 index; + + if (!link) + return; + + index = rtw89_sta_link_inst_get_index(link); + clear_bit(index, rtwsta->links_inst_map); + *container = NULL; +} + int rtw89_core_init(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; @@ -4519,10 +4760,8 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv } void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, bool hw_scan) + struct rtw89_vif_link *rtwvif_link, bool hw_scan) { - struct rtw89_vif_link *rtwvif_link = - vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; struct ieee80211_bss_conf *bss_conf; if (!rtwvif_link) @@ -4753,7 +4992,7 @@ EXPORT_SYMBOL(rtw89_chip_info_setup); void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; struct ieee80211_bss_conf *bss_conf; @@ -4774,14 +5013,15 @@ void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; + u8 n = rtwdev->support_mlo ? chip->support_link_num : 1; struct ieee80211_hw *hw = rtwdev->hw; struct rtw89_efuse *efuse = &rtwdev->efuse; struct rtw89_hal *hal = &rtwdev->hal; int ret; int tx_headroom = IEEE80211_HT_CTL_LEN; - hw->vif_data_size = sizeof(struct rtw89_vif_link); - hw->sta_data_size = sizeof(struct rtw89_sta_link); + hw->vif_data_size = struct_size_t(struct rtw89_vif, links_inst, n); + hw->sta_data_size = struct_size_t(struct rtw89_sta, links_inst, n); hw->txq_data_size = sizeof(struct rtw89_txq); hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 1d3b987d66ad..ac9f9d33436c 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -829,6 +829,8 @@ enum rtw89_phy_idx { RTW89_PHY_MAX }; +#define __RTW89_MLD_MAX_LINK_NUM 2 + enum rtw89_chanctx_idx { RTW89_CHANCTX_0 = 0, RTW89_CHANCTX_1 = 1, @@ -1166,8 +1168,8 @@ struct rtw89_core_tx_request { enum rtw89_core_tx_type tx_type; struct sk_buff *skb; - struct ieee80211_vif *vif; - struct ieee80211_sta *sta; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; struct rtw89_tx_desc_info desc_info; }; @@ -3355,12 +3357,11 @@ struct rtw89_sec_cam_entry { }; struct rtw89_sta_link { + struct rtw89_sta *rtwsta; unsigned int link_id; u8 mac_id; - bool disassoc; bool er_cap; - struct rtw89_dev *rtwdev; struct rtw89_vif_link *rtwvif_link; struct rtw89_ra_info ra; struct rtw89_ra_report ra_report; @@ -3372,15 +3373,12 @@ struct rtw89_sta_link { struct ewma_evm evm_1ss; struct ewma_evm evm_min[RF_PATH_MAX]; struct ewma_evm evm_max[RF_PATH_MAX]; - struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; - DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS); struct ieee80211_rx_status rx_status; u16 rx_hw_rate; __le32 htc_template; struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */ struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */ struct list_head ba_cam_list; - struct sk_buff_head roc_queue; bool use_cfg_mask; struct cfg80211_bitrate_mask mask; @@ -3463,11 +3461,9 @@ struct rtw89_p2p_noa_setter { }; struct rtw89_vif_link { + struct rtw89_vif *rtwvif; unsigned int link_id; - struct list_head list; - struct rtw89_dev *rtwdev; - struct rtw89_roc roc; bool chanctx_assigned; /* only valid when running with chanctx_ops */ enum rtw89_chanctx_idx chanctx_idx; enum rtw89_reg_6ghz_power reg_6ghz_power; @@ -3477,7 +3473,6 @@ struct rtw89_vif_link { u8 port; u8 mac_addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; - __be32 ip_addr; u8 phy_idx; u8 mac_idx; u8 net_type; @@ -3488,7 +3483,6 @@ struct rtw89_vif_link { u8 hit_rule; u8 last_noa_nr; u64 sync_bcn_tsf; - bool offchan; bool trigger; bool lsig_txop; u8 tgt_ind; @@ -3502,15 +3496,11 @@ struct rtw89_vif_link { bool pre_pwr_diff_en; bool pwr_diff_en; u8 def_tri_idx; - u32 tdls_peer; struct work_struct update_beacon_work; struct rtw89_addr_cam_entry addr_cam; struct rtw89_bssid_cam_entry bssid_cam; struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; - struct rtw89_traffic_stats stats; struct rtw89_phy_rate_pattern rate_pattern; - struct cfg80211_scan_request *scan_req; - struct ieee80211_scan_ies *scan_ies; struct list_head general_pkt_list; struct rtw89_p2p_noa_setter p2p_noa; }; @@ -3659,14 +3649,16 @@ struct rtw89_chip_ops { struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int (*h2c_update_beacon)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); - int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, + int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); void (*btc_set_rfe)(struct rtw89_dev *rtwdev); @@ -5201,7 +5193,7 @@ struct rtw89_early_h2c { }; struct rtw89_hw_scan_info { - struct ieee80211_vif *scanning_vif; + struct rtw89_vif_link *scanning_vif; struct list_head pkt_list[NUM_NL80211_BANDS]; struct rtw89_chan op_chan; bool abort; @@ -5376,7 +5368,7 @@ struct rtw89_wow_aoac_report { }; struct rtw89_wow_param { - struct ieee80211_vif *wow_vif; + struct rtw89_vif_link *rtwvif_link; DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; struct rtw89_wow_key_info key_info; @@ -5613,6 +5605,121 @@ struct rtw89_dev { u8 priv[] __aligned(sizeof(void *)); }; +struct rtw89_vif { + struct rtw89_dev *rtwdev; + struct list_head list; + + u8 mac_addr[ETH_ALEN]; + __be32 ip_addr; + + struct rtw89_traffic_stats stats; + u32 tdls_peer; + + struct ieee80211_scan_ies *scan_ies; + struct cfg80211_scan_request *scan_req; + + struct rtw89_roc roc; + bool offchan; + + u8 links_inst_valid_num; + DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS]; + struct rtw89_vif_link links_inst[] __counted_by(links_inst_valid_num); +}; + +static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwvif_link, + const struct rtw89_vif *rtwvif, + unsigned int link_id) +{ + *rtwvif_link = rtwvif->links[link_id]; + return !!*rtwvif_link; +} + +#define rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) \ + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \ + if (rtw89_vif_assign_link_is_valid(&(rtwvif_link), rtwvif, link_id)) + +struct rtw89_sta { + struct rtw89_dev *rtwdev; + struct rtw89_vif *rtwvif; + + bool disassoc; + + struct sk_buff_head roc_queue; + + struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; + DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS); + + u8 links_inst_valid_num; + DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM); + struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS]; + struct rtw89_sta_link links_inst[] __counted_by(links_inst_valid_num); +}; + +static inline bool rtw89_sta_assign_link_is_valid(struct rtw89_sta_link **rtwsta_link, + const struct rtw89_sta *rtwsta, + unsigned int link_id) +{ + *rtwsta_link = rtwsta->links[link_id]; + return !!*rtwsta_link; +} + +#define rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) \ + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \ + if (rtw89_sta_assign_link_is_valid(&(rtwsta_link), rtwsta, link_id)) + +static inline u8 rtw89_vif_get_main_macid(struct rtw89_vif *rtwvif) +{ + /* const after init, so no need to check if active first */ + return rtwvif->links_inst[0].mac_id; +} + +static inline u8 rtw89_vif_get_main_port(struct rtw89_vif *rtwvif) +{ + /* const after init, so no need to check if active first */ + return rtwvif->links_inst[0].port; +} + +static inline struct rtw89_vif_link * +rtw89_vif_get_link_inst(struct rtw89_vif *rtwvif, u8 index) +{ + if (index >= rtwvif->links_inst_valid_num || + !test_bit(index, rtwvif->links_inst_map)) + return NULL; + return &rtwvif->links_inst[index]; +} + +static inline +u8 rtw89_vif_link_inst_get_index(struct rtw89_vif_link *rtwvif_link) +{ + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + + return rtwvif_link - rtwvif->links_inst; +} + +static inline u8 rtw89_sta_get_main_macid(struct rtw89_sta *rtwsta) +{ + /* const after init, so no need to check if active first */ + return rtwsta->links_inst[0].mac_id; +} + +static inline struct rtw89_sta_link * +rtw89_sta_get_link_inst(struct rtw89_sta *rtwsta, u8 index) +{ + if (index >= rtwsta->links_inst_valid_num || + !test_bit(index, rtwsta->links_inst_map)) + return NULL; + return &rtwsta->links_inst[index]; +} + +static inline +u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + + return rtwsta_link - rtwsta->links_inst; +} + static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { @@ -5965,44 +6072,78 @@ static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, INIT_LIST_HEAD(&rtwtxq->list); } -static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif_link *rtwvif_link) +static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) { - void *p = rtwvif_link; + void *p = rtwvif; return container_of(p, struct ieee80211_vif, drv_priv); } -static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif_link *rtwvif_link) +static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif) { - return rtwvif_link ? rtwvif_to_vif(rtwvif_link) : NULL; + return rtwvif ? rtwvif_to_vif(rtwvif) : NULL; } -static inline struct rtw89_vif_link *vif_to_rtwvif_safe(struct ieee80211_vif *vif) +static inline +struct ieee80211_vif *rtwvif_link_to_vif(struct rtw89_vif_link *rtwvif_link) { - return vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; + return rtwvif_to_vif(rtwvif_link->rtwvif); } -static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta_link *rtwsta_link) +static inline +struct ieee80211_vif *rtwvif_link_to_vif_safe(struct rtw89_vif_link *rtwvif_link) { - void *p = rtwsta_link; + return rtwvif_link ? rtwvif_link_to_vif(rtwvif_link) : NULL; +} + +static inline struct rtw89_vif *vif_to_rtwvif(struct ieee80211_vif *vif) +{ + return (struct rtw89_vif *)vif->drv_priv; +} + +static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif) +{ + return vif ? vif_to_rtwvif(vif) : NULL; +} + +static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) +{ + void *p = rtwsta; return container_of(p, struct ieee80211_sta, drv_priv); } -static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta_link *rtwsta_link) +static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta) { - return rtwsta_link ? rtwsta_to_sta(rtwsta_link) : NULL; + return rtwsta ? rtwsta_to_sta(rtwsta) : NULL; } -static inline struct rtw89_sta_link *sta_to_rtwsta_safe(struct ieee80211_sta *sta) +static inline +struct ieee80211_sta *rtwsta_link_to_sta(struct rtw89_sta_link *rtwsta_link) { - return sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL; + return rtwsta_to_sta(rtwsta_link->rtwsta); +} + +static inline +struct ieee80211_sta *rtwsta_link_to_sta_safe(struct rtw89_sta_link *rtwsta_link) +{ + return rtwsta_link ? rtwsta_link_to_sta(rtwsta_link) : NULL; +} + +static inline struct rtw89_sta *sta_to_rtwsta(struct ieee80211_sta *sta) +{ + return (struct rtw89_sta *)sta->drv_priv; +} + +static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta) +{ + return sta ? sta_to_rtwsta(sta) : NULL; } static inline struct ieee80211_bss_conf * __rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct ieee80211_bss_conf *bss_conf; bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]); @@ -6023,7 +6164,7 @@ __rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolin \ bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \ if (unlikely(nolink) && (assert)) \ - rtw89_err(p->rtwdev, \ + rtw89_err(p->rtwvif->rtwdev, \ "%s: cannot find exact bss_conf for link_id %u\n",\ __func__, p->link_id); \ bss_conf; \ @@ -6032,7 +6173,7 @@ __rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolin static inline struct ieee80211_link_sta * __rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); struct ieee80211_link_sta *link_sta; link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]); @@ -6053,7 +6194,7 @@ __rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolin \ link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \ if (unlikely(nolink) && (assert)) \ - rtw89_err(p->rtwdev, \ + rtw89_err(p->rtwsta->rtwdev, \ "%s: cannot find exact link_sta for link_id %u\n",\ __func__, p->link_id); \ link_sta; \ @@ -6147,7 +6288,7 @@ struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif struct rtw89_sta_link *rtwsta_link) { if (rtwsta_link) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) return &rtwsta_link->addr_cam; @@ -6160,7 +6301,7 @@ struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwv struct rtw89_sta_link *rtwsta_link) { if (rtwsta_link) { - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link); + struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link); if (sta->tdls) return &rtwsta_link->bssid_cam; @@ -6224,8 +6365,7 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev, static inline const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev) { - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; if (rtwvif_link) return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); @@ -6687,13 +6827,21 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev); u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev); void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id); +void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u8 mac_id, u8 port); +void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta, u8 mac_id); +struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif, + unsigned int link_id); +void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id); +struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta, + unsigned int link_id); +void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id); void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev); void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef); void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef, struct rtw89_chan *chan); int rtw89_set_channel(struct rtw89_dev *rtwdev); -void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, - struct rtw89_chan *chan); u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); @@ -6727,12 +6875,12 @@ int rtw89_core_start(struct rtw89_dev *rtwdev); void rtw89_core_stop(struct rtw89_dev *rtwdev); void rtw89_core_update_beacon_work(struct work_struct *work); void rtw89_roc_work(struct work_struct *work); -void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); -void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, const u8 *mac_addr, bool hw_scan); void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, bool hw_scan); + struct rtw89_vif_link *rtwvif_link, bool hw_scan); int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool active); void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index cc7aaf6fa31f..7391f131229a 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3506,7 +3506,9 @@ static ssize_t rtw89_debug_priv_fw_log_manual_set(struct file *filp, return count; } -static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) +static void rtw89_sta_link_info_get_iter(struct seq_file *m, + struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) { static const char * const he_gi_str[] = { [NL80211_RATE_INFO_HE_GI_0_8] = "0.8", @@ -3518,11 +3520,8 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) [NL80211_RATE_INFO_EHT_GI_1_6] = "1.6", [NL80211_RATE_INFO_EHT_GI_3_2] = "3.2", }; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rate_info *rate = &rtwsta_link->ra_report.txrate; struct ieee80211_rx_status *status = &rtwsta_link->rx_status; - struct seq_file *m = (struct seq_file *)data; - struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; struct rtw89_hal *hal = &rtwdev->hal; u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; @@ -3540,7 +3539,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) rcu_read_unlock(); - seq_printf(m, "TX rate [%d]: ", rtwsta_link->mac_id); + seq_printf(m, "TX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); if (rate->flags & RATE_INFO_FLAGS_MCS) seq_printf(m, "HT MCS-%d%s", rate->mcs, @@ -3560,11 +3559,11 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) seq_printf(m, "Legacy %d", rate->legacy); seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); - seq_printf(m, "\t(hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); - seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, + seq_printf(m, " (hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); + seq_printf(m, " ==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, max_rc_amsdu_len); - seq_printf(m, "RX rate [%d]: ", rtwsta_link->mac_id); + seq_printf(m, "RX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); switch (status->encoding) { case RX_ENC_LEGACY: @@ -3591,7 +3590,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) break; } seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); - seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate); + seq_printf(m, " (hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate); rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [", @@ -3620,6 +3619,18 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) seq_printf(m, "SNR: %u\n", snr); } +static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) +{ + struct seq_file *m = (struct seq_file *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + rtw89_sta_link_info_get_iter(m, rtwdev, rtwsta_link); +} + static void rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat, enum rtw89_hw_rate first_rate, int len) @@ -3746,25 +3757,37 @@ static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_lis seq_puts(m, "\n"); } -static -void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +static void rtw89_vif_link_ids_get(struct seq_file *m, u8 *mac, + struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; - struct seq_file *m = (struct seq_file *)data; struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; - seq_printf(m, "VIF [%d] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr); + seq_printf(m, " [%u] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr); + seq_printf(m, "\tlink_id=%u\n", rtwvif_link->link_id); seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam); rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list, "\tpkt_ofld[GENERAL]: "); } -static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta_link *rtwsta_link) +static +void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct seq_file *m = (struct seq_file *)data; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + seq_printf(m, "VIF %pM\n", rtwvif->mac_addr); + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_vif_link_ids_get(m, mac, rtwdev, rtwvif_link); +} + +static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; struct rtw89_ba_cam_entry *entry; bool first = true; @@ -3781,24 +3804,36 @@ static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta_link *rtwsta_ seq_puts(m, "\n"); } -static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) +static void rtw89_sta_link_ids_get(struct seq_file *m, + struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; - struct seq_file *m = (struct seq_file *)data; struct ieee80211_link_sta *link_sta; rcu_read_lock(); link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); - seq_printf(m, "STA [%d] %pM %s\n", rtwsta_link->mac_id, link_sta->addr, - sta->tdls ? "(TDLS)" : ""); + seq_printf(m, " [%u] %pM\n", rtwsta_link->mac_id, link_sta->addr); rcu_read_unlock(); + seq_printf(m, "\tlink_id=%u\n", rtwsta_link->link_id); rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam); - rtw89_dump_ba_cam(m, rtwsta_link); + rtw89_dump_ba_cam(m, rtwdev, rtwsta_link); +} + +static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta) +{ + struct seq_file *m = (struct seq_file *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + seq_printf(m, "STA %pM %s\n", sta->addr, sta->tdls ? "(TDLS)" : ""); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + rtw89_sta_link_ids_get(m, rtwdev, rtwsta_link); } static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 56f67f77b496..3c4a3302d43d 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1910,11 +1910,12 @@ int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); -int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_h2c_ba_cam *h2c; u8 macid = rtwsta_link->mac_id; u32 len = sizeof(*h2c); @@ -2044,11 +2045,12 @@ void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) } } -int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_h2c_ba_cam_v1 *h2c; u8 macid = rtwsta_link->mac_id; u32 len = sizeof(*h2c); @@ -2294,6 +2296,7 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev, static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct ieee80211_hdr_3addr *hdr; @@ -2333,7 +2336,7 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev, arp_hdr->ar_op = htons(ARPOP_REPLY); ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr); - arp_skb->sender_ip = rtwvif_link->ip_addr; + arp_skb->sender_ip = rtwvif->ip_addr; return skb; } @@ -2343,7 +2346,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, enum rtw89_fw_pkt_ofld_type type, u8 *id) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_pktofld_info *info; struct sk_buff *skb; int ret; @@ -2416,9 +2419,13 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, notify_fw); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, + notify_fw); } #define H2C_GENERAL_PKT_LEN 6 @@ -2835,7 +2842,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); @@ -2982,7 +2989,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; @@ -3106,10 +3113,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7); int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; struct rtw89_h2c_cctlinfo_ud_g7 *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -3126,11 +3133,11 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, skb_put(skb, len); h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data; - for_each_set_bit(tid, rtwsta_link->ampdu_map, IEEE80211_NUM_TIDS) { + for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { if (agg_num == 0) - agg_num = rtwsta_link->ampdu_params[tid].agg_num; + agg_num = rtwsta->ampdu_params[tid].agg_num; else - agg_num = min(agg_num, rtwsta_link->ampdu_params[tid].agg_num); + agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); } if (agg_num <= 0x20) @@ -3257,7 +3264,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_h2c_bcn_upd *h2c; struct sk_buff *skb_beacon; struct ieee80211_hdr *hdr; @@ -3336,7 +3343,7 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_h2c_bcn_upd_be *h2c; struct sk_buff *skb_beacon; struct ieee80211_hdr *hdr; @@ -3900,7 +3907,8 @@ int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct rtw89_traffic_stats *stats = &rtwvif_link->stats; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct rtw89_traffic_stats *stats = &rtwvif->stats; struct rtw89_h2c_ofld *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; @@ -5031,9 +5039,10 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool wowlan) { + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_h2c_scanofld_be_macc_role *macc_role; struct rtw89_chan *op = &scan_info->op_chan; struct rtw89_h2c_scanofld_be_opch *opch; @@ -5950,12 +5959,10 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) } static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, - struct rtw89_vif_link *rtwvif_link, + struct cfg80211_scan_request *req, struct rtw89_pktofld_info *info, enum nl80211_band band, u8 ssid_idx) { - struct cfg80211_scan_request *req = rtwvif_link->scan_req; - if (band != NL80211_BAND_6GHZ) return false; @@ -5975,7 +5982,9 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, struct sk_buff *skb, u8 ssid_idx) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct ieee80211_scan_ies *ies = rtwvif_link->scan_ies; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_pktofld_info *info; struct sk_buff *new; int ret = 0; @@ -6000,8 +6009,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, goto out; } - rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif_link, info, band, - ssid_idx); + rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx); ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); if (ret) { @@ -6020,7 +6028,8 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct sk_buff *skb; u8 num = req->n_ssids, i; int ret; @@ -6044,13 +6053,12 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev, } static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, + struct ieee80211_scan_ies *ies, struct cfg80211_scan_request *req, struct rtw89_mac_chinfo *ch_info) { - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; struct list_head *pkt_list = rtwdev->scan_info.pkt_list; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - struct ieee80211_scan_ies *ies = rtwvif_link->scan_ies; struct cfg80211_scan_6ghz_params *params; struct rtw89_pktofld_info *info, *tmp; struct ieee80211_hdr *hdr; @@ -6169,9 +6177,10 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, struct rtw89_mac_chinfo *ch_info) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_chan *op = &rtwdev->scan_info.op_chan; struct rtw89_pktofld_info *info; u8 band, probe_count = 0; @@ -6196,7 +6205,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, } } - ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info); + ret = rtw89_update_6ghz_rnr_chan(rtwdev, ies, req, ch_info); if (ret) rtw89_warn(rtwdev, "RNR fails: %d\n", ret); @@ -6286,9 +6295,9 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type, struct rtw89_mac_chinfo_be *ch_info) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_pktofld_info *info; u8 band, probe_count = 0, i; @@ -6396,7 +6405,8 @@ int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool connected) { - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_mac_chinfo *ch_info, *tmp; struct ieee80211_channel *channel; struct list_head chan_list; @@ -6525,7 +6535,8 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool connected) { - struct cfg80211_scan_request *req = rtwvif_link->scan_req; + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; + struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_mac_chinfo_be *ch_info, *tmp; struct ieee80211_channel *channel; struct list_head chan_list; @@ -6597,21 +6608,26 @@ static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, return ret; } -void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, struct ieee80211_scan_request *scan_req) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct cfg80211_scan_request *req = &scan_req->req; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, + rtwvif_link->chanctx_idx); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; u32 rx_fltr = rtwdev->hal.rx_fltr; u8 mac_addr[ETH_ALEN]; - rtw89_get_channel(rtwdev, rtwvif_link, &rtwdev->scan_info.op_chan); - rtwdev->scan_info.scanning_vif = vif; + /* clone op and keep it during scan */ + rtwdev->scan_info.op_chan = *chan; + + rtwdev->scan_info.scanning_vif = rtwvif_link; rtwdev->scan_info.last_chan_idx = 0; rtwdev->scan_info.abort = false; - rtwvif_link->scan_ies = &scan_req->ies; - rtwvif_link->scan_req = req; + rtwvif->scan_ies = &scan_req->ies; + rtwvif->scan_req = req; ieee80211_stop_queues(rtwdev->hw); rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false); @@ -6633,33 +6649,36 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN); } -void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool aborted) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); struct cfg80211_scan_info info = { .aborted = aborted, }; + struct rtw89_vif *rtwvif; - if (!vif) + if (!rtwvif_link) return; + rtwvif = rtwvif_link->rtwvif; + rtw89_write32_mask(rtwdev, rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); - rtw89_core_scan_complete(rtwdev, vif, true); + rtw89_core_scan_complete(rtwdev, rtwvif_link, true); ieee80211_scan_completed(rtwdev->hw, &info); ieee80211_wake_queues(rtwdev->hw); rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true); rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); rtw89_release_pkt_list(rtwdev); - rtwvif_link->scan_req = NULL; - rtwvif_link->scan_ies = NULL; + rtwvif->scan_req = NULL; + rtwvif->scan_ies = NULL; scan_info->last_chan_idx = 0; scan_info->scanning_vif = NULL; scan_info->abort = false; @@ -6667,14 +6686,15 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, rtw89_chanctx_proceed(rtwdev); } -void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; int ret; scan_info->abort = true; - ret = rtw89_hw_scan_offload(rtwdev, vif, false); + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false); if (ret) rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret); @@ -6683,32 +6703,35 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan * work properly. */ - rtw89_hw_scan_complete(rtwdev, vif, true); + rtw89_hw_scan_complete(rtwdev, rtwvif_link, true); } static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - /* This variable implies connected or during attempt to connect */ - if (!is_zero_ether_addr(rtwvif_link->bssid)) - return true; + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + /* This variable implies connected or during attempt to connect */ + if (!is_zero_ether_addr(rtwvif_link->bssid)) + return true; + } } return false; } -int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_scan_option opt = {0}; - struct rtw89_vif_link *rtwvif_link; bool connected; int ret = 0; - rtwvif_link = vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL; if (!rtwvif_link) return -EINVAL; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index c4239bb943e1..a083bed3822b 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4474,8 +4474,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, @@ -4569,9 +4569,13 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool notify_fw); void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); -int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, +int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); -int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, +int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users, @@ -4590,13 +4594,17 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, struct rtw89_mac_c2h_info *c2h_info); int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); -void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_scan_request *req); -void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct ieee80211_scan_request *scan_req); +void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool aborted); -int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, +int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool enable); -void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); +void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool connected); int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, @@ -4717,25 +4725,59 @@ static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); } -static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static inline +int rtw89_chip_h2c_ampdu_link_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->ops->h2c_ampdu_cmac_tbl) - return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, vif, sta); + return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, rtwvif_link, + rtwsta_link); + + return 0; +} + +static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_sta *rtwsta) +{ + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_chip_h2c_ampdu_link_cmac_tbl(rtwdev, rtwvif_link, + rtwsta_link); + if (ret) + return ret; + } return 0; } static inline -int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link, +int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params) { const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + int ret; - return chip->ops->h2c_ba_cam(rtwdev, rtwsta_link, valid, params); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = chip->ops->h2c_ba_cam(rtwdev, rtwvif_link, rtwsta_link, + valid, params); + if (ret) + return ret; + } + + return 0; } /* must consider compatibility; don't insert new in the mid */ diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 28cc4885105a..4e15d539e3d1 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4298,10 +4298,13 @@ static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev, void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) - rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en); } static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, @@ -4547,13 +4550,17 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *src = NULL, *tmp; u8 offset = 100, vif_aps = 0; + struct rtw89_vif *rtwvif; + unsigned int link_id; int n_offset = 1; - rtw89_for_each_rtwvif(rtwdev, tmp) { - if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA) - src = tmp; - if (tmp->net_type == RTW89_NET_TYPE_AP_MODE) - vif_aps++; + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, tmp, link_id) { + if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA) + src = tmp; + if (tmp->net_type == RTW89_NET_TYPE_AP_MODE) + vif_aps++; + } } if (vif_aps == 0) @@ -4561,8 +4568,10 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) offset /= (vif_aps + 1); - rtw89_for_each_rtwvif(rtwdev, tmp) - rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, tmp, link_id) + rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, + &n_offset); } int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) @@ -4699,7 +4708,7 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_bss_conf *bss_conf; @@ -4768,8 +4777,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, { const struct rtw89_c2h_scanofld *c2h = (const struct rtw89_c2h_scanofld *)skb->data; - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif; + struct rtw89_vif *rtwvif; struct rtw89_chan new; u8 reason, status, tx_fail, band, actual_period, expect_period; u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf; @@ -4780,6 +4789,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, if (!rtwvif_link) return; + rtwvif = rtwvif_link->rtwvif; + tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL); status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS); chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH); @@ -4819,15 +4830,15 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, if (rtwdev->scan_info.abort) return; - if (rtwvif_link && rtwvif_link->scan_req && - last_chan < rtwvif_link->scan_req->n_channels) { - ret = rtw89_hw_scan_offload(rtwdev, vif, true); + if (rtwvif_link && rtwvif->scan_req && + last_chan < rtwvif->scan_req->n_channels) { + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true); if (ret) { - rtw89_hw_scan_abort(rtwdev, vif); + rtw89_hw_scan_abort(rtwdev, rtwvif_link); rtw89_warn(rtwdev, "HW scan failed: %d\n", ret); } } else { - rtw89_hw_scan_complete(rtwdev, vif, false); + rtw89_hw_scan_complete(rtwdev, rtwvif_link, false); } break; case RTW89_SCAN_ENTER_OP_NOTIFY: @@ -4853,7 +4864,8 @@ static void rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct sk_buff *skb) { - struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; enum nl80211_cqm_rssi_threshold_event nl_event; const struct rtw89_c2h_mac_bcnfltr_rpt *c2h = (const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data; @@ -4874,7 +4886,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l switch (type) { case RTW89_BCN_FLTR_BEACON_LOSS: - if (!rtwdev->scanning && !rtwvif_link->offchan) + if (!rtwdev->scanning && !rtwvif->offchan) ieee80211_connection_loss(vif); else rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); @@ -4902,9 +4914,12 @@ rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h); } static void @@ -6112,10 +6127,21 @@ void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - u8 mac_idx = rtwvif_link->mac_idx; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + u8 mac_idx; __le32 *p; + rtwvif_link = rtwvif->links[conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, conf->link_id); + return; + } + + mac_idx = rtwvif_link->mac_idx; + rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n"); p = (__le32 *)conf->mu_group.membership; @@ -6146,20 +6172,30 @@ struct rtw89_mac_bf_monitor_iter_data { static void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; struct rtw89_mac_bf_monitor_iter_data *iter_data = (struct rtw89_mac_bf_monitor_iter_data *)data; struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); struct ieee80211_link_sta *link_sta; + struct rtw89_sta_link *rtwsta_link; + bool has_beamformer_cap = false; int *count = &iter_data->count; - - if (down_rtwsta_link == rtwsta_link) - return; + unsigned int link_id; rcu_read_lock(); - link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); - if (rtw89_sta_has_beamformer_cap(link_sta)) + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + if (rtwsta_link == down_rtwsta_link) + continue; + + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + if (rtw89_sta_has_beamformer_cap(link_sta)) { + has_beamformer_cap = true; + break; + } + } + + if (has_beamformer_cap) (*count)++; rcu_read_unlock(); @@ -6191,7 +6227,9 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) struct rtw89_vif_link *rtwvif_link; bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv; bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); + struct rtw89_vif *rtwvif; bool keep_timer = true; + unsigned int link_id; bool old_keep_timer; old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); @@ -6200,16 +6238,18 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) keep_timer = false; if (keep_timer != old_keep_timer) { - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx, - keep_timer); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx, + keep_timer); } if (en == old) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en); } static int @@ -6393,7 +6433,9 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val) } static -void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) +void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) { static const enum rtw89_pkt_drop_sel sels[] = { RTW89_PKT_DROP_SEL_MACID_BE_ONCE, @@ -6401,7 +6443,6 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtw RTW89_PKT_DROP_SEL_MACID_VI_ONCE, RTW89_PKT_DROP_SEL_MACID_VO_ONCE, }; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_pkt_drop_params params = {0}; int i; @@ -6419,22 +6460,28 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtw static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; - struct rtw89_vif_link *target = data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + struct rtw89_vif *target = data; + unsigned int link_id; - if (rtwvif_link != target) + if (rtwvif != target) return; - rtw89_mac_pkt_drop_sta(rtwdev, rtwsta_link); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + rtw89_mac_pkt_drop_sta(rtwdev, rtwvif_link, rtwsta_link); + } } -void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_mac_pkt_drop_vif_iter, - rtwvif_link); + rtwvif); } int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index b781b823496f..0c269961a573 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1466,7 +1466,7 @@ int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val) return mac->read_xtal_si(rtwdev, offset, val); } -void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, enum rtw89_mac_idx band); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index fc05ad1b799b..44ba4dc181b5 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -23,17 +23,16 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); struct ieee80211_sta *sta = control->sta; u32 flags = IEEE80211_SKB_CB(skb)->flags; int ret, qsel; - if (rtwvif_link->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { - struct rtw89_sta_link *rtwsta_link = - (struct rtw89_sta_link *)sta->drv_priv; + if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n"); - skb_queue_tail(&rtwsta_link->roc_queue, skb); + skb_queue_tail(&rtwsta->roc_queue, skb); return; } @@ -158,7 +157,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; u8 mac_id, port; int ret = 0; @@ -173,13 +173,6 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | IEEE80211_VIF_SUPPORTS_CQM_RSSI; - rtwvif_link->rtwdev = rtwdev; - rtwvif_link->roc.state = RTW89_ROC_IDLE; - rtwvif_link->offchan = false; - INIT_DELAYED_WORK(&rtwvif_link->roc.roc_work, rtw89_roc_work); - - rtw89_traffic_stats_init(rtwdev, &rtwvif_link->stats); - mac_id = rtw89_acquire_mac_id(rtwdev); if (mac_id == RTW89_MAX_MAC_ID_NUM) { ret = -ENOSPC; @@ -192,27 +185,40 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, goto release_macid; } - rtwvif_link->mac_idx = RTW89_MAC_0; - rtwvif_link->phy_idx = RTW89_PHY_0; - rtwvif_link->mac_id = mac_id; - rtwvif_link->port = port; + rtw89_init_vif(rtwdev, rtwvif, mac_id, port); rtw89_core_txq_init(rtwdev, vif->txq); - if (!rtw89_rtwvif_in_list(rtwdev, rtwvif_link)) - list_add_tail(&rtwvif_link->list, &rtwdev->rtwvifs_list); + if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) + list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); + + ether_addr_copy(rtwvif->mac_addr, vif->addr); + + rtwvif->offchan = false; + rtwvif->roc.state = RTW89_ROC_IDLE; + INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work); + + rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); + + rtwvif_link = rtw89_vif_set_link(rtwvif, 0); + if (!rtwvif_link) { + ret = -EINVAL; + goto release_port; + } ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link); if (ret) - goto release_port; + goto unset_link; rtw89_recalc_lps(rtwdev); mutex_unlock(&rtwdev->mutex); return 0; +unset_link: + rtw89_vif_unset_link(rtwvif, 0); release_port: - list_del_init(&rtwvif_link->list); + list_del_init(&rtwvif->list); rtw89_core_release_bit_map(rtwdev->hw_port, port); release_macid: rtw89_release_mac_id(rtwdev, mac_id); @@ -226,20 +232,35 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + u8 macid = rtw89_vif_get_main_macid(rtwvif); + u8 port = rtw89_vif_get_main_port(rtwvif); + struct rtw89_vif_link *rtwvif_link; rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", vif->addr, vif->type, vif->p2p); - cancel_delayed_work_sync(&rtwvif_link->roc.roc_work); + cancel_delayed_work_sync(&rtwvif->roc.roc_work); mutex_lock(&rtwdev->mutex); + rtwvif_link = rtwvif->links[0]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, 0); + goto bottom; + } + __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link); - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); - rtw89_release_mac_id(rtwdev, rtwvif_link->mac_id); - list_del_init(&rtwvif_link->list); + rtw89_vif_unset_link(rtwvif, 0); + +bottom: + list_del_init(&rtwvif->list); + rtw89_core_release_bit_map(rtwdev->hw_port, port); + rtw89_release_mac_id(rtwdev, macid); + rtw89_recalc_lps(rtwdev); rtw89_enter_ips_by_hwflags(rtwdev); @@ -460,8 +481,10 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; bool acquire_macid = false; u8 macid; int ret; @@ -469,7 +492,7 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { /* for station mode, assign the mac_id from itself */ - macid = rtwvif_link->mac_id; + macid = rtw89_vif_get_main_macid(rtwvif); } else { macid = rtw89_acquire_mac_id(rtwdev); if (macid == RTW89_MAX_MAC_ID_NUM) @@ -478,24 +501,32 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, acquire_macid = true; } - rtwsta_link->rtwdev = rtwdev; - rtwsta_link->rtwvif_link = rtwvif_link; - rtwsta_link->mac_id = macid; + rtw89_init_sta(rtwdev, rtwvif, rtwsta, macid); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) rtw89_core_txq_init(rtwdev, sta->txq[i]); - skb_queue_head_init(&rtwsta_link->roc_queue); + skb_queue_head_init(&rtwsta->roc_queue); + + rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id); + if (!rtwsta_link) { + ret = -EINVAL; + goto err; + } + + rtwvif_link = rtwsta_link->rtwvif_link; ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link); if (ret) - goto err; + goto unset_link; if (vif->type == NL80211_IFTYPE_AP || sta->tdls) rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); return 0; +unset_link: + rtw89_sta_unset_link(rtwsta, sta->deflink.link_id); err: if (acquire_macid) rtw89_release_mac_id(rtwdev, macid); @@ -508,20 +539,27 @@ static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, bool station_mode) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; int ret; - if (station_mode) - rtw89_vif_type_mapping(rtwvif_link, true); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; - ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link); - if (ret) - return ret; + if (station_mode) + rtw89_vif_type_mapping(rtwvif_link, true); + + ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } rtwdev->total_sta_assoc++; if (sta->tdls) - rtwvif_link->tdls_peer++; + rtwvif->tdls_peer++; return 0; } @@ -530,19 +568,25 @@ static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; int ret; - ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link); - if (ret) - return ret; + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } - rtwsta_link->disassoc = true; + rtwsta->disassoc = true; rtwdev->total_sta_assoc--; if (sta->tdls) - rtwvif_link->tdls_peer--; + rtwvif->tdls_peer--; return 0; } @@ -551,17 +595,22 @@ static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; int ret; rtw89_core_free_sta_pending_ba(rtwdev, sta); rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); - ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link); - if (ret) - return ret; + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + } return 0; } @@ -570,14 +619,21 @@ static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - u8 macid = rtwsta_link->mac_id; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + u8 macid = rtw89_sta_get_main_macid(rtwsta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; int ret; - ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link); - if (ret) - return ret; + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link); + if (ret) + return ret; + + rtw89_sta_unset_link(rtwsta, link_id); + } if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { rtw89_release_mac_id(rtwdev, macid); @@ -613,11 +669,22 @@ static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev, rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link); } +static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); +} + static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 changed) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); @@ -625,7 +692,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { if (vif->cfg.assoc) { rtw89_station_mode_sta_assoc(rtwdev, vif); - __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); + __rtw89_ops_bss_assoc(rtwdev, vif); rtw89_queue_chanctx_work(rtwdev); } else { @@ -641,7 +708,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, rtw89_recalc_lps(rtwdev); if (changed & BSS_CHANGED_ARP_FILTER) - rtwvif_link->ip_addr = vif->cfg.arp_addr_list[0]; + rtwvif->ip_addr = vif->cfg.arp_addr_list[0]; mutex_unlock(&rtwdev->mutex); } @@ -652,11 +719,20 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, u64 changed) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); + rtwvif_link = rtwvif->links[conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, conf->link_id); + goto out; + } + if (changed & BSS_CHANGED_BSSID) { ether_addr_copy(rtwvif_link->bssid, conf->bssid); rtw89_cam_bssid_changed(rtwdev, rtwvif_link); @@ -685,6 +761,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_TPE) rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true); +out: mutex_unlock(&rtwdev->mutex); } @@ -693,11 +770,20 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_bss_conf *link_conf) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; const struct rtw89_chan *chan; mutex_lock(&rtwdev->mutex); + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + goto out; + } + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); if (chan->band_type == RTW89_BAND_6G) { mutex_unlock(&rtwdev->mutex); @@ -717,6 +803,8 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, rtw89_chip_rfk_channel(rtwdev, rtwvif_link); rtw89_queue_chanctx_work(rtwdev); + +out: mutex_unlock(&rtwdev->mutex); return 0; @@ -727,12 +815,24 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; mutex_lock(&rtwdev->mutex); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + goto out; + } + rtw89_mac_stop_ap(rtwdev, rtwvif_link); rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); + +out: mutex_unlock(&rtwdev->mutex); } @@ -740,10 +840,13 @@ static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; - ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work); + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work); return 0; } @@ -754,15 +857,29 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, const struct ieee80211_tx_queue_params *params) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + int ret = 0; mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); + + rtwvif_link = rtwvif->links[link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_id); + ret = -ENOLINK; + goto out; + } + rtwvif_link->tx_params[ac] = *params; __rtw89_conf_tx(rtwdev, rtwvif_link, ac); + +out: mutex_unlock(&rtwdev->mutex); - return 0; + return ret; } static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, @@ -860,7 +977,8 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, { struct rtw89_dev *rtwdev = hw->priv; struct ieee80211_sta *sta = params->sta; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); u16 tid = params->tid; struct ieee80211_txq *txq = sta->txq[tid]; struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; @@ -873,29 +991,29 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mutex_lock(&rtwdev->mutex); clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); - clear_bit(tid, rtwsta_link->ampdu_map); - rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta); + clear_bit(tid, rtwsta->ampdu_map); + rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); mutex_unlock(&rtwdev->mutex); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: mutex_lock(&rtwdev->mutex); set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); - rtwsta_link->ampdu_params[tid].agg_num = params->buf_size; - rtwsta_link->ampdu_params[tid].amsdu = params->amsdu; - set_bit(tid, rtwsta_link->ampdu_map); + rtwsta->ampdu_params[tid].agg_num = params->buf_size; + rtwsta->ampdu_params[tid].amsdu = params->amsdu; + set_bit(tid, rtwsta->ampdu_map); rtw89_leave_ps_mode(rtwdev); - rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta); + rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta); mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_START: mutex_lock(&rtwdev->mutex); - rtw89_chip_h2c_ba_cam(rtwdev, rtwsta_link, true, params); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params); mutex_unlock(&rtwdev->mutex); break; case IEEE80211_AMPDU_RX_STOP: mutex_lock(&rtwdev->mutex); - rtw89_chip_h2c_ba_cam(rtwdev, rtwsta_link, false, params); + rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params); mutex_unlock(&rtwdev->mutex); break; default: @@ -924,7 +1042,12 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct station_info *sinfo) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + + rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0); + if (unlikely(!rtwsta_link)) + return; sinfo->txrate = rtwsta_link->ra_report.txrate; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); @@ -933,14 +1056,14 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, static void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) { - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; if (vif) { - rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; - rtw89_mac_pkt_drop_vif(rtwdev, rtwvif_link); + rtwvif = vif_to_rtwvif(vif); + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); } else { - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_pkt_drop_vif(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_mac_pkt_drop_vif(rtwdev, rtwvif); } } @@ -970,14 +1093,20 @@ struct rtw89_iter_bitrate_mask_data { static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_iter_bitrate_mask_data *br_data = data; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta_link->rtwvif_link); + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; if (vif != br_data->vif || vif->p2p) return; - rtwsta_link->use_cfg_mask = true; - rtwsta_link->mask = *br_data->mask; + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwsta_link->use_cfg_mask = true; + rtwsta_link->mask = *br_data->mask; + } + rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED); } @@ -1047,10 +1176,20 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, const u8 *mac_addr) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; mutex_lock(&rtwdev->mutex); + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "sw scan start: find no link on HW-0\n"); + goto out; + } + rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false); + +out: mutex_unlock(&rtwdev->mutex); } @@ -1058,9 +1197,20 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; mutex_lock(&rtwdev->mutex); - rtw89_core_scan_complete(rtwdev, vif, false); + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "sw scan complete: find no link on HW-0\n"); + goto out; + } + + rtw89_core_scan_complete(rtwdev, rtwvif_link, false); + +out: mutex_unlock(&rtwdev->mutex); } @@ -1077,22 +1227,35 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - int ret = 0; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + int ret; if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return 1; - if (rtwdev->scanning || rtwvif_link->offchan) - return -EBUSY; - mutex_lock(&rtwdev->mutex); - rtw89_hw_scan_start(rtwdev, vif, req); - ret = rtw89_hw_scan_offload(rtwdev, vif, true); + + if (rtwdev->scanning || rtwvif->offchan) { + ret = -EBUSY; + goto out; + } + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "hw scan: find no link on HW-0\n"); + ret = -ENOLINK; + goto out; + } + + rtw89_hw_scan_start(rtwdev, rtwvif_link, req); + ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true); if (ret) { - rtw89_hw_scan_abort(rtwdev, vif); + rtw89_hw_scan_abort(rtwdev, rtwvif_link); rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret); } + +out: mutex_unlock(&rtwdev->mutex); return ret; @@ -1102,6 +1265,8 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) return; @@ -1110,7 +1275,16 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, return; mutex_lock(&rtwdev->mutex); - rtw89_hw_scan_abort(rtwdev, vif); + + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, "cancel hw scan: find no link on HW-0\n"); + goto out; + } + + rtw89_hw_scan_abort(rtwdev, rtwvif_link); + +out: mutex_unlock(&rtwdev->mutex); } @@ -1163,11 +1337,24 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; int ret; mutex_lock(&rtwdev->mutex); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + ret = -ENOLINK; + goto out; + } + ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx); + +out: mutex_unlock(&rtwdev->mutex); return ret; @@ -1179,9 +1366,19 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; mutex_lock(&rtwdev->mutex); + + rtwvif_link = rtwvif->links[link_conf->link_id]; + if (unlikely(!rtwvif_link)) { + rtw89_err(rtwdev, + "%s: rtwvif link (link_id %u) is not active\n", + __func__, link_conf->link_id); + return; + } + rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx); mutex_unlock(&rtwdev->mutex); } @@ -1193,10 +1390,10 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, enum ieee80211_roc_type type) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); - struct rtw89_roc *roc = &rtwvif_link->roc; + struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); + struct rtw89_roc *roc = &rtwvif->roc; - if (!vif) + if (!rtwvif) return -EINVAL; mutex_lock(&rtwdev->mutex); @@ -1218,7 +1415,7 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, roc->chan = *chan; roc->type = type; - rtw89_roc_start(rtwdev, rtwvif_link); + rtw89_roc_start(rtwdev, rtwvif); mutex_unlock(&rtwdev->mutex); @@ -1229,15 +1426,15 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif); + struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); - if (!rtwvif_link) + if (!rtwvif) return -EINVAL; - cancel_delayed_work_sync(&rtwvif_link->roc.roc_work); + cancel_delayed_work_sync(&rtwvif->roc.roc_work); mutex_lock(&rtwdev->mutex); - rtw89_roc_end(rtwdev, rtwvif_link); + rtw89_roc_end(rtwdev, rtwvif); mutex_unlock(&rtwdev->mutex); return 0; @@ -1246,8 +1443,8 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta) { struct cfg80211_tid_config *tid_config = data; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta_link->rtwvif_link->rtwdev; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; rtw89_core_set_tid_config(rtwdev, sta, tid_config); } diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 8f1f2c7f2c54..1527b08e0c92 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -466,12 +466,12 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ra->csi_mode = csi_mode; } -void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, - u32 changed) +static void __rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + u32 changed) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_ra_info *ra = &rtwsta_link->ra; struct ieee80211_link_sta *link_sta; @@ -499,6 +499,20 @@ void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta rtw89_fw_h2c_ra(rtwdev, ra, false); } +void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, + u32 changed) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + __rtw89_phy_ra_update_sta(rtwdev, rtwvif_link, rtwsta_link, changed); + } +} + static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, u16 rate_base, u64 ra_mask, u8 ra_mode, u32 rate_ctrl, u32 ctrl_skip, bool force) @@ -533,12 +547,12 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, [RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \ } -void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, - const struct cfg80211_bitrate_mask *mask) +static +void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const struct cfg80211_bitrate_mask *mask) { struct ieee80211_supported_band *sband; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; struct rtw89_phy_rate_pattern next_pattern = {0}; const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); @@ -623,6 +637,18 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n"); } +void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + __rtw89_phy_rate_pattern_vif(rtwdev, rtwvif_link, mask); +} + static void rtw89_phy_ra_update_sta_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; @@ -640,7 +666,7 @@ void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) { struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_ra_info *ra = &rtwsta_link->ra; u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR; struct ieee80211_link_sta *link_sta; @@ -2688,13 +2714,17 @@ static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link, static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) { struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; struct ieee80211_link_sta *link_sta; + unsigned int link_id; rcu_read_lock(); - link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); - __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false); + __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data); + } rcu_read_unlock(); } @@ -4561,7 +4591,7 @@ void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, struct rtw89_phy_ul_tb_check_data *ul_tb_data) { struct rtw89_traffic_stats *stats = &rtwdev->stats; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) return; @@ -4627,6 +4657,8 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_phy_ul_tb_check_data ul_tb_data = {}; struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff) return; @@ -4634,8 +4666,9 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) if (rtwdev->total_sta_assoc != 1) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data); if (!ul_tb_data.valid) return; @@ -4799,12 +4832,10 @@ struct rtw89_phy_iter_rssi_data { bool rssi_changed; }; -static void rtw89_phy_stat_rssi_update_iter(void *data, - struct ieee80211_sta *sta) +static +void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link, + struct rtw89_phy_iter_rssi_data *rssi_data) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_phy_iter_rssi_data *rssi_data = - (struct rtw89_phy_iter_rssi_data *)data; struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info; unsigned long rssi_curr; @@ -4824,6 +4855,19 @@ static void rtw89_phy_stat_rssi_update_iter(void *data, } } +static void rtw89_phy_stat_rssi_update_iter(void *data, + struct ieee80211_sta *sta) +{ + struct rtw89_phy_iter_rssi_data *rssi_data = + (struct rtw89_phy_iter_rssi_data *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) + __rtw89_phy_stat_rssi_update_iter(rtwsta_link, rssi_data); +} + static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev) { struct rtw89_phy_iter_rssi_data rssi_data = {0}; @@ -5927,24 +5971,13 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev) rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); } -static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta) +static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) { - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_dev *rtwdev = rtwsta_link->rtwdev; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; struct rtw89_hal *hal = &rtwdev->hal; - bool *done = data; u8 rssi_a, rssi_b; u32 candidate; - if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION || sta->tdls) - return; - - if (*done) - return; - - *done = true; - rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]); rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]); @@ -5970,6 +6003,37 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta } } +static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_dev *rtwdev = rtwsta->rtwdev; + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; + bool *done = data; + + if (WARN(ieee80211_vif_is_mld(vif), "MLD mix path_div\n")) + return; + + if (sta->tdls) + return; + + if (*done) + return; + + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; + if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION) + continue; + + *done = true; + __rtw89_phy_tx_path_div_sta_iter(rtwdev, rtwsta_link); + return; + } +} + void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev) { struct rtw89_hal *hal = &rtwdev->hal; @@ -6179,7 +6243,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld; enum rtw89_phy_idx phy_idx = RTW89_PHY_0; diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index ded0b73bd678..c1c12abc2ea9 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -147,6 +147,8 @@ static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, void rtw89_leave_lps(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; lockdep_assert_held(&rtwdev->mutex); @@ -155,21 +157,25 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev) __rtw89_leave_ps_mode(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_leave_lps_vif(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_leave_lps_vif(rtwdev, rtwvif_link); } void rtw89_enter_ips(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) return; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_vif_deinit(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_vif_deinit(rtwdev, rtwvif_link); rtw89_core_stop(rtwdev); } @@ -177,6 +183,8 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev) void rtw89_leave_ips(struct rtw89_dev *rtwdev) { struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; int ret; if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) @@ -188,8 +196,9 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev) rtw89_set_channel(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_mac_vif_init(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_mac_vif_init(rtwdev, rtwvif_link); clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); } @@ -269,16 +278,22 @@ void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, void rtw89_recalc_lps(struct rtw89_dev *rtwdev) { struct ieee80211_vif *vif, *found_vif = NULL; - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; enum rtw89_entity_mode mode; int count = 0; + /* FIXME: Fix rtw89_enter_lps() and __rtw89_enter_ps_mode() + * to take MLO cases into account before doing the following. + */ + if (rtwdev->support_mlo) + goto disable_lps; + mode = rtw89_get_entity_mode(rtwdev); if (mode == RTW89_ENTITY_MODE_MCC) goto disable_lps; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - vif = rtwvif_to_vif(rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + vif = rtwvif_to_vif(rtwvif); if (vif->type != NL80211_IFTYPE_STATION) { count = 0; diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index aa5ae0244372..bb064a086970 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -794,21 +794,25 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev) struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; struct rtw89_reg_6ghz_tpe new = {}; struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; bool changed = false; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { + rtw89_for_each_rtwvif(rtwdev, rtwvif) { const struct rtw89_reg_6ghz_tpe *tmp; const struct rtw89_chan *chan; - chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - if (chan->band_type != RTW89_BAND_6G) - continue; + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->band_type != RTW89_BAND_6G) + continue; - tmp = &rtwvif_link->reg_6ghz_tpe; - if (!tmp->valid) - continue; + tmp = &rtwvif_link->reg_6ghz_tpe; + if (!tmp->valid) + continue; - tpe_intersect_constraint(&new, tmp->constraint); + tpe_intersect_constraint(&new, tmp->constraint); + } } if (memcmp(®ulatory->reg_6ghz_tpe, &new, @@ -873,19 +877,23 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) enum rtw89_reg_6ghz_power sel; const struct rtw89_chan *chan; struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; + unsigned int link_id; int count = 0; u8 index; - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) { - chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); - if (chan->band_type != RTW89_BAND_6G) - continue; + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + if (chan->band_type != RTW89_BAND_6G) + continue; - if (count != 0 && rtwvif_link->reg_6ghz_power == sel) - continue; + if (count != 0 && rtwvif_link->reg_6ghz_power == sel) + continue; - sel = rtwvif_link->reg_6ghz_power; - count++; + sel = rtwvif_link->reg_6ghz_power; + count++; + } } if (count != 1) diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 50b66eaf9bd0..7b203bb7f151 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -298,54 +298,71 @@ static void drv_resume_rx(struct rtw89_ser *ser) clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags); } -static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); - rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; - rtwvif_link->trigger = false; - rtwvif_link->tdls_peer = 0; + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + + rtwvif->tdls_peer = 0; + + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port); + rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK; + rtwvif_link->trigger = false; + } } static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) { - struct rtw89_vif_link *target_rtwvif = (struct rtw89_vif_link *)data; - struct rtw89_sta_link *rtwsta_link = (struct rtw89_sta_link *)sta->drv_priv; - struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link; - struct rtw89_dev *rtwdev = rtwvif_link->rtwdev; + struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data; + struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + struct rtw89_dev *rtwdev = rtwvif->rtwdev; + struct rtw89_vif_link *rtwvif_link; + struct rtw89_sta_link *rtwsta_link; + unsigned int link_id; - if (rtwvif_link != target_rtwvif) + if (rtwvif != target_rtwvif) return; - if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) - rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); - if (sta->tdls) - rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); + rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) { + rtwvif_link = rtwsta_link->rtwvif_link; - INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam); + if (sta->tdls) + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam); + + INIT_LIST_HEAD(&rtwsta_link->ba_cam_list); + } } -static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) +static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { + struct rtw89_vif_link *rtwvif_link; + unsigned int link_id; + ieee80211_iterate_stations_atomic(rtwdev->hw, ser_sta_deinit_cam_iter, - rtwvif_link); + rtwvif); - rtw89_cam_deinit(rtwdev, rtwvif_link); + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) + rtw89_cam_deinit(rtwdev, rtwvif_link); bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM); } static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) { - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; rtw89_cam_reset_keys(rtwdev); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - ser_deinit_cam(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_deinit_cam(rtwdev, rtwvif); rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - ser_reset_vif(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_reset_vif(rtwdev, rtwvif); rtwdev->total_sta_assoc = 0; } diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h index a5e87a8d8642..e669544cafd3 100644 --- a/drivers/net/wireless/realtek/rtw89/util.h +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -21,14 +21,14 @@ * twice cause the list to be added twice. */ static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev, - struct rtw89_vif_link *new) + struct rtw89_vif *new) { - struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; lockdep_assert_held(&rtwdev->mutex); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - if (rtwvif_link == new) + rtw89_for_each_rtwvif(rtwdev, rtwvif) + if (rtwvif == new) return true; return false; diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 97b527d04ad7..3e81fd974ec1 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -421,7 +421,8 @@ static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); bool err = false; rcu_read_lock(); @@ -596,7 +597,8 @@ static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready) static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, u32 cipher, u8 keyidx, u8 *gtk) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_cipher_info *cipher_info; struct ieee80211_key_conf *rekey_conf; struct ieee80211_key_conf *key; @@ -632,8 +634,8 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; struct rtw89_set_key_info_iter_data data = {.error = false, @@ -689,16 +691,14 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; __rtw89_enter_ps_mode(rtwdev, rtwvif_link); } static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; if (rtw89_wow_mgd_linked(rtwdev)) rtw89_enter_lps(rtwdev, rtwvif_link, false); @@ -708,8 +708,7 @@ static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; if (rtw89_wow_mgd_linked(rtwdev)) { rtw89_leave_lps(rtwdev); @@ -742,6 +741,8 @@ static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable) static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) { + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; struct cfg80211_wowlan_nd_info nd_info; @@ -788,36 +789,34 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) break; default: rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); - ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL, - GFP_KERNEL); + ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL); return; } - ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup, - GFP_KERNEL); + ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL); } static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link); + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); /* Current WoWLAN function support setting of only vif in * infra mode or no link mode. When one suitable vif is found, * stop the iteration. */ - if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION) + if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION) return; switch (rtwvif_link->net_type) { case RTW89_NET_TYPE_INFRA: if (rtw_wow_has_mgd_features(rtwdev)) - rtw_wow->wow_vif = vif; + rtw_wow->rtwvif_link = rtwvif_link; break; case RTW89_NET_TYPE_NO_LINK: if (rtw_wow->pno_inited) - rtw_wow->wow_vif = vif; + rtw_wow->rtwvif_link = rtwvif_link; break; default: break; @@ -1049,7 +1048,7 @@ static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - rtw_wow->wow_vif = NULL; + rtw_wow->rtwvif_link = NULL; rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); rtw_wow->pattern_cnt = 0; rtw_wow->pno_inited = false; @@ -1076,6 +1075,7 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_vif_link *rtwvif_link; + struct rtw89_vif *rtwvif; if (wowlan->disconnect) set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); @@ -1087,21 +1087,25 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, if (wowlan->nd_config) rtw89_wow_init_pno(rtwdev, wowlan->nd_config); - rtw89_for_each_rtwvif(rtwdev, rtwvif_link) - rtw89_wow_vif_iter(rtwdev, rtwvif_link); + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + /* use the link on HW-0 to do wow flow */ + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0); + if (!rtwvif_link) + continue; - if (!rtw_wow->wow_vif) + rtw89_wow_vif_iter(rtwdev, rtwvif_link); + } + + rtwvif_link = rtw_wow->rtwvif_link; + if (!rtwvif_link) return -EPERM; - rtwvif_link = (struct rtw89_vif_link *)rtw_wow->wow_vif->drv_priv; return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan); } static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow) { - struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; int ret; ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true); @@ -1128,15 +1132,20 @@ static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow) static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); struct ieee80211_sta *wow_sta; struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_sta *rtwsta; int ret; - wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); - if (wow_sta) - rtwsta_link = (struct rtw89_sta_link *)wow_sta->drv_priv; + wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); + if (wow_sta) { + rtwsta = sta_to_rtwsta(wow_sta); + rtwsta_link = rtwsta->links[rtwvif_link->link_id]; + if (!rtwsta_link) + return -ENOLINK; + } if (wow) { if (rtw_wow->pattern_cnt) @@ -1199,25 +1208,30 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; + struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; const struct rtw89_chip_info *chip = rtwdev->chip; bool include_bb = !!chip->bbmcu_nr; bool disable_intr_for_dlfw = false; struct ieee80211_sta *wow_sta; struct rtw89_sta_link *rtwsta_link = NULL; + struct rtw89_sta *rtwsta; bool is_conn = true; int ret; if (chip_id == RTL8852C || chip_id == RTL8922A) disable_intr_for_dlfw = true; - wow_sta = ieee80211_find_sta(wow_vif, rtwvif_link->bssid); - if (wow_sta) - rtwsta_link = (struct rtw89_sta_link *)wow_sta->drv_priv; - else + wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); + if (wow_sta) { + rtwsta = sta_to_rtwsta(wow_sta); + rtwsta_link = rtwsta->links[rtwvif_link->link_id]; + if (!rtwsta_link) + return -ENOLINK; + } else { is_conn = false; + } if (disable_intr_for_dlfw) rtw89_hci_disable_intr(rtwdev); @@ -1372,9 +1386,7 @@ static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev) static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) { - struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; int ret; ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); @@ -1446,8 +1458,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; int interval = rtw_wow->nd_config->scan_plans[0].interval; struct rtw89_scan_option opt = {}; int ret; @@ -1489,8 +1500,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; int ret; if (rtw89_wow_no_link(rtwdev)) { @@ -1558,8 +1568,7 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) { struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; int ret; if (rtw89_wow_no_link(rtwdev)) { diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h index a80b4b84587d..f91991e8f2e3 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.h +++ b/drivers/net/wireless/realtek/rtw89/wow.h @@ -97,16 +97,14 @@ static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev) #ifdef CONFIG_PM static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA; } static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev) { - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv; + struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK; } From 630d5d8f2bf6b340202b6bc2c05d794bbd8e4c1c Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 19 Sep 2024 16:12:14 +0800 Subject: [PATCH 026/126] wifi: rtw89: check return value of ieee80211_probereq_get() for RNR The return value of ieee80211_probereq_get() might be NULL, so check it before using to avoid NULL pointer access. Addresses-Coverity-ID: 1529805 ("Dereference null return value") Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240919081216.28505-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/fw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 3c4a3302d43d..1be1f61e0858 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -6089,6 +6089,9 @@ static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, NULL, 0, req->ie_len); + if (!skb) + return -ENOMEM; + skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); skb_put_data(skb, ies->common_ies, ies->common_ie_len); hdr = (struct ieee80211_hdr *)skb->data; From 6cdfb5659624081aedc8786ab89df927c264bb18 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 19 Sep 2024 16:12:15 +0800 Subject: [PATCH 027/126] wifi: rtw89: coex: initialize local .dbcc_2g_phy in _set_btg_ctrl() For the case of DBCC enabled and fwrole version 0, the local variable wl_rinfo.dbcc_2g_phy might not be set by following for-loop, leading uninitialized variable before using. Addresses-Coverity-ID: 1586724 ("Uninitialized scalar variable") Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240919081216.28505-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 3b3fd451e445..6da1193422fb 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4855,6 +4855,8 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev) if (rtwdev->dbcc_en) { if (ver->fwlrole == 0) { + wl_rinfo.dbcc_2g_phy = RTW89_PHY_MAX; + for (i = 0; i < RTW89_PHY_MAX; i++) { if (wl_dinfo->real_band[i] == RTW89_BAND_2G) wl_rinfo.dbcc_2g_phy = i; From 7bf2f8fe4237ffe260d9cb603500f07ceee36ed8 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 19 Sep 2024 16:12:16 +0800 Subject: [PATCH 028/126] wifi: rtw89: 8852c: rfk: remove unnecessary assignment of return value of _dpk_dgain_read() The return value of _dpk_dgain_read() is not used afterward, so remove it safely. Addresses-Coverity-ID: 1504753 ("Unused value") Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240919081216.28505-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 211c051c2967..3281ee9d7523 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -2350,7 +2350,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, if (dgain > 0x5fc || dgain < 0x556) { _dpk_one_shot(rtwdev, phy, path, D_SYNC); - dgain = _dpk_dgain_read(rtwdev); + _dpk_dgain_read(rtwdev); } if (agc_cnt == 0) { From bbb6f9be7f99464d5ab7e2f321fa728d33eeec9a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Sep 2024 22:27:30 +0300 Subject: [PATCH 029/126] wifi: rtw88: Parse the RX descriptor with a single function rtw8703b_query_rx_desc(), rtw8723d_query_rx_desc(), rtw8821c_query_rx_desc(), rtw8822b_query_rx_desc(), and rtw8822c_query_rx_desc() are almost identical, so replace them all with a single function, rtw_rx_query_rx_desc(). Also, access the RX descriptor using a struct with __le32 members and le32_get_bits(). Tested with RTL8811CU, RTL8811AU, and RTL8812AU. Signed-off-by: Bitterblue Smith Tested-by: Ping-Ke Shih # RTL8723DE and RTL8822CE Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com --- drivers/net/wireless/realtek/rtw88/main.h | 5 +- drivers/net/wireless/realtek/rtw88/pci.c | 2 +- drivers/net/wireless/realtek/rtw88/rtw8703b.c | 56 +-------------- drivers/net/wireless/realtek/rtw88/rtw8723d.c | 43 +----------- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 43 +----------- drivers/net/wireless/realtek/rtw88/rtw8822b.c | 43 +----------- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 44 +----------- drivers/net/wireless/realtek/rtw88/rx.c | 70 +++++++++++++++++-- drivers/net/wireless/realtek/rtw88/rx.h | 64 ++++++++--------- drivers/net/wireless/realtek/rtw88/sdio.c | 3 +- drivers/net/wireless/realtek/rtw88/usb.c | 4 +- 11 files changed, 106 insertions(+), 271 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 83180c488c37..05cfb235f272 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -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, diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 0b9b8807af2c..f71e41d6f97c 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -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 + diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c index e3ac748ad646..77399b8dd8cd 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c @@ -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, \ @@ -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 @@ -1948,7 +1894,7 @@ static const struct rtw_chip_ops rtw8703b_ops = { .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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index 7f33e141e646..86a5e2497641 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -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) { @@ -1433,7 +1392,7 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) 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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index 9d21c4b1450e..66c79956e8e5 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -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) { @@ -1686,7 +1645,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8821c = { 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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 650585086e8f..24f76a36f23e 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -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) { @@ -2175,7 +2134,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8822b = { 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, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index a5531e663dde..da74e66bda84 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -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) @@ -4991,7 +4949,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8822c = { 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, diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c index 66f9419588cf..1de93fc9efe9 100644 --- a/drivers/net/wireless/realtek/rtw88/rx.c +++ b/drivers/net/wireless/realtek/rtw88/rx.c @@ -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); diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h index 9f0019112987..6b7dee245c0a 100644 --- a/drivers/net/wireless/realtek/rtw88/rx.h +++ b/drivers/net/wireless/realtek/rtw88/rx.h @@ -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); diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index b67e551fcee3..f0b06ed8f76d 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -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; diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index dbc7d8d73494..ba314d90ab3f 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -571,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; From 1a82680839ee86f50ace41b6375ecee0c9320b12 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 25 Sep 2024 09:38:58 +0800 Subject: [PATCH 030/126] wifi: rtw89: pci: consolidate PCI basic configurations for probe and resume The PCI settings aren't always persistent after chip suspends, so reconfigure the settings after chip resumes. Since most of these settings are the same, consolidate them into a function to avoid missing somewhere. Fix the missing case of 8922AE resume flow. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925013901.9835-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 23 +++++++++++++-------- drivers/net/wireless/realtek/rtw89/pci.h | 1 + drivers/net/wireless/realtek/rtw89/pci_be.c | 2 ++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 02afeb3acce4..5733192cf380 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -4188,6 +4188,17 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) RTW89_PCIE_BIT_CFG_RST_MSTATE); } +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume) +{ + if (resume) + rtw89_pci_cfg_dac(rtwdev); + + rtw89_pci_disable_eq(rtwdev); + rtw89_pci_filter_out(rtwdev); + rtw89_pci_link_cfg(rtwdev); + rtw89_pci_l1ss_cfg(rtwdev); +} + static int __maybe_unused rtw89_pci_resume(struct device *dev) { struct ieee80211_hw *hw = dev_get_drvdata(dev); @@ -4209,11 +4220,8 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev) B_AX_SEL_REQ_ENTR_L1); } rtw89_pci_l2_hci_ldo(rtwdev); - rtw89_pci_disable_eq(rtwdev); - rtw89_pci_cfg_dac(rtwdev); - rtw89_pci_filter_out(rtwdev); - rtw89_pci_link_cfg(rtwdev); - rtw89_pci_l1ss_cfg(rtwdev); + + rtw89_pci_basic_cfg(rtwdev, true); return 0; } @@ -4345,10 +4353,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_clear_resource; } - rtw89_pci_disable_eq(rtwdev); - rtw89_pci_filter_out(rtwdev); - rtw89_pci_link_cfg(rtwdev); - rtw89_pci_l1ss_cfg(rtwdev); + rtw89_pci_basic_cfg(rtwdev, false); ret = rtw89_core_napi_init(rtwdev); if (ret) { diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 48c3ab735db2..f101bd932f62 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -1600,6 +1600,7 @@ struct pci_device_id; int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtw89_pci_remove(struct pci_dev *pdev); +void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume); void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev); int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en); int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en); diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c index 7cc328222965..c1415a7b18ff 100644 --- a/drivers/net/wireless/realtek/rtw89/pci_be.c +++ b/drivers/net/wireless/realtek/rtw89/pci_be.c @@ -584,6 +584,8 @@ static int __maybe_unused rtw89_pci_resume_be(struct device *dev) rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR); + rtw89_pci_basic_cfg(rtwdev, true); + return 0; } From bbc0be2ee2d8f5172ad68600c09401daa7270f64 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 25 Sep 2024 09:38:59 +0800 Subject: [PATCH 031/126] wifi: rtw89: 8922ae: disable PCI PHY EQ to improve compatibility For adaption EQ circuit, this HW design and affected by EIEOS (Electrical Idle Exit Order Set) amplitude from platform and process from IC, so disable EQ to improve that. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925013901.9835-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 4 +- drivers/net/wireless/realtek/rtw89/pci.h | 23 +++++++ drivers/net/wireless/realtek/rtw89/pci_be.c | 75 +++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 5733192cf380..c1e0861b7b3f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2358,7 +2358,7 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) return 0; } -static void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev) +static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev) { u16 g1_oobs, g2_oobs; u32 backup_aspm; @@ -4254,6 +4254,8 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = { .aspm_set = rtw89_pci_aspm_set_ax, .clkreq_set = rtw89_pci_clkreq_set_ax, .l1ss_set = rtw89_pci_l1ss_set_ax, + + .disable_eq = rtw89_pci_disable_eq_ax, }; EXPORT_SYMBOL(rtw89_pci_gen_ax); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index f101bd932f62..796f6cd3c965 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -18,11 +18,16 @@ #define BAC_OOBS_SEL BIT(4) #define RAC_ANA0A 0x0A #define B_BAC_EQ_SEL BIT(5) +#define RAC_ANA0B 0x0B +#define MANUAL_LVL_MASK GENMASK(8, 5) #define RAC_ANA0C 0x0C #define B_PCIE_BIT_PSAVE BIT(15) #define RAC_ANA0D 0x0D +#define OFFSET_CAL_MODE BIT(13) #define BAC_RX_TEST_EN BIT(6) #define RAC_ANA10 0x10 +#define ADDR_SEL_MASK GENMASK(9, 4) +#define ADDR_SEL_VAL 0x3C #define ADDR_SEL_PINOUT_DIS_VAL 0x3C4 #define B_PCIE_BIT_PINOUT_DIS BIT(3) #define RAC_REG_REV2 0x1B @@ -38,6 +43,7 @@ #define RAC_ANA1E_G2_VAL 0x6EEA #define RAC_ANA1F 0x1F #define OOBS_LEVEL_MASK GENMASK(12, 8) +#define OFFSET_CAL_MASK GENMASK(7, 4) #define RAC_ANA24 0x24 #define B_AX_DEGLITCH GENMASK(11, 8) #define RAC_ANA26 0x26 @@ -134,6 +140,11 @@ #define REG_FILTER_OUT_MASK GENMASK(6, 2) #define RAC_MULT 2 +#define R_RAC_DIRECT_OFFSET_BE_LANE0_G1 0x3800 +#define R_RAC_DIRECT_OFFSET_BE_LANE1_G1 0x3880 +#define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900 +#define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980 + #define RTW89_PCI_WR_RETRY_CNT 20 /* Interrupts */ @@ -299,6 +310,7 @@ #define B_BE_L1SS_TIMEOUT_CTRL BIT(18) #define B_BE_ASPM_CTRL_L1 BIT(17) #define B_BE_ASPM_CTRL_L0 BIT(16) +#define B_BE_RTK_ASPM_CTRL_MASK GENMASK(17, 16) #define B_BE_XFER_PENDING_FW BIT(11) #define B_BE_XFER_PENDING BIT(10) #define B_BE_REQ_EXIT_L1 BIT(9) @@ -1276,6 +1288,8 @@ struct rtw89_pci_gen_def { void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable); void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable); void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable); + + void (*disable_eq)(struct rtw89_dev *rtwdev); }; struct rtw89_pci_info { @@ -1767,4 +1781,13 @@ static inline int rtw89_pci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev) return gen_def->poll_txdma_ch_idle(rtwdev); } + +static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + gen_def->disable_eq(rtwdev); +} + #endif diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c index c1415a7b18ff..34154506f5d4 100644 --- a/drivers/net/wireless/realtek/rtw89/pci_be.c +++ b/drivers/net/wireless/realtek/rtw89/pci_be.c @@ -550,6 +550,79 @@ static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev) return 0; } +static void rtw89_pci_disable_eq_be(struct rtw89_dev *rtwdev) +{ + u32 backup_aspm, phy_offset; + u16 oobs_val, offset_cal; + u16 g1_oobs, g2_oobs; + u8 gen; + + if (rtwdev->chip->chip_id != RTL8922A) + return; + + g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 + + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + if (g1_oobs && g2_oobs) + return; + + backup_aspm = rtw89_read32(rtwdev, R_BE_PCIE_MIX_CFG); + rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_RTK_ASPM_CTRL_MASK); + + /* offset K */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT, + MANUAL_LVL_MASK, offset_cal); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + OFFSET_CAL_MODE); + } + + /* OOBS */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + BAC_RX_TEST_EN); + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, + ADDR_SEL_MASK, ADDR_SEL_VAL); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, + B_PCIE_BIT_PINOUT_DIS); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + oobs_val = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 + + RAC_ANA1F * RAC_MULT, OOBS_LEVEL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 : + R_RAC_DIRECT_OFFSET_BE_LANE0_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA03 * RAC_MULT, + OOBS_SEN_MASK, oobs_val); + rtw89_write16_set(rtwdev, phy_offset + RAC_ANA09 * RAC_MULT, + BAC_OOBS_SEL); + } + + rtw89_write32(rtwdev, R_BE_PCIE_MIX_CFG, backup_aspm); +} + static int __maybe_unused rtw89_pci_suspend_be(struct device *dev) { struct ieee80211_hw *hw = dev_get_drvdata(dev); @@ -616,5 +689,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = { .aspm_set = rtw89_pci_aspm_set_be, .clkreq_set = rtw89_pci_clkreq_set_be, .l1ss_set = rtw89_pci_l1ss_set_be, + + .disable_eq = rtw89_pci_disable_eq_be, }; EXPORT_SYMBOL(rtw89_pci_gen_be); From c76afc421cf7212c1b0a89f6ba79cd671db84f2e Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 25 Sep 2024 09:39:00 +0800 Subject: [PATCH 032/126] wifi: rtw89: 8852ce: fix gray code conversion for filter out EQ To use manual mode to set value of filter out EQ, read the source value of filter out EQ coded in gray code, and write to the target register in binary number. The function to convert from gray code to binary number is wrong originally, causing unexpected EQ, so fix it. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925013901.9835-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index c1e0861b7b3f..45d536b818e9 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3724,19 +3724,16 @@ static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev, pci_free_irq_vectors(pdev); } -static u16 gray_code_to_bin(u16 gray_code, u32 bit_num) +static u16 gray_code_to_bin(u16 gray_code) { - u16 bin = 0, gray_bit; - u32 bit_idx; + u16 binary = gray_code; - for (bit_idx = 0; bit_idx < bit_num; bit_idx++) { - gray_bit = (gray_code >> bit_idx) & 0x1; - if (bit_num - bit_idx > 1) - gray_bit ^= (gray_code >> (bit_idx + 1)) & 0x1; - bin |= (gray_bit << bit_idx); + while (gray_code) { + gray_code >>= 1; + binary ^= gray_code; } - return bin; + return binary; } static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev) @@ -3772,7 +3769,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev) val16 = rtw89_read16_mask(rtwdev, phy_offset + RAC_ANA1F * RAC_MULT, FILTER_OUT_EQ_MASK); - val16 = gray_code_to_bin(val16, hweight16(val16)); + val16 = gray_code_to_bin(val16); filter_out_val = rtw89_read16(rtwdev, phy_offset + RAC_ANA24 * RAC_MULT); filter_out_val &= ~REG_FILTER_OUT_MASK; From 6f46547d3db93a77d5a7f031880eabfd0448e46a Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Wed, 25 Sep 2024 09:39:01 +0800 Subject: [PATCH 033/126] wifi: rtw89: 8852ce: set offset K of PCI PHY EQ to manual mode to improve compatibility Read calibration value of PCI RX offset, and set to manual mode as the value at PCI probe to prevent abnormal calibration results at runtime. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925013901.9835-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/pci.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 45d536b818e9..5ed7eaa18c85 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2363,8 +2363,10 @@ static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev) u16 g1_oobs, g2_oobs; u32 backup_aspm; u32 phy_offset; + u16 offset_cal; u16 oobs_val; int ret; + u8 gen; if (rtwdev->chip->chip_id != RTL8852C) return; @@ -2400,6 +2402,28 @@ static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev) rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL); + /* offset K */ + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 : + R_RAC_DIRECT_OFFSET_G2; + + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, + B_PCIE_BIT_RD_SEL); + } + + offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 + + RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK); + + for (gen = 1; gen <= 2; gen++) { + phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 : + R_RAC_DIRECT_OFFSET_G2; + + rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT, + MANUAL_LVL_MASK, offset_cal); + rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, + OFFSET_CAL_MODE); + } + out: rtw89_write32(rtwdev, R_AX_PCIE_MIX_CFG_V1, backup_aspm); } From f82a4471fc51608472237ceedcb5f80162fd764c Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Wed, 25 Sep 2024 10:01:18 +0800 Subject: [PATCH 034/126] wifi: rtw89: initialize dual HW bands for MLO and control them by link To support MLO, we initialize things on dual HW bands of Wi-Fi 7 chip. And, each link will indicate which HW band it's bound to. So, in link control flow, we control major things based on target link's HW band instead of hardcode like RTW89_PHY_X or RTW89_MAC_X. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925020119.13170-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 22 ++--- drivers/net/wireless/realtek/rtw89/core.h | 19 +++- drivers/net/wireless/realtek/rtw89/fw.c | 33 ++++--- drivers/net/wireless/realtek/rtw89/fw.h | 4 - drivers/net/wireless/realtek/rtw89/mac.c | 12 ++- drivers/net/wireless/realtek/rtw89/mac.h | 17 +++- drivers/net/wireless/realtek/rtw89/mac80211.c | 2 +- drivers/net/wireless/realtek/rtw89/mac_be.c | 2 +- drivers/net/wireless/realtek/rtw89/phy.c | 90 +++++++++++++------ drivers/net/wireless/realtek/rtw89/phy.h | 4 + drivers/net/wireless/realtek/rtw89/phy_be.c | 12 ++- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 17 +++- 12 files changed, 162 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 5b8e65f6de6a..6200755b5ce9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3150,6 +3150,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) struct rtw89_vif_link *rtwvif_link; struct cfg80211_chan_def roc_chan; struct rtw89_vif *tmp_vif; + u32 reg; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -3185,9 +3186,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT); rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, &roc_chan); rtw89_set_channel(rtwdev); - rtw89_write32_clr(rtwdev, - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), - B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); + rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); ieee80211_ready_on_channel(hw); cancel_delayed_work(&rtwvif->roc.roc_work); @@ -3202,6 +3203,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) struct rtw89_roc *roc = &rtwvif->roc; struct rtw89_vif_link *rtwvif_link; struct rtw89_vif *tmp_vif; + u32 reg; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -3217,10 +3219,8 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) return; } - rtw89_write32_mask(rtwdev, - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), - B_AX_RX_FLTR_CFG_MASK, - rtwdev->hal.rx_fltr); + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); roc->state = RTW89_ROC_IDLE; rtw89_config_roc_chandef(rtwdev, rtwvif_link->chanctx_idx, NULL); @@ -4399,8 +4399,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) rtw89_phy_dm_init(rtwdev); - rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); - rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); + rtw89_mac_cfg_ppdu_status_bands(rtwdev, true); + rtw89_mac_update_rts_threshold(rtwdev); rtw89_tas_reset(rtwdev); @@ -4751,7 +4751,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv rtw89_leave_ips_by_hwflags(rtwdev); ether_addr_copy(rtwvif_link->mac_addr, mac_addr); - rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type); + rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type); rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true); rtw89_hci_recalc_int_mit(rtwdev); rtw89_phy_config_edcca(rtwdev, true); @@ -4777,7 +4777,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); - rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); + rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx); rtw89_phy_config_edcca(rtwdev, false); rtwdev->scanning = false; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ac9f9d33436c..f1f10b7b0731 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -6484,8 +6484,12 @@ static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; - if (chip->ops->set_txpwr_ctrl) - chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0); + if (!chip->ops->set_txpwr_ctrl) + return; + + chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_1); } static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) @@ -6496,8 +6500,8 @@ static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) chip->ops->power_trim(rtwdev); } -static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx) +static inline void __rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) { const struct rtw89_chip_info *chip = rtwdev->chip; @@ -6505,6 +6509,13 @@ static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, chip->ops->init_txpwr_unit(rtwdev, phy_idx); } +static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev) +{ + __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_1); +} + static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 1be1f61e0858..752a3c2536d4 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -4761,6 +4761,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, return 0; } +static int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num, struct list_head *chan_list) { @@ -4832,8 +4833,10 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num, return 0; } +static int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, - struct list_head *chan_list) + struct list_head *chan_list, + struct rtw89_vif_link *rtwvif_link) { struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; struct rtw89_h2c_chinfo_elem_be *elem; @@ -4858,7 +4861,8 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, h2c->ch_num = ch_num; h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */ - h2c->arg = u8_encode_bits(RTW89_PHY_0, RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK); + h2c->arg = u8_encode_bits(rtwvif_link->mac_idx, + RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK); list_for_each_entry(ch_info, chan_list, list) { elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem)); @@ -4965,7 +4969,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | - le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) | + le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) | le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | @@ -6524,7 +6528,8 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, list_add_tail(&ch_info->list, &chan_list); } - ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list); + ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list, + rtwvif_link); out: list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { @@ -6584,7 +6589,8 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, } rtwdev->scan_info.last_chan_idx = idx; - ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list); + ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list, + rtwvif_link); out: list_for_each_entry_safe(ch_info, tmp, &chan_list, list) { @@ -6622,6 +6628,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; u32 rx_fltr = rtwdev->hal.rx_fltr; u8 mac_addr[ETH_ALEN]; + u32 reg; /* clone op and keep it during scan */ rtwdev->scan_info.op_chan = *chan; @@ -6644,10 +6651,9 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, rx_fltr &= ~B_AX_A_BCN_CHK_EN; rx_fltr &= ~B_AX_A_BC; rx_fltr &= ~B_AX_A_A1_MATCH; - rtw89_write32_mask(rtwdev, - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), - B_AX_RX_FLTR_CFG_MASK, - rx_fltr); + + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr); rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN); } @@ -6662,16 +6668,15 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, .aborted = aborted, }; struct rtw89_vif *rtwvif; + u32 reg; if (!rtwvif_link) return; rtwvif = rtwvif_link->rtwvif; - rtw89_write32_mask(rtwdev, - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), - B_AX_RX_FLTR_CFG_MASK, - rtwdev->hal.rx_fltr); + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); + rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); rtw89_core_scan_complete(rtwdev, rtwvif_link, true); ieee80211_scan_completed(rtwdev->hw, &info); @@ -6750,7 +6755,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; opt.scan_mode = RTW89_SCAN_MODE_SA; - opt.band = RTW89_PHY_0; + opt.band = rtwvif_link->mac_idx; opt.num_macc_role = 0; opt.mlo_mode = rtwdev->mlo_dbcc_mode; opt.num_opch = connected ? 1 : 0; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index a083bed3822b..d338c3aec725 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4527,10 +4527,6 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type); int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id); int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, struct sk_buff *skb_ofld); -int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num, - struct list_head *chan_list); -int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num, - struct list_head *chan_list); int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev, struct rtw89_scan_option *opt, struct rtw89_vif_link *vif, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 4e15d539e3d1..6a0262e512ea 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5543,7 +5543,8 @@ int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enab return 0; } -void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) +static +void __rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) { #define MAC_AX_TIME_TH_SH 5 #define MAC_AX_LEN_TH_SH 4 @@ -5573,6 +5574,13 @@ void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th); } +void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev) +{ + __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); + if (rtwdev->dbcc_en) + __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_1); +} + void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop) { bool empty; @@ -6446,7 +6454,7 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_pkt_drop_params params = {0}; int i; - params.mac_band = RTW89_MAC_0; + params.mac_band = rtwvif_link->mac_idx; params.macid = rtwsta_link->mac_id; params.port = rtwvif_link->port; params.mbssid = 0; diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 0c269961a573..e59c1fcfea46 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1222,7 +1222,22 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) return mac->cfg_ppdu_status(rtwdev, mac_idx, enable); } -void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx); +static inline +int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable) +{ + int ret; + + ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, enable); + if (ret) + return ret; + + if (!rtwdev->dbcc_en) + return 0; + + return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable); +} + +void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev); void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 44ba4dc181b5..1ee63a85308f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -1031,7 +1031,7 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) - rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); + rtw89_mac_update_rts_threshold(rtwdev); mutex_unlock(&rtwdev->mutex); return 0; diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index f22eaa83297f..30943462640f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -773,7 +773,7 @@ static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) return ret; } - ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode); + ret = rtw89_mac_preload_init(rtwdev, mac_idx, rtwdev->mac.qta_mode); if (ret) { rtw89_err(rtwdev, "[ERR]preload init %d\n", ret); return ret; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 1527b08e0c92..7f90316a0f2f 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -1114,14 +1114,21 @@ static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev) return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1; } -static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx) +static void __rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) { const struct rtw89_chip_info *chip = rtwdev->chip; chip->ops->bb_reset(rtwdev, phy_idx); } +static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev) +{ + __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_1); +} + static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, enum rtw89_rf_path rf_path, @@ -1667,13 +1674,15 @@ void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev) if (rtwdev->dbcc_en) rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, (void *)RTW89_PHY_1); - rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); + + rtw89_chip_init_txpwr_unit(rtwdev); bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table; if (bb_gain_table) rtw89_phy_init_reg(rtwdev, bb_gain_table, chip->phy_def->config_bb_gain, NULL); - rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); + + rtw89_phy_bb_reset(rtwdev); } static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev) @@ -1793,6 +1802,24 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, } EXPORT_SYMBOL(rtw89_phy_write32_idx); +void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + rtw89_phy_write32_set(rtwdev, addr, bits); +} +EXPORT_SYMBOL(rtw89_phy_write32_idx_set); + +void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx) +{ + if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) + addr += rtw89_phy0_phy1_offset(rtwdev, addr); + rtw89_phy_write32_clr(rtwdev, addr, bits); +} +EXPORT_SYMBOL(rtw89_phy_write32_idx_clr); + u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, enum rtw89_phy_idx phy_idx) { @@ -5406,7 +5433,8 @@ static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page) } static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev, - enum rtw89_phy_status_bitmap ie_page) + enum rtw89_phy_status_bitmap ie_page, + enum rtw89_phy_idx phy_idx) { u32 addr; @@ -5415,12 +5443,12 @@ static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev, addr = rtw89_phy_get_ie_bitmap_addr(ie_page); - return rtw89_phy_read32(rtwdev, addr); + return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx); } static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev, enum rtw89_phy_status_bitmap ie_page, - u32 val) + u32 val, enum rtw89_phy_idx phy_idx) { const struct rtw89_chip_info *chip = rtwdev->chip; u32 addr; @@ -5432,22 +5460,22 @@ static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev, val &= B_PHY_STS_BITMAP_MSK_52A; addr = rtw89_phy_get_ie_bitmap_addr(ie_page); - rtw89_phy_write32(rtwdev, addr, val); + rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx); } static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev, enum rtw89_phy_status_bitmap bitmap, enum rtw89_phy_status_ie_type ie, - bool enable) + bool enable, enum rtw89_phy_idx phy_idx) { - u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap); + u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap, phy_idx); if (enable) val |= BIT(ie); else val &= ~BIT(ie); - rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val); + rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val, phy_idx); } static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev, @@ -5458,44 +5486,52 @@ static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev, const struct rtw89_physts_regs *physts = phy->physts; if (enable) { - rtw89_phy_write32_clr(rtwdev, physts->setting_addr, - physts->dis_trigger_fail_mask); - rtw89_phy_write32_clr(rtwdev, physts->setting_addr, - physts->dis_trigger_brk_mask); + rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr, + physts->dis_trigger_fail_mask, phy_idx); + rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr, + physts->dis_trigger_brk_mask, phy_idx); } else { - rtw89_phy_write32_set(rtwdev, physts->setting_addr, - physts->dis_trigger_fail_mask); - rtw89_phy_write32_set(rtwdev, physts->setting_addr, - physts->dis_trigger_brk_mask); + rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr, + physts->dis_trigger_fail_mask, phy_idx); + rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr, + physts->dis_trigger_brk_mask, phy_idx); } } -static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev) +static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) { u8 i; - rtw89_physts_enable_fail_report(rtwdev, false, RTW89_PHY_0); + rtw89_physts_enable_fail_report(rtwdev, false, phy_idx); for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) { if (i >= RTW89_CCK_PKT) rtw89_physts_enable_ie_bitmap(rtwdev, i, RTW89_PHYSTS_IE09_FTR_0, - true); + true, phy_idx); if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) || (i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT)) continue; rtw89_physts_enable_ie_bitmap(rtwdev, i, RTW89_PHYSTS_IE24_OFDM_TD_PATH_A, - true); + true, phy_idx); } rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT, - RTW89_PHYSTS_IE13_DL_MU_DEF, true); + RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx); rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT, - RTW89_PHYSTS_IE13_DL_MU_DEF, true); + RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx); /* force IE01 for channel index, only channel field is valid */ rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT, - RTW89_PHYSTS_IE01_CMN_OFDM, true); + RTW89_PHYSTS_IE01_CMN_OFDM, true, phy_idx); +} + +static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev) +{ + __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0); + if (rtwdev->dbcc_en) + __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1); } static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) @@ -6246,7 +6282,7 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld; - enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx; struct ieee80211_bss_conf *bss_conf; u8 bss_color; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 727b69c45a52..c683f4d7d29b 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -815,6 +815,10 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, void rtw89_phy_dm_init(struct rtw89_dev *rtwdev); void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data, enum rtw89_phy_idx phy_idx); +void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx); +void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits, + enum rtw89_phy_idx phy_idx); u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, enum rtw89_phy_idx phy_idx); s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/phy_be.c b/drivers/net/wireless/realtek/rtw89/phy_be.c index 72eda9bbd3ae..37d8f254ae32 100644 --- a/drivers/net/wireless/realtek/rtw89/phy_be.c +++ b/drivers/net/wireless/realtek/rtw89/phy_be.c @@ -398,10 +398,9 @@ static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev) } } -static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev) +static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev, + enum rtw89_mac_idx mac_idx) { - enum rtw89_mac_idx mac_idx = RTW89_MAC_0; - rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev); rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev); rtw89_phy_bb_wrap_listen_path_en_init(rtwdev); @@ -411,6 +410,13 @@ static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev) rtw89_phy_bb_wrap_ul_pwr(rtwdev); } +static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev) +{ + __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_0); + if (rtwdev->dbcc_en) + __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_1); +} + static void rtw89_phy_ch_info_init_be(struct rtw89_dev *rtwdev) { rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG, B_CHINFO_SEG_LEN, 0x0); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 2aff7e29992f..58c9721ac3ab 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -1991,14 +1991,23 @@ static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev) memset(rfk_mcc, 0, sizeof(*rfk_mcc)); } +static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + const struct rtw89_chan *chan) +{ + rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5); + + rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58); + rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 32); +} + static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev) { const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); - rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5); - - rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, chan, 58); - rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, false, 32); + __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan); + if (rtwdev->dbcc_en) + __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan); } static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) From ad95bb3b92c65849a6101402197e2cbeb2910a4a Mon Sep 17 00:00:00 2001 From: Zong-Zhe Yang Date: Wed, 25 Sep 2024 10:01:19 +0800 Subject: [PATCH 035/126] wifi: rtw89: handle entity active flag per PHY Originally, we have an active flag to record whether we have set PHY once. After impending MLO support, there will be dual-PHY and they can be set individually on Wi-Fi 7 chips. So, we now have active flag per PHY and handle them individually. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240925020119.13170-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/chan.h | 11 +++++++---- drivers/net/wireless/realtek/rtw89/core.c | 15 ++++++++------- drivers/net/wireless/realtek/rtw89/core.h | 2 +- drivers/net/wireless/realtek/rtw89/mac.c | 3 ++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h index 4ed777ea5064..74de13a2e7da 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.h +++ b/drivers/net/wireless/realtek/rtw89/chan.h @@ -43,18 +43,21 @@ struct rtw89_entity_weight { unsigned int active_roles; }; -static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev) +static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx) { struct rtw89_hal *hal = &rtwdev->hal; - return READ_ONCE(hal->entity_active); + return READ_ONCE(hal->entity_active[phy_idx]); } -static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active) +static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, + bool active) { struct rtw89_hal *hal = &rtwdev->hal; - WRITE_ONCE(hal->entity_active, active); + WRITE_ONCE(hal->entity_active[phy_idx], active); } static inline diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 6200755b5ce9..e5dc6d36245d 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -352,10 +352,6 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev) enum rtw89_entity_mode mode; bool entity_active; - entity_active = rtw89_get_entity_state(rtwdev); - if (!entity_active) - return; - mode = rtw89_get_entity_mode(rtwdev); switch (mode) { case RTW89_ENTITY_MODE_SCC: @@ -375,6 +371,11 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev) chanctx_idx = roc_idx; phy_idx = RTW89_PHY_0; + + entity_active = rtw89_get_entity_state(rtwdev, phy_idx); + if (!entity_active) + return; + chan = rtw89_chan_get(rtwdev, chanctx_idx); chip->ops->set_txpwr(rtwdev, chan, phy_idx); } @@ -393,8 +394,6 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev) enum rtw89_entity_mode mode; bool entity_active; - entity_active = rtw89_get_entity_state(rtwdev); - mode = rtw89_entity_recalc(rtwdev); switch (mode) { case RTW89_ENTITY_MODE_SCC: @@ -416,6 +415,8 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev) mac_idx = RTW89_MAC_0; phy_idx = RTW89_PHY_0; + entity_active = rtw89_get_entity_state(rtwdev, phy_idx); + chan = rtw89_chan_get(rtwdev, chanctx_idx); chan_rcd = rtw89_chan_rcd_get(rtwdev, chanctx_idx); @@ -432,7 +433,7 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev) rtw89_chip_rfk_band_changed(rtwdev, phy_idx, chan); } - rtw89_set_entity_state(rtwdev, true); + rtw89_set_entity_state(rtwdev, phy_idx, true); return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index f1f10b7b0731..598eee12339e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4669,7 +4669,7 @@ struct rtw89_hal { struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX]; struct cfg80211_chan_def roc_chandef; - bool entity_active; + bool entity_active[RTW89_PHY_MAX]; bool entity_pause; enum rtw89_entity_mode entity_mode; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 6a0262e512ea..b3f417003087 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -1483,7 +1483,8 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags); clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR); - rtw89_set_entity_state(rtwdev, false); + rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false); + rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false); } return 0; From 284939d7e87f0a79424412004473abbc8e8ddddf Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 27 Sep 2024 09:35:12 +0800 Subject: [PATCH 036/126] wifi: rtw89: debug: add beacon RSSI for debugging In range test, the RSSI is helpful to check attenuation of cable and align difference between environments. Since data packets can be transmitted with different rate and power, the RSSI of all packets can be variant. Oppositely beacon is transmitted with the same rate and power, so beacon RSSI will be relatively invariant, and more helpful to diagnose problems. The output of beacon RSSI in unit of dBm looks like: Beacon: 19 (-33 dBm), TF: 0 Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240927013512.7106-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 3 +++ drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/debug.c | 7 +++++-- drivers/net/wireless/realtek/rtw89/phy.c | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index e5dc6d36245d..bba5bde95bb4 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2110,6 +2110,9 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu); } pkt_stat->beacon_nr++; + + if (phy_ppdu) + ewma_rssi_add(&rtwdev->phystat.bcn_rssi, phy_ppdu->rssi_avg); } if (!ether_addr_equal(bss_conf->addr, hdr->addr1)) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 598eee12339e..d9cf39cc4cec 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4747,6 +4747,7 @@ DECLARE_EWMA(thermal, 4, 4); struct rtw89_phy_stat { struct ewma_thermal avg_thermal[RF_PATH_MAX]; + struct ewma_rssi bcn_rssi; struct rtw89_pkt_stat cur_pkt_stat; struct rtw89_pkt_stat last_pkt_stat; }; diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 7391f131229a..74b0c722a5b8 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3673,13 +3673,16 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_rx_rate_cnt_info *info; enum rtw89_hw_rate first_rate; + u8 rssi; int i; + rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi); + seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n", stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv, stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv); - seq_printf(m, "Beacon: %u, TF: %u\n", pkt_stat->beacon_nr, - stats->rx_tf_periodic); + seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr, + RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic); seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len, stats->rx_avg_len); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 7f90316a0f2f..5a08e3d46bac 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -4921,6 +4921,8 @@ static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev) memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat)); + + ewma_rssi_init(&phystat->bcn_rssi); } void rtw89_phy_stat_track(struct rtw89_dev *rtwdev) From d7063ed6758c62e00a2f56467ded85a021fac67a Mon Sep 17 00:00:00 2001 From: Martin Kaistra Date: Mon, 30 Sep 2024 10:49:55 +0200 Subject: [PATCH 037/126] wifi: rtl8xxxu: Perform update_beacon_work when beaconing is enabled In STA+AP concurrent mode, performing a scan operation on one vif temporarily stops beacons on the other. When the scan is completed, beacons are enabled again with BSS_CHANGED_BEACON_ENABLED. We can observe that no beacons are being sent when just rtl8xxxu_start_tx_beacon() is being called. Thus, also perform update_beacon_work in order to restore beaconing. Fixes: cde8848cad0b ("wifi: rtl8xxxu: Add beacon functions") Signed-off-by: Martin Kaistra Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240930084955.455241-1-martin.kaistra@linutronix.de --- drivers/net/wireless/realtek/rtl8xxxu/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c index 7891c988dd5f..f95898f68d68 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -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) From 2b73e9ab8535caca192844a161d9f491ee9f8aab Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 10 Sep 2024 13:40:03 -0700 Subject: [PATCH 038/126] wifi: mac80211: constify ieee80211_ie_build_{he,eht}_oper() chandef The chandef parameter passed to ieee80211_ie_build_he_oper() and ieee80211_ie_build_eht_oper is read-only. Since it is never modified, add the const qualifier to this parameter. This makes these consistent with ieee80211_ie_build_ht_oper() and ieee80211_ie_build_vht_oper(). Signed-off-by: Jeff Johnson Link: https://patch.msgid.link/20240910-wireless-utils-constify-v1-1-e59947bcb3c3@quicinc.com Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/util.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4f0390918b60..3f4d2773b828 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2545,8 +2545,8 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, const struct cfg80211_chan_def *chandef); u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata); -u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef); -u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef, +u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef); +u8 *ieee80211_ie_build_eht_oper(u8 *pos, const struct cfg80211_chan_def *chandef, const struct ieee80211_sta_eht_cap *eht_cap); int ieee80211_parse_bitrates(enum nl80211_chan_width width, const struct ieee80211_supported_band *sband, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f94faa86ba8a..f0db60878321 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2752,7 +2752,7 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, return pos + sizeof(struct ieee80211_vht_operation); } -u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef) +u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef) { struct ieee80211_he_operation *he_oper; struct ieee80211_he_6ghz_oper *he_6ghz_op; @@ -2844,7 +2844,7 @@ u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef) return pos; } -u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef, +u8 *ieee80211_ie_build_eht_oper(u8 *pos, const struct cfg80211_chan_def *chandef, const struct ieee80211_sta_eht_cap *eht_cap) { From 4b482281eeb263d5bbbe75e1c5688d80daabb20e Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 13 Sep 2024 11:49:19 +0300 Subject: [PATCH 039/126] wifi: mac80211, cfg80211: miscellaneous spelling fixes Correct spelling here and there as suggested by codespell. Signed-off-by: Dmitry Antipov Link: https://patch.msgid.link/20240913084919.118862-1-dmantipov@yandex.ru Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 2 +- net/mac80211/chan.c | 4 ++-- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mesh.c | 2 +- net/mac80211/mesh_plink.c | 2 +- net/mac80211/mesh_sync.c | 2 +- net/mac80211/rc80211_minstrel_ht.c | 2 +- net/mac80211/sta_info.h | 2 +- net/mac80211/tkip.c | 2 +- net/mac80211/tx.c | 2 +- net/mac80211/util.c | 2 +- net/mac80211/vht.c | 4 ++-- net/wireless/chan.c | 2 +- net/wireless/nl80211.c | 4 ++-- net/wireless/radiotap.c | 2 +- net/wireless/reg.c | 2 +- net/wireless/util.c | 2 +- net/wireless/wext-compat.c | 2 +- net/wireless/wext-core.c | 2 +- 19 files changed, 22 insertions(+), 22 deletions(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 1c18b862ef8c..04cb45cfb310 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -797,7 +797,7 @@ void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, if (!test_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)) { ieee80211_send_addba_with_timeout(sta, tid_tx); - /* RESPONSE_RECEIVED state whould trigger the flow again */ + /* RESPONSE_RECEIVED state would trigger the flow again */ return; } diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index cca6d14084d2..a155e418d26b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -462,7 +462,7 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local, continue; /* vif changed to narrow BW and narrow BW for station wasn't - * requested or vise versa */ + * requested or vice versa */ if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed) continue; @@ -1118,7 +1118,7 @@ ieee80211_replace_chanctx(struct ieee80211_local *local, * * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and * link2 from ctx1 request new different chandefs starting 2 - * in-place reserations with ctx4 and ctx5 replacing ctx1 and + * in-place reservations with ctx4 and ctx5 replacing ctx1 and * ctx2 respectively. Next link5 and link6 from ctx3 reserve * ctx4. If link3 and link4 remain on ctx2 as they are then this * fails unless `replace_ctx` from ctx5 is replaced with ctx3. diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3f4d2773b828..afb867dc6b24 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2452,7 +2452,7 @@ static inline bool ieee80211_can_run_worker(struct ieee80211_local *local) /* * If quiescing is set, we are racing with __ieee80211_suspend. * __ieee80211_suspend flushes the workers after setting quiescing, - * and we check quiescing / suspended before enqueing new workers. + * and we check quiescing / suspended before enqueuing new workers. * We should abort the worker to avoid the races below. */ if (local->quiescing) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index f94e4be0be12..0460102c8796 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1482,7 +1482,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (!elems) return; - /* ignore non-mesh or secure / unsecure mismatch */ + /* ignore non-mesh or secure / insecure mismatch */ if ((!elems->mesh_id || !elems->mesh_config) || (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 8f2b492a9fe9..42286aa3623c 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -667,7 +667,7 @@ void mesh_plink_timer(struct timer_list *t) /* * This STA is valid because sta_info_destroy() will * del_timer_sync() this timer after having made sure - * it cannot be readded (by deleting the plink.) + * it cannot be re-added (by deleting the plink.) */ sta = mesh->plink_sta; diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 8cf3f395f52f..3a66b4cefca7 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -175,7 +175,7 @@ static void mesh_sync_offset_adjust_tsf(struct ieee80211_sub_if_data *sdata, spin_lock_bh(&ifmsh->sync_offset_lock); if (ifmsh->sync_offset_clockdrift_max > TOFFSET_MINIMUM_ADJUSTMENT) { - /* Since ajusting the tsf here would + /* Since adjusting the tsf here would * require a possibly blocking call * to the driver tsf setter, we punt * the tsf adjustment to the mesh tasklet diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 6bf3b4444a43..706cbc99f718 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1053,7 +1053,7 @@ minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi) * - max_prob_rate must use only one stream, as a tradeoff between delivery * probability and throughput during strong fluctuations * - as long as the max prob rate has a probability of more than 75%, pick - * higher throughput rates, even if the probablity is a bit lower + * higher throughput rates, even if the probability is a bit lower */ static void minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9195d5a2de0a..9f89fb5bee37 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -169,7 +169,7 @@ struct sta_info; * @buf_size: reorder buffer size at receiver * @failed_bar_ssn: ssn of the last failed BAR tx attempt * @bar_pending: BAR needs to be re-sent - * @amsdu: support A-MSDU withing A-MDPU + * @amsdu: support A-MSDU within A-MDPU * @ssn: starting sequence number of the session * * This structure's lifetime is managed by RCU, assignments to diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index e7f57bb18f6e..7aac84cec044 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -313,7 +313,7 @@ int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx, * Record previously received IV, will be copied into the * key information after MIC verification. It is possible * that we don't catch replays of fragments but that's ok - * because the Michael MIC verication will then fail. + * because the Michael MIC verification will then fail. */ *out_iv32 = iv32; *out_iv16 = iv16; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a9ee86982259..eedb2c5123ab 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -6214,7 +6214,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, goto start_xmit; /* update QoS header to prioritize control port frames if possible, - * priorization also happens for control port frames send over + * prioritization also happens for control port frames send over * AF_PACKET */ rcu_read_lock(); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f0db60878321..bd93de637f94 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1010,7 +1010,7 @@ void ieee80211_set_wmm_default(struct ieee80211_link_data *link, else aCWmin = 15; - /* Confiure old 802.11b/g medium access rules. */ + /* Configure old 802.11b/g medium access rules. */ qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index bf6ef45af757..eafe47bf201a 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -280,10 +280,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, /* * This is a workaround for VHT-enabled STAs which break the spec * and have the VHT-MCS Rx map filled in with value 3 for all eight - * spacial streams, an example is AR9462. + * spatial streams, an example is AR9462. * * As per spec, in section 22.1.1 Introduction to the VHT PHY - * A VHT STA shall support at least single spactial stream VHT-MCSs + * A VHT STA shall support at least single spatial stream VHT-MCSs * 0 to 7 (transmit and receive) in all supported channel widths. */ if (vht_cap->vht_mcs.rx_mcs_map == cpu_to_le16(0xFFFF)) { diff --git a/net/wireless/chan.c b/net/wireless/chan.c index e579d7e1425f..afd86f7c66ce 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -289,7 +289,7 @@ static bool cfg80211_valid_center_freq(u32 center, /* * Valid channels are packed from lowest frequency towards higher ones. - * So test that the lower frequency alignes with one of these steps. + * So test that the lower frequency aligns with one of these steps. */ return (center - bw / 2 - 5945) % step == 0; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9ab777e0bd4d..d51bcb4e9108 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12446,7 +12446,7 @@ static int nl80211_del_pmksa(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) { pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); } else if (info->attrs[NL80211_ATTR_SSID]) { - /* SSID based pmksa flush suppported only for FILS, + /* SSID based pmksa flush supported only for FILS, * OWE/SAE OFFLOAD cases */ if (info->attrs[NL80211_ATTR_FILS_CACHE_ID] && @@ -15498,7 +15498,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { /* TODO: handle 802.11 TSPEC/admission control * need more attributes for that (e.g. BA session requirement); - * change the WMM adminssion test above to allow both then + * change the WMM admission test above to allow both then */ return -EINVAL; } diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index ae2e1a896461..619187e229b4 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -200,7 +200,7 @@ static void find_ns(struct ieee80211_radiotap_iterator *iterator, * present fields. @this_arg can be changed by the caller (eg, * incremented to move inside a compound argument like * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in - * little-endian format whatever the endianess of your CPU. + * little-endian format whatever the endianness of your CPU. * * Alignment Gotcha: * You must take care when dereferencing iterator.this_arg diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6489ba943a63..1df65a5a44f7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1147,7 +1147,7 @@ static const struct ieee80211_regdomain *reg_get_regdomain(struct wiphy *wiphy) /* * Follow the driver's regulatory domain, if present, unless a country - * IE has been processed or a user wants to help complaince further + * IE has been processed or a user wants to help compliance further */ if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && lr->initiator != NL80211_REGDOM_SET_BY_USER && diff --git a/net/wireless/util.c b/net/wireless/util.c index f49b55724f83..93a9c32418a6 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -743,7 +743,7 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, return NULL; /* - * When reusing framents, copy some data to the head to simplify + * When reusing fragments, copy some data to the head to simplify * ethernet header handling and speed up protocol header processing * in the stack later. */ diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 2371069f3c43..cd9f8f6e298b 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1204,7 +1204,7 @@ static int cfg80211_wext_siwpower(struct net_device *dev, switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_ON: /* If not specified */ case IW_POWER_MODE: /* If set all mask */ - case IW_POWER_ALL_R: /* If explicitely state all */ + case IW_POWER_ALL_R: /* If explicitly state all */ ps = true; break; default: /* Otherwise we ignore */ diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 838ad6541a17..3bb04b05c5ce 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -1159,7 +1159,7 @@ char *iwe_stream_add_event(struct iw_request_info *info, char *stream, /* Check if it's possible */ if (likely((stream + event_len) < ends)) { iwe->len = event_len; - /* Beware of alignement issues on 64 bits */ + /* Beware of alignment issues on 64 bits */ memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); memcpy(stream + lcp_len, &iwe->u, event_len - lcp_len); From bd9813d13be439851a7ff3e6372e53caa6e387a6 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periyasamy Date: Tue, 17 Sep 2024 19:32:39 +0530 Subject: [PATCH 040/126] wifi: cfg80211: check radio iface combination for multi radio per wiphy Currently, wiphy_verify_combinations() fails for the multi-radio per wiphy due to the condition check on new global interface combination that DFS only works on one channel. In a multi-radio scenario, new global interface combination encompasses the capabilities of all radio combinations, so it supports more than one channel with DFS. For multi-radio per wiphy, interface combination verification needs to be performed for radio specific interface combinations. This is necessary as the new global interface combination combines the capabilities of all radio combinations. Fixes: a01b1e9f9955 ("wifi: mac80211: add support for DFS with multiple radios") Signed-off-by: Karthikeyan Periyasamy Link: https://patch.msgid.link/20240917140239.886083-1-quic_periyasa@quicinc.com Signed-off-by: Johannes Berg --- net/wireless/core.c | 64 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 661adfc77644..4c8d8f167409 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -603,16 +603,20 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, } EXPORT_SYMBOL(wiphy_new_nm); -static int wiphy_verify_combinations(struct wiphy *wiphy) +static +int wiphy_verify_iface_combinations(struct wiphy *wiphy, + const struct ieee80211_iface_combination *iface_comb, + int n_iface_comb, + bool combined_radio) { const struct ieee80211_iface_combination *c; int i, j; - for (i = 0; i < wiphy->n_iface_combinations; i++) { + for (i = 0; i < n_iface_comb; i++) { u32 cnt = 0; u16 all_iftypes = 0; - c = &wiphy->iface_combinations[i]; + c = &iface_comb[i]; /* * Combinations with just one interface aren't real, @@ -625,9 +629,13 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(!c->num_different_channels)) return -EINVAL; - /* DFS only works on one channel. */ - if (WARN_ON(c->radar_detect_widths && - (c->num_different_channels > 1))) + /* DFS only works on one channel. Avoid this check + * for multi-radio global combination, since it hold + * the capabilities of all radio combinations. + */ + if (!combined_radio && + WARN_ON(c->radar_detect_widths && + c->num_different_channels > 1)) return -EINVAL; if (WARN_ON(!c->n_limits)) @@ -648,13 +656,21 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(wiphy->software_iftypes & types)) return -EINVAL; - /* Only a single P2P_DEVICE can be allowed */ - if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && + /* Only a single P2P_DEVICE can be allowed, avoid this + * check for multi-radio global combination, since it + * hold the capabilities of all radio combinations. + */ + if (!combined_radio && + WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && c->limits[j].max > 1)) return -EINVAL; - /* Only a single NAN can be allowed */ - if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && + /* Only a single NAN can be allowed, avoid this + * check for multi-radio global combination, since it + * hold the capabilities of all radio combinations. + */ + if (!combined_radio && + WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && c->limits[j].max > 1)) return -EINVAL; @@ -693,6 +709,34 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) return 0; } +static int wiphy_verify_combinations(struct wiphy *wiphy) +{ + int i, ret; + bool combined_radio = false; + + if (wiphy->n_radio) { + for (i = 0; i < wiphy->n_radio; i++) { + const struct wiphy_radio *radio = &wiphy->radio[i]; + + ret = wiphy_verify_iface_combinations(wiphy, + radio->iface_combinations, + radio->n_iface_combinations, + false); + if (ret) + return ret; + } + + combined_radio = true; + } + + ret = wiphy_verify_iface_combinations(wiphy, + wiphy->iface_combinations, + wiphy->n_iface_combinations, + combined_radio); + + return ret; +} + int wiphy_register(struct wiphy *wiphy) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); From b0b6646a9d680c1d865ef308d84de98e28df9963 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 30 Sep 2024 13:21:13 +0200 Subject: [PATCH 041/126] mac80211: Reorganize kerneldoc parameter names Reorganize kerneldoc parameter names to match the parameter order in the function header. Problems identified using Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Jeff Johnson Link: https://patch.msgid.link/20240930112121.95324-28-Julia.Lawall@inria.fr Signed-off-by: Johannes Berg --- net/mac80211/mesh_hwmp.c | 6 +++--- net/mac80211/mesh_pathtbl.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 024f48db6b05..0b13a6648e08 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -220,12 +220,12 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, /** * mesh_path_error_tx - Sends a PERR mesh management frame * + * @sdata: local mesh subif * @ttl: allowed remaining hops * @target: broken destination * @target_sn: SN of the broken destination * @target_rcode: reason code for this PERR * @ra: node this frame is addressed to - * @sdata: local mesh subif * * Note: This function may be called with driver locks taken that the driver * also acquires in the TX path. To avoid a deadlock we don't transmit the @@ -1137,8 +1137,8 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) /** * mesh_nexthop_resolve - lookup next hop; conditionally start path discovery * - * @skb: 802.11 frame to be sent * @sdata: network subif the frame will be sent through + * @skb: 802.11 frame to be sent * * Lookup next hop for given skb and start path discovery if no * forwarding information is found. @@ -1245,8 +1245,8 @@ void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, * this function is considered "using" the associated mpath, so preempt a path * refresh if this mpath expires soon. * - * @skb: 802.11 frame to be sent * @sdata: network subif the frame will be sent through + * @skb: 802.11 frame to be sent * * Returns: 0 if the next hop was found. Nonzero otherwise. */ diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 30c0d89203af..9f9cb5af0a97 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -300,8 +300,8 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx) /** * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index - * @idx: index * @sdata: local subif, or NULL for all entries + * @idx: index * * Returns: pointer to the mesh path structure, or NULL if not found. * @@ -315,8 +315,8 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) /** * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index - * @idx: index * @sdata: local subif, or NULL for all entries + * @idx: index * * Returns: pointer to the proxy path structure, or NULL if not found. * @@ -670,8 +670,8 @@ void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, /** * mesh_path_add - allocate and add a new path to the mesh path table - * @dst: destination address of the path (ETH_ALEN length) * @sdata: local subif + * @dst: destination address of the path (ETH_ALEN length) * * Returns: 0 on success * @@ -916,8 +916,8 @@ static int table_path_del(struct mesh_table *tbl, /** * mesh_path_del - delete a mesh path from the table * - * @addr: dst address (ETH_ALEN length) * @sdata: local subif + * @addr: dst address (ETH_ALEN length) * * Returns: 0 if successful */ @@ -996,8 +996,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath) /** * mesh_path_discard_frame - discard a frame whose path could not be resolved * - * @skb: frame to discard * @sdata: network subif the frame was to be sent through + * @skb: frame to discard * * Locking: the function must me called within a rcu_read_lock region */ From 484bd64bdc2721224e90e131607398e546cf84b1 Mon Sep 17 00:00:00 2001 From: Dmitry Kandybka Date: Thu, 3 Oct 2024 12:59:12 +0300 Subject: [PATCH 042/126] wifi: nl80211: remove redundant null pointer check in coalescing In 'cfg80211_free_coalesce', '&coalesce->rules[i]' is a pointer to VLA member of 'struct cfg80211_coalesce' and should never be NULL, so redundant check may be dropped. I think this is correct, but I haven't tested it seriously. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Dmitry Kandybka Link: https://patch.msgid.link/20241003095912.218465-1-d.kandybka@gmail.com Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d51bcb4e9108..4e3609176880 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -14061,8 +14061,6 @@ void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce) for (i = 0; i < coalesce->n_rules; i++) { rule = &coalesce->rules[i]; - if (!rule) - continue; for (j = 0; j < rule->n_patterns; j++) kfree(rule->patterns[j].mask); kfree(rule->patterns); From 77511103be444d5368c04caa3e8af9eb54e762ab Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:51 +0200 Subject: [PATCH 043/126] wifi: qtnfmac: don't include lib80211.h This driver doesn't use it, and really can't, so don't include lib80211.h. Link: https://patch.msgid.link/20241007202706.d92615cbf659.I2dc8ea3df0760121dc202616bdf3942caf51b232@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/quantenna/qtnfmac/core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h index b204a24074ab..b375a4751580 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.h +++ b/drivers/net/wireless/quantenna/qtnfmac/core.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include From da066f38717550f2ec8a4919f5a3585ea595e972 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:52 +0200 Subject: [PATCH 044/126] wifi: mwifiex: don't include lib80211.h This really should never have been used, it's ancient code, but then the driver needs its own define for NUM_WEP_KEYS. Link: https://patch.msgid.link/20241007202706.74be9cca3eb8.I47b2e8e2d09c0a0be1f8346478d3d908b4021abd@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/marvell/mwifiex/ioctl.h | 2 +- drivers/net/wireless/marvell/mwifiex/main.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h index 516159b721d3..74747d3a379a 100644 --- a/drivers/net/wireless/marvell/mwifiex/ioctl.h +++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h @@ -8,7 +8,7 @@ #ifndef _MWIFIEX_IOCTL_H_ #define _MWIFIEX_IOCTL_H_ -#include +#define NUM_WEP_KEYS 4 enum { MWIFIEX_SCAN_TYPE_UNCHANGED = 0, diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 566adce3413c..366590236ed7 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include From 4fe9a5ec4501ddd142291cdd6edd989987cf66e6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:53 +0200 Subject: [PATCH 045/126] wifi: libertas: don't select/include lib80211 This isn't used in this driver, and should't be, so remove the include as well as the select. Link: https://patch.msgid.link/20241007202706.f8a6dd67f650.I74bc1f334c02043a238303d3e71c955d0d9b01b0@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/marvell/libertas/Kconfig | 1 - drivers/net/wireless/marvell/libertas/mesh.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig index 36b234bc5be8..caf8bc231b2e 100644 --- a/drivers/net/wireless/marvell/libertas/Kconfig +++ b/drivers/net/wireless/marvell/libertas/Kconfig @@ -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. diff --git a/drivers/net/wireless/marvell/libertas/mesh.h b/drivers/net/wireless/marvell/libertas/mesh.h index 44c4cd0230a8..e37db10e82a9 100644 --- a/drivers/net/wireless/marvell/libertas/mesh.h +++ b/drivers/net/wireless/marvell/libertas/mesh.h @@ -7,7 +7,6 @@ #include -#include #include "host.h" #include "dev.h" From be9be9f54f225f8301a0eb10d2d6f79077817e75 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:54 +0200 Subject: [PATCH 046/126] staging: rtl8192e: delete the driver This driver is using lib80211 and any driver that plans to ever leave staging should never have done that, so remove the driver to enable cleaning up lib80211 into libipw inside the old Intel drivers. Acked-by: Greg Kroah-Hartman Link: https://patch.msgid.link/20241007202707.d0e59cdd2cdc.I8e4d74a6e1d09eefe1f5e2e208735ba2ccef1d4f@changeid Signed-off-by: Johannes Berg --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rtl8192e/Kconfig | 61 - drivers/staging/rtl8192e/Makefile | 19 - drivers/staging/rtl8192e/TODO | 18 - drivers/staging/rtl8192e/rtl8192e/Kconfig | 10 - drivers/staging/rtl8192e/rtl8192e/Makefile | 19 - .../staging/rtl8192e/rtl8192e/r8190P_def.h | 265 -- .../rtl8192e/rtl8192e/r8190P_rtl8256.c | 198 -- .../rtl8192e/rtl8192e/r8190P_rtl8256.h | 17 - .../staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c | 79 - .../staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h | 12 - .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 1920 ------------ .../staging/rtl8192e/rtl8192e/r8192E_dev.h | 34 - .../rtl8192e/rtl8192e/r8192E_firmware.c | 189 -- .../rtl8192e/rtl8192e/r8192E_firmware.h | 52 - drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h | 244 -- .../staging/rtl8192e/rtl8192e/r8192E_phy.c | 1109 ------- .../staging/rtl8192e/rtl8192e/r8192E_phy.h | 57 - .../staging/rtl8192e/rtl8192e/r8192E_phyreg.h | 773 ----- drivers/staging/rtl8192e/rtl8192e/rtl_cam.c | 123 - drivers/staging/rtl8192e/rtl8192e/rtl_cam.h | 25 - drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 2016 ------------- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 402 --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 1857 ------------ drivers/staging/rtl8192e/rtl8192e/rtl_dm.h | 155 - .../staging/rtl8192e/rtl8192e/rtl_eeprom.c | 84 - .../staging/rtl8192e/rtl8192e/rtl_eeprom.h | 12 - .../staging/rtl8192e/rtl8192e/rtl_ethtool.c | 37 - drivers/staging/rtl8192e/rtl8192e/rtl_pci.c | 79 - drivers/staging/rtl8192e/rtl8192e/rtl_pci.h | 20 - drivers/staging/rtl8192e/rtl8192e/rtl_pm.c | 89 - drivers/staging/rtl8192e/rtl8192e/rtl_pm.h | 16 - drivers/staging/rtl8192e/rtl8192e/rtl_ps.c | 231 -- drivers/staging/rtl8192e/rtl8192e/rtl_ps.h | 31 - drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 866 ------ drivers/staging/rtl8192e/rtl8192e/rtl_wx.h | 13 - drivers/staging/rtl8192e/rtl8192e/table.c | 543 ---- drivers/staging/rtl8192e/rtl8192e/table.h | 27 - drivers/staging/rtl8192e/rtl819x_BA.h | 60 - drivers/staging/rtl8192e/rtl819x_BAProc.c | 544 ---- drivers/staging/rtl8192e/rtl819x_HT.h | 223 -- drivers/staging/rtl8192e/rtl819x_HTProc.c | 699 ----- drivers/staging/rtl8192e/rtl819x_Qos.h | 43 - drivers/staging/rtl8192e/rtl819x_TS.h | 50 - drivers/staging/rtl8192e/rtl819x_TSProc.c | 450 --- drivers/staging/rtl8192e/rtllib.h | 1810 ------------ drivers/staging/rtl8192e/rtllib_crypt_ccmp.c | 411 --- drivers/staging/rtl8192e/rtllib_crypt_tkip.c | 712 ----- drivers/staging/rtl8192e/rtllib_crypt_wep.c | 242 -- drivers/staging/rtl8192e/rtllib_module.c | 179 -- drivers/staging/rtl8192e/rtllib_rx.c | 2564 ----------------- drivers/staging/rtl8192e/rtllib_softmac.c | 2309 --------------- drivers/staging/rtl8192e/rtllib_softmac_wx.c | 534 ---- drivers/staging/rtl8192e/rtllib_tx.c | 901 ------ drivers/staging/rtl8192e/rtllib_wx.c | 752 ----- 56 files changed, 24188 deletions(-) delete mode 100644 drivers/staging/rtl8192e/Kconfig delete mode 100644 drivers/staging/rtl8192e/Makefile delete mode 100644 drivers/staging/rtl8192e/TODO delete mode 100644 drivers/staging/rtl8192e/rtl8192e/Kconfig delete mode 100644 drivers/staging/rtl8192e/rtl8192e/Makefile delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8190P_def.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_cam.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_cam.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_core.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_core.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_dm.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_dm.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_pci.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_pci.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_pm.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_pm.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_ps.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_ps.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_wx.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/rtl_wx.h delete mode 100644 drivers/staging/rtl8192e/rtl8192e/table.c delete mode 100644 drivers/staging/rtl8192e/rtl8192e/table.h delete mode 100644 drivers/staging/rtl8192e/rtl819x_BA.h delete mode 100644 drivers/staging/rtl8192e/rtl819x_BAProc.c delete mode 100644 drivers/staging/rtl8192e/rtl819x_HT.h delete mode 100644 drivers/staging/rtl8192e/rtl819x_HTProc.c delete mode 100644 drivers/staging/rtl8192e/rtl819x_Qos.h delete mode 100644 drivers/staging/rtl8192e/rtl819x_TS.h delete mode 100644 drivers/staging/rtl8192e/rtl819x_TSProc.c delete mode 100644 drivers/staging/rtl8192e/rtllib.h delete mode 100644 drivers/staging/rtl8192e/rtllib_crypt_ccmp.c delete mode 100644 drivers/staging/rtl8192e/rtllib_crypt_tkip.c delete mode 100644 drivers/staging/rtl8192e/rtllib_crypt_wep.c delete mode 100644 drivers/staging/rtl8192e/rtllib_module.c delete mode 100644 drivers/staging/rtl8192e/rtllib_rx.c delete mode 100644 drivers/staging/rtl8192e/rtllib_softmac.c delete mode 100644 drivers/staging/rtl8192e/rtllib_softmac_wx.c delete mode 100644 drivers/staging/rtl8192e/rtllib_tx.c delete mode 100644 drivers/staging/rtl8192e/rtllib_wx.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index db4a392841b1..3f46446a84fa 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -26,8 +26,6 @@ if STAGING source "drivers/staging/olpc_dcon/Kconfig" -source "drivers/staging/rtl8192e/Kconfig" - source "drivers/staging/rtl8723bs/Kconfig" source "drivers/staging/rtl8712/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5390879b5d1b..5f32a5d1957b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,7 +3,6 @@ obj-y += media/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ -obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_RTS5208) += rts5208/ diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig deleted file mode 100644 index e06c189b4ce4..000000000000 --- a/drivers/staging/rtl8192e/Kconfig +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config RTLLIB - tristate "Support for rtllib wireless devices" - depends on WLAN && m - select LIB80211 - select CRC32 - help - If you have a wireless card that uses rtllib, say - Y. Currently the only card is the rtl8192e. - - If unsure, say N. - - This driver adds support for rtllib wireless cards. - Only the rtl8192e is supported as of now. - -if RTLLIB - -config RTLLIB_CRYPTO_CCMP - tristate "Support for rtllib CCMP crypto" - depends on RTLLIB - select CRYPTO - select CRYPTO_AES - select CRYPTO_CCM - default y - help - CCMP crypto driver for rtllib. - - If you enabled RTLLIB, you want this. - Adds support for the CCM mode Protocol crypto driver for - use in wireless cards (including rtllib cards). - -config RTLLIB_CRYPTO_TKIP - tristate "Support for rtllib TKIP crypto" - depends on RTLLIB - select CRYPTO - select CRYPTO_LIB_ARC4 - select CRYPTO_MICHAEL_MIC - default y - help - TKIP crypto driver for rtllib. - - If you enabled RTLLIB, you want this. - Adds support for the Temporal Key Integrity Protocol for - the IEEE 802.11i standard for use on wireless cards. - -config RTLLIB_CRYPTO_WEP - tristate "Support for rtllib WEP crypto" - select CRYPTO_LIB_ARC4 - depends on RTLLIB - default y - help - WEP crypto driver for rtllib. - - If you enabled RTLLIB, you want this. - Adds support for the (now weak) Wired Equivalent Privacy - (WEP) crypto protocol for wireless cards. - NOTE: This protocol is now considered insecure. - -source "drivers/staging/rtl8192e/rtl8192e/Kconfig" - -endif diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile deleted file mode 100644 index a1492215dab1..000000000000 --- a/drivers/staging/rtl8192e/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -rtllib-objs := \ - rtllib_module.o \ - rtllib_rx.o \ - rtllib_tx.o \ - rtllib_wx.o \ - rtllib_softmac.o \ - rtllib_softmac_wx.o \ - rtl819x_BAProc.o \ - rtl819x_HTProc.o \ - rtl819x_TSProc.o - -obj-$(CONFIG_RTLLIB) += rtllib.o - -obj-$(CONFIG_RTLLIB_CRYPTO_CCMP) += rtllib_crypt_ccmp.o -obj-$(CONFIG_RTLLIB_CRYPTO_TKIP) += rtllib_crypt_tkip.o -obj-$(CONFIG_RTLLIB_CRYPTO_WEP) += rtllib_crypt_wep.o - -obj-$(CONFIG_RTL8192E) += rtl8192e/ diff --git a/drivers/staging/rtl8192e/TODO b/drivers/staging/rtl8192e/TODO deleted file mode 100644 index 7221ae65d63e..000000000000 --- a/drivers/staging/rtl8192e/TODO +++ /dev/null @@ -1,18 +0,0 @@ -To-do list: - -* merge into drivers/net/wireless/realtek/rtlwifi/rtl8192* -* clean up function naming -* Correct the coding style according to Linux guidelines; please read the document - at https://www.kernel.org/doc/html/latest/process/coding-style.html. -* Remove unnecessary debugging/printing macros; for those that are still needed - use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). -* Remove dead code such as unusued functions, variables, fields, etc.. -* Use in-kernel API and remove unnecessary wrappers where possible. -* Fix bugs due to code that sleeps in atomic context. -* Remove the HAL layer and migrate its functionality into the relevant parts of - the driver. -* Switch to use LIB80211. -* Switch to use MAC80211. -* Switch to use CFG80211. -* Improve the error handling of various functions, particularly those that use - existing kernel APIs. diff --git a/drivers/staging/rtl8192e/rtl8192e/Kconfig b/drivers/staging/rtl8192e/rtl8192e/Kconfig deleted file mode 100644 index f8f774a16295..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config RTL8192E - tristate "RealTek RTL8192E Wireless LAN NIC driver" - depends on PCI && WLAN && RTLLIB - depends on m - select CFG80211 - select WIRELESS_EXT - select WEXT_PRIV - select CRYPTO - select FW_LOADER diff --git a/drivers/staging/rtl8192e/rtl8192e/Makefile b/drivers/staging/rtl8192e/rtl8192e/Makefile deleted file mode 100644 index a442d79ea71e..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -r8192e_pci-objs := \ - r8192E_dev.o \ - r8192E_phy.o \ - r8192E_firmware.o \ - r8192E_cmdpkt.o \ - table.o \ - r8190P_rtl8256.o \ - rtl_cam.o \ - rtl_core.o \ - rtl_dm.o \ - rtl_eeprom.o \ - rtl_ethtool.o \ - rtl_pci.o \ - rtl_pm.o \ - rtl_ps.o \ - rtl_wx.o \ - -obj-$(CONFIG_RTL8192E) += r8192e_pci.o diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h deleted file mode 100644 index d87bace0a19b..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h +++ /dev/null @@ -1,265 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef R8190P_DEF_H -#define R8190P_DEF_H - -#include - -#define MAX_SILENT_RESET_RX_SLOT_NUM 10 - -enum rtl819x_loopback { - RTL819X_NO_LOOPBACK = 0, - RTL819X_MAC_LOOPBACK = 1, - RTL819X_DMA_LOOPBACK = 2, - RTL819X_CCK_LOOPBACK = 3, -}; - -#define DESC90_RATE1M 0x00 -#define DESC90_RATE2M 0x01 -#define DESC90_RATE5_5M 0x02 -#define DESC90_RATE11M 0x03 -#define DESC90_RATE6M 0x04 -#define DESC90_RATE9M 0x05 -#define DESC90_RATE12M 0x06 -#define DESC90_RATE18M 0x07 -#define DESC90_RATE24M 0x08 -#define DESC90_RATE36M 0x09 -#define DESC90_RATE48M 0x0a -#define DESC90_RATE54M 0x0b -#define DESC90_RATEMCS0 0x00 -#define DESC90_RATEMCS1 0x01 -#define DESC90_RATEMCS2 0x02 -#define DESC90_RATEMCS3 0x03 -#define DESC90_RATEMCS4 0x04 -#define DESC90_RATEMCS5 0x05 -#define DESC90_RATEMCS6 0x06 -#define DESC90_RATEMCS7 0x07 -#define DESC90_RATEMCS8 0x08 -#define DESC90_RATEMCS9 0x09 -#define DESC90_RATEMCS10 0x0a -#define DESC90_RATEMCS11 0x0b -#define DESC90_RATEMCS12 0x0c -#define DESC90_RATEMCS13 0x0d -#define DESC90_RATEMCS14 0x0e -#define DESC90_RATEMCS15 0x0f -#define DESC90_RATEMCS32 0x20 - -#define SHORT_SLOT_TIME 9 -#define NON_SHORT_SLOT_TIME 20 - -#define RX_SMOOTH 20 - -#define QSLT_BK 0x1 -#define QSLT_BE 0x0 -#define QSLT_VI 0x4 -#define QSLT_VO 0x6 -#define QSLT_BEACON 0x10 -#define QSLT_HIGH 0x11 -#define QSLT_MGNT 0x12 -#define QSLT_CMD 0x13 - -#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007 -#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa -#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024 -#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007 -#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10 -#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd - -#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000 -#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08 -#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18 -#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 - -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 - -enum version_8190_loopback { - VERSION_8190_BD = 0x3, - VERSION_8190_BE -}; - -#define IC_VersionCut_D 0x3 - -enum rf_optype { - RF_OP_By_SW_3wire = 0, - RF_OP_By_FW, - RF_OP_MAX -}; - -struct bb_reg_definition { - u32 rfintfs; - u32 rfintfo; - u32 rfintfe; - u32 rf3wireOffset; - u32 rfHSSIPara2; - u32 rfLSSIReadBack; - u32 rfLSSIReadBackPi; -}; - -struct tx_fwinfo_8190pci { - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; - u8 TxBandwidth:1; - u8 TxSubCarrier:2; - u8 STBC:2; - u8 AllowAggregation:1; - u8 RtsHT:1; - u8 RtsShort:1; - u8 RtsBandwidth:1; - u8 RtsSubcarrier:2; - u8 RtsSTBC:2; - u8 EnableCPUDur:1; - - u32 RxMF:2; - u32 RxAMD:3; - u32 TxPerPktInfoFeedback:1; - u32 Reserved1:2; - u32 TxAGCOffset:4; - u32 TxAGCSign:1; - u32 RAW_TXD:1; - u32 Retry_Limit:4; - u32 Reserved2:1; - u32 PacketID:13; -}; - -struct phy_sts_ofdm_819xpci { - u8 trsw_gain_X[4]; - u8 pwdb_all; - u8 cfosho_X[4]; - u8 cfotail_X[4]; - u8 rxevm_X[2]; - u8 rxsnr_X[4]; - u8 pdsnr_X[2]; - u8 csi_current_X[2]; - u8 csi_target_X[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 sgi_en; - u8 rxsc_sgien_exflg; -}; - -struct phy_sts_cck_819xpci { - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_Beacon_RSSI_SLID_WIN_MAX 10 - -struct tx_desc { - u16 PktSize; - u8 Offset; - u8 Reserved1:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - u8 TxFWInfoSize; - u8 RATid:3; - u8 DISFB:1; - u8 USERATE:1; - u8 MOREFRAG:1; - u8 NoEnc:1; - u8 PIFS:1; - u8 QueueSelect:5; - u8 NoACM:1; - u8 Resv:2; - u8 SecCAMID:5; - u8 SecDescAssign:1; - u8 SecType:2; - - u16 TxBufferSize; - u8 PktId:7; - u8 Resv1:1; - u8 Reserved2; - - u32 TxBuffAddr; - - u32 NextDescAddress; - - u32 Reserved5; - u32 Reserved6; - u32 Reserved7; -}; - -struct tx_desc_cmd { - u16 PktSize; - u8 Reserved1; - u8 CmdType:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - u16 ElementReport; - u16 Reserved2; - - u16 TxBufferSize; - u16 Reserved3; - - u32 TxBuffAddr; - u32 NextDescAddress; - u32 Reserved4; - u32 Reserved5; - u32 Reserved6; -}; - -struct rx_desc { - u16 Length:14; - u16 CRC32:1; - u16 ICV:1; - u8 RxDrvInfoSize; - u8 Shift:2; - u8 PHYStatus:1; - u8 SWDec:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 EOR:1; - u8 OWN:1; - - u32 Reserved2; - - u32 Reserved3; - - u32 BufferAddress; -}; - -struct rx_fwinfo { - u16 Reserved1:12; - u16 PartAggr:1; - u16 FirstAGGR:1; - u16 Reserved2:2; - - u8 RxRate:7; - u8 RxHT:1; - - u8 BW:1; - u8 SPLCP:1; - u8 Reserved3:2; - u8 PAM:1; - u8 Mcast:1; - u8 Bcast:1; - u8 Reserved4:1; - - u32 TSFL; -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c deleted file mode 100644 index 7061f1cf4d3a..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_phyreg.h" -#include "r8192E_phy.h" -#include "r8190P_rtl8256.h" - -void rtl92e_set_bandwidth(struct net_device *dev, - enum ht_channel_width bandwidth) -{ - u8 eRFPath; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->card_8192_version != VERSION_8190_BD && - priv->card_8192_version != VERSION_8190_BE) { - netdev_warn(dev, "%s(): Unknown HW version.\n", __func__); - return; - } - - for (eRFPath = 0; eRFPath < priv->num_total_rf_path; eRFPath++) { - switch (bandwidth) { - case HT_CHANNEL_WIDTH_20: - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x0b, bMask12Bits, 0x100); - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x2c, bMask12Bits, 0x3d7); - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x0e, bMask12Bits, 0x021); - break; - case HT_CHANNEL_WIDTH_20_40: - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x0b, bMask12Bits, 0x300); - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x2c, bMask12Bits, 0x3ff); - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, - 0x0e, bMask12Bits, 0x0e1); - break; - default: - netdev_err(dev, "%s(): Unknown bandwidth: %#X\n", - __func__, bandwidth); - break; - } - } -} - -bool rtl92e_config_rf(struct net_device *dev) -{ - u32 u4RegValue = 0; - u8 eRFPath; - bool rtStatus = true; - struct bb_reg_definition *pPhyReg; - struct r8192_priv *priv = rtllib_priv(dev); - u32 RegOffSetToBeCheck = 0x3; - u32 RegValueToBeCheck = 0x7f1; - u32 RF3_Final_Value = 0; - u8 ConstRetryTimes = 5, RetryTimes = 5; - u8 ret = 0; - - priv->num_total_rf_path = RTL819X_TOTAL_RF_PATH; - - for (eRFPath = (enum rf90_radio_path)RF90_PATH_A; - eRFPath < priv->num_total_rf_path; eRFPath++) { - pPhyReg = &priv->phy_reg_def[eRFPath]; - - switch (eRFPath) { - case RF90_PATH_A: - u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs, - bRFSI_RFENV); - break; - case RF90_PATH_B: - u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs, - bRFSI_RFENV << 16); - break; - } - - rtl92e_set_bb_reg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); - - rtl92e_set_bb_reg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); - - rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, - b3WireAddressLength, 0x0); - rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, - b3WireDataLength, 0x0); - - rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, 0x0, - bMask12Bits, 0xbf); - - rtStatus = rtl92e_check_bb_and_rf(dev, HW90_BLOCK_RF, - (enum rf90_radio_path)eRFPath); - if (!rtStatus) { - netdev_err(dev, "%s(): Failed to check RF Path %d.\n", - __func__, eRFPath); - goto fail; - } - - RetryTimes = ConstRetryTimes; - RF3_Final_Value = 0; - while (RF3_Final_Value != RegValueToBeCheck && - RetryTimes != 0) { - ret = rtl92e_config_rf_path(dev, - (enum rf90_radio_path)eRFPath); - RF3_Final_Value = rtl92e_get_rf_reg(dev, - (enum rf90_radio_path)eRFPath, - RegOffSetToBeCheck, - bMask12Bits); - RetryTimes--; - } - - switch (eRFPath) { - case RF90_PATH_A: - rtl92e_set_bb_reg(dev, pPhyReg->rfintfs, bRFSI_RFENV, - u4RegValue); - break; - case RF90_PATH_B: - rtl92e_set_bb_reg(dev, pPhyReg->rfintfs, - bRFSI_RFENV << 16, u4RegValue); - break; - } - - if (ret) { - netdev_err(dev, - "%s(): Failed to initialize RF Path %d.\n", - __func__, eRFPath); - goto fail; - } - } - return true; - -fail: - return false; -} - -void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel) -{ - u32 TxAGC = 0; - struct r8192_priv *priv = rtllib_priv(dev); - - TxAGC = powerlevel; - if (priv->dynamic_tx_low_pwr) { - if (priv->customer_id == RT_CID_819X_NETCORE) - TxAGC = 0x22; - else - TxAGC += priv->cck_pwr_enl; - } - if (TxAGC > 0x24) - TxAGC = 0x24; - rtl92e_set_bb_reg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); -} - -void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 writeVal, powerBase0, powerBase1, writeVal_tmp; - u8 index = 0; - u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; - u8 byte0, byte1, byte2, byte3; - - powerBase0 = powerlevel + priv->legacy_ht_tx_pwr_diff; - powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | - (powerBase0 << 8) | powerBase0; - powerBase1 = powerlevel; - powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | - (powerBase1 << 8) | powerBase1; - - for (index = 0; index < 6; index++) { - writeVal = (u32)(priv->mcs_tx_pwr_level_org_offset[index] + - ((index < 2) ? powerBase0 : powerBase1)); - byte0 = writeVal & 0x7f; - byte1 = (writeVal & 0x7f00) >> 8; - byte2 = (writeVal & 0x7f0000) >> 16; - byte3 = (writeVal & 0x7f000000) >> 24; - if (byte0 > 0x24) - byte0 = 0x24; - if (byte1 > 0x24) - byte1 = 0x24; - if (byte2 > 0x24) - byte2 = 0x24; - if (byte3 > 0x24) - byte3 = 0x24; - - if (index == 3) { - writeVal_tmp = (byte3 << 24) | (byte2 << 16) | - (byte1 << 8) | byte0; - priv->pwr_track = writeVal_tmp; - } - - if (priv->dynamic_tx_high_pwr) - writeVal = 0x03030303; - else - writeVal = (byte3 << 24) | (byte2 << 16) | - (byte1 << 8) | byte0; - rtl92e_set_bb_reg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); - } -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h deleted file mode 100644 index 3c52e2b43095..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef RTL8225H -#define RTL8225H - -#define RTL819X_TOTAL_RF_PATH 2 -void rtl92e_set_bandwidth(struct net_device *dev, - enum ht_channel_width bandwidth); -bool rtl92e_config_rf(struct net_device *dev); -void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel); -void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c deleted file mode 100644 index e470b49b0ff7..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_hw.h" -#include "r8192E_cmdpkt.h" - -bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data, - u32 len) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u16 frag_length = 0, frag_offset = 0; - struct sk_buff *skb; - unsigned char *seg_ptr; - struct cb_desc *tcb_desc; - u8 bLastIniPkt; - - struct tx_fwinfo_8190pci *pTxFwInfo = NULL; - - do { - if ((len - frag_offset) > CMDPACKET_FRAG_SIZE) { - frag_length = CMDPACKET_FRAG_SIZE; - bLastIniPkt = 0; - - } else { - frag_length = (u16)(len - frag_offset); - bLastIniPkt = 1; - } - - if (type == DESC_PACKET_TYPE_NORMAL) - skb = dev_alloc_skb(frag_length + - priv->rtllib->tx_headroom + 4); - else - skb = dev_alloc_skb(frag_length + 4); - - if (!skb) - return false; - - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = type; - tcb_desc->bLastIniPkt = bLastIniPkt; - - if (type == DESC_PACKET_TYPE_NORMAL) { - tcb_desc->pkt_size = frag_length; - - seg_ptr = skb_put(skb, priv->rtllib->tx_headroom); - pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr; - memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); - memset(pTxFwInfo, 0x12, 8); - } else { - tcb_desc->txbuf_size = frag_length; - } - - skb_put_data(skb, data, frag_length); - - if (type == DESC_PACKET_TYPE_INIT && - (!priv->rtllib->check_nic_enough_desc(dev, TXCMD_QUEUE) || - (!skb_queue_empty(&priv->rtllib->skb_waitq[TXCMD_QUEUE])) || - (priv->rtllib->queue_stop))) { - skb_queue_tail(&priv->rtllib->skb_waitq[TXCMD_QUEUE], - skb); - } else { - priv->rtllib->softmac_hard_start_xmit(skb, dev); - } - - data += frag_length; - frag_offset += frag_length; - - } while (frag_offset < len); - - rtl92e_writeb(dev, TP_POLL, TP_POLL_CQ); - - return true; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h deleted file mode 100644 index c63909199e93..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef R819XUSB_CMDPKT_H -#define R819XUSB_CMDPKT_H - -bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data, - u32 len); -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c deleted file mode 100644 index b3d4b3394284..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ /dev/null @@ -1,1920 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" -#include "r8192E_cmdpkt.h" -#include "rtl_dm.h" -#include "rtl_wx.h" - -static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, - EDCAPARA_VO}; - -static void _rtl92e_update_msr(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 msr; - - msr = rtl92e_readb(dev, MSR); - msr &= ~MSR_LINK_MASK; - - switch (priv->rtllib->iw_mode) { - case IW_MODE_INFRA: - if (priv->rtllib->link_state == MAC80211_LINKED) - msr |= MSR_LINK_MANAGED; - break; - default: - break; - } - - rtl92e_writeb(dev, MSR, msr); -} - -void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - switch (variable) { - case HW_VAR_BSSID: - /* BSSIDR 2 byte alignment */ - rtl92e_writew(dev, BSSIDR, *(u16 *)val); - rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(val + 2)); - break; - - case HW_VAR_MEDIA_STATUS: - { - enum rt_op_mode op_mode = *((enum rt_op_mode *)(val)); - u8 btMsr = rtl92e_readb(dev, MSR); - - btMsr &= 0xfc; - - switch (op_mode) { - case RT_OP_MODE_INFRASTRUCTURE: - btMsr |= MSR_INFRA; - break; - - case RT_OP_MODE_IBSS: - btMsr |= MSR_ADHOC; - break; - - case RT_OP_MODE_AP: - btMsr |= MSR_AP; - break; - - default: - btMsr |= MSR_NOLINK; - break; - } - - rtl92e_writeb(dev, MSR, btMsr); - } - break; - - case HW_VAR_CECHK_BSSID: - { - u32 RegRCR, Type; - - Type = val[0]; - RegRCR = rtl92e_readl(dev, RCR); - priv->receive_config = RegRCR; - - if (Type) - RegRCR |= (RCR_CBSSID); - else - RegRCR &= (~RCR_CBSSID); - - rtl92e_writel(dev, RCR, RegRCR); - priv->receive_config = RegRCR; - } - break; - - case HW_VAR_SLOT_TIME: - - priv->slot_time = val[0]; - rtl92e_writeb(dev, SLOT_TIME, val[0]); - - break; - - case HW_VAR_ACK_PREAMBLE: - { - u32 regTmp; - - priv->short_preamble = (bool)*val; - regTmp = priv->basic_rate; - if (priv->short_preamble) - regTmp |= BRSR_AckShortPmb; - rtl92e_writel(dev, RRSR, regTmp); - break; - } - - case HW_VAR_CPU_RST: - rtl92e_writel(dev, CPU_GEN, ((u32 *)(val))[0]); - break; - - case HW_VAR_AC_PARAM: - { - u8 pAcParam = *val; - u32 eACI = pAcParam; - u8 u1bAIFS; - u32 u4bAcParam; - u8 mode = priv->rtllib->mode; - struct rtllib_qos_parameters *qop = - &priv->rtllib->current_network.qos_data.parameters; - - u1bAIFS = qop->aifs[pAcParam] * - ((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + asifs_time; - - rtl92e_dm_init_edca_turbo(dev); - - u4bAcParam = (le16_to_cpu(qop->tx_op_limit[pAcParam]) << - AC_PARAM_TXOP_LIMIT_OFFSET) | - ((le16_to_cpu(qop->cw_max[pAcParam])) << - AC_PARAM_ECW_MAX_OFFSET) | - ((le16_to_cpu(qop->cw_min[pAcParam])) << - AC_PARAM_ECW_MIN_OFFSET) | - (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET); - - switch (eACI) { - case AC1_BK: - rtl92e_writel(dev, EDCAPARA_BK, u4bAcParam); - break; - - case AC0_BE: - rtl92e_writel(dev, EDCAPARA_BE, u4bAcParam); - break; - - case AC2_VI: - rtl92e_writel(dev, EDCAPARA_VI, u4bAcParam); - break; - - case AC3_VO: - rtl92e_writel(dev, EDCAPARA_VO, u4bAcParam); - break; - - default: - netdev_info(dev, "SetHwReg8185(): invalid ACI: %d !\n", - eACI); - break; - } - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACM_CTRL, - &pAcParam); - break; - } - - case HW_VAR_ACM_CTRL: - { - struct rtllib_qos_parameters *qos_parameters = - &priv->rtllib->current_network.qos_data.parameters; - u8 pAcParam = *val; - u32 eACI = pAcParam; - union aci_aifsn *pAciAifsn = (union aci_aifsn *)& - (qos_parameters->aifs[0]); - u8 acm = pAciAifsn->f.acm; - u8 AcmCtrl = rtl92e_readb(dev, ACM_HW_CTRL); - - if (acm) { - switch (eACI) { - case AC0_BE: - AcmCtrl |= ACM_HW_BEQ_EN; - break; - - case AC2_VI: - AcmCtrl |= ACM_HW_VIQ_EN; - break; - - case AC3_VO: - AcmCtrl |= ACM_HW_VOQ_EN; - break; - } - } else { - switch (eACI) { - case AC0_BE: - AcmCtrl &= (~ACM_HW_BEQ_EN); - break; - - case AC2_VI: - AcmCtrl &= (~ACM_HW_VIQ_EN); - break; - - case AC3_VO: - AcmCtrl &= (~ACM_HW_BEQ_EN); - break; - - default: - break; - } - } - rtl92e_writeb(dev, ACM_HW_CTRL, AcmCtrl); - break; - } - - case HW_VAR_SIFS: - rtl92e_writeb(dev, SIFS, val[0]); - rtl92e_writeb(dev, SIFS + 1, val[0]); - break; - - case HW_VAR_RF_TIMING: - { - u8 Rf_Timing = *val; - - rtl92e_writeb(dev, rFPGA0_RFTiming1, Rf_Timing); - break; - } - - default: - break; - } -} - -static void _rtl92e_read_eeprom_info(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - const u8 bMac_Tmp_Addr[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; - u8 tempval; - u8 ICVer8192, ICVer8256; - u16 i, usValue, IC_Version; - u16 EEPROMId; - - EEPROMId = rtl92e_eeprom_read(dev, 0); - if (EEPROMId != RTL8190_EEPROM_ID) { - netdev_err(dev, "%s(): Invalid EEPROM ID: %x\n", __func__, - EEPROMId); - priv->autoload_fail_flag = true; - } else { - priv->autoload_fail_flag = false; - } - - if (!priv->autoload_fail_flag) { - priv->eeprom_vid = rtl92e_eeprom_read(dev, EEPROM_VID >> 1); - priv->eeprom_did = rtl92e_eeprom_read(dev, EEPROM_DID >> 1); - - usValue = rtl92e_eeprom_read(dev, - (EEPROM_Customer_ID >> 1)) >> 8; - priv->eeprom_customer_id = usValue & 0xff; - usValue = rtl92e_eeprom_read(dev, - EEPROM_ICVersion_ChannelPlan >> 1); - IC_Version = (usValue & 0xff00) >> 8; - - ICVer8192 = IC_Version & 0xf; - ICVer8256 = (IC_Version & 0xf0) >> 4; - if (ICVer8192 == 0x2) { - if (ICVer8256 == 0x5) - priv->card_8192_version = VERSION_8190_BE; - } - switch (priv->card_8192_version) { - case VERSION_8190_BD: - case VERSION_8190_BE: - break; - default: - priv->card_8192_version = VERSION_8190_BD; - break; - } - } else { - priv->card_8192_version = VERSION_8190_BD; - priv->eeprom_vid = 0; - priv->eeprom_did = 0; - priv->eeprom_customer_id = 0; - } - - if (!priv->autoload_fail_flag) { - u8 addr[ETH_ALEN]; - - for (i = 0; i < 6; i += 2) { - usValue = rtl92e_eeprom_read(dev, - (EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1); - *(u16 *)(&addr[i]) = usValue; - } - eth_hw_addr_set(dev, addr); - } else { - eth_hw_addr_set(dev, bMac_Tmp_Addr); - } - - if (priv->card_8192_version > VERSION_8190_BD) - priv->tx_pwr_data_read_from_eeprom = true; - else - priv->tx_pwr_data_read_from_eeprom = false; - - if (priv->card_8192_version > VERSION_8190_BD) { - if (!priv->autoload_fail_flag) { - tempval = (rtl92e_eeprom_read(dev, - (EEPROM_RFInd_PowerDiff >> 1))) & 0xff; - priv->eeprom_legacy_ht_tx_pwr_diff = tempval & 0xf; - } else { - priv->eeprom_legacy_ht_tx_pwr_diff = 0x04; - } - - if (!priv->autoload_fail_flag) - priv->eeprom_thermal_meter = ((rtl92e_eeprom_read(dev, - (EEPROM_ThermalMeter >> 1))) & - 0xff00) >> 8; - else - priv->eeprom_thermal_meter = EEPROM_Default_ThermalMeter; - priv->tssi_13dBm = priv->eeprom_thermal_meter * 100; - - if (priv->epromtype == EEPROM_93C46) { - if (!priv->autoload_fail_flag) { - usValue = rtl92e_eeprom_read(dev, - EEPROM_TxPwDiff_CrystalCap >> 1); - priv->eeprom_ant_pwr_diff = usValue & 0x0fff; - priv->eeprom_crystal_cap = (usValue & 0xf000) - >> 12; - } else { - priv->eeprom_ant_pwr_diff = - EEPROM_Default_AntTxPowerDiff; - priv->eeprom_crystal_cap = - EEPROM_Default_TxPwDiff_CrystalCap; - } - - for (i = 0; i < 14; i += 2) { - if (!priv->autoload_fail_flag) - usValue = rtl92e_eeprom_read(dev, - (EEPROM_TxPwIndex_CCK + i) >> 1); - else - usValue = EEPROM_Default_TxPower; - *((u16 *)(&priv->eeprom_tx_pwr_level_cck[i])) = - usValue; - } - for (i = 0; i < 14; i += 2) { - if (!priv->autoload_fail_flag) - usValue = rtl92e_eeprom_read(dev, - (EEPROM_TxPwIndex_OFDM_24G + i) >> 1); - else - usValue = EEPROM_Default_TxPower; - *((u16 *)(&priv->eeprom_tx_pwr_level_ofdm24g[i])) - = usValue; - } - } - if (priv->epromtype == EEPROM_93C46) { - for (i = 0; i < 14; i++) { - priv->tx_pwr_level_cck[i] = - priv->eeprom_tx_pwr_level_cck[i]; - priv->tx_pwr_level_ofdm_24g[i] = - priv->eeprom_tx_pwr_level_ofdm24g[i]; - } - priv->legacy_ht_tx_pwr_diff = - priv->eeprom_legacy_ht_tx_pwr_diff; - priv->antenna_tx_pwr_diff[0] = priv->eeprom_ant_pwr_diff & 0xf; - priv->antenna_tx_pwr_diff[1] = (priv->eeprom_ant_pwr_diff & - 0xf0) >> 4; - priv->antenna_tx_pwr_diff[2] = (priv->eeprom_ant_pwr_diff & - 0xf00) >> 8; - priv->crystal_cap = priv->eeprom_crystal_cap; - priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf; - priv->thermal_meter[1] = (priv->eeprom_thermal_meter & - 0xf0) >> 4; - } else if (priv->epromtype == EEPROM_93C56) { - priv->legacy_ht_tx_pwr_diff = - priv->eeprom_legacy_ht_tx_pwr_diff; - priv->antenna_tx_pwr_diff[0] = 0; - priv->antenna_tx_pwr_diff[1] = 0; - priv->antenna_tx_pwr_diff[2] = 0; - priv->crystal_cap = priv->eeprom_crystal_cap; - priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf; - priv->thermal_meter[1] = (priv->eeprom_thermal_meter & - 0xf0) >> 4; - } - } - - rtl92e_init_adaptive_rate(dev); - - switch (priv->eeprom_customer_id) { - case EEPROM_CID_NetCore: - priv->customer_id = RT_CID_819X_NETCORE; - break; - case EEPROM_CID_TOSHIBA: - priv->customer_id = RT_CID_TOSHIBA; - break; - } - - if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) - priv->rtllib->bSupportRemoteWakeUp = true; - else - priv->rtllib->bSupportRemoteWakeUp = false; -} - -void rtl92e_get_eeprom_size(struct net_device *dev) -{ - u16 curCR; - struct r8192_priv *priv = rtllib_priv(dev); - - curCR = rtl92e_readw(dev, EPROM_CMD); - priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 : - EEPROM_93C46; - _rtl92e_read_eeprom_info(dev); -} - -static void _rtl92e_hwconfig(struct net_device *dev) -{ - u32 regRATR = 0, regRRSR = 0; - u8 regBwOpMode = 0, regTmp = 0; - struct r8192_priv *priv = rtllib_priv(dev); - - switch (priv->rtllib->mode) { - case WIRELESS_MODE_B: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK; - regRRSR = RATE_ALL_CCK; - break; - case WIRELESS_MODE_AUTO: - case WIRELESS_MODE_N_24G: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_G: - default: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - } - - rtl92e_writeb(dev, BW_OPMODE, regBwOpMode); - { - u32 ratr_value; - - ratr_value = regRATR; - ratr_value &= ~(RATE_ALL_OFDM_2SS); - rtl92e_writel(dev, RATR0, ratr_value); - rtl92e_writeb(dev, UFWP, 1); - } - regTmp = rtl92e_readb(dev, 0x313); - regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); - rtl92e_writel(dev, RRSR, regRRSR); - - rtl92e_writew(dev, RETRY_LIMIT, - priv->short_retry_limit << RETRY_LIMIT_SHORT_SHIFT | - priv->long_retry_limit << RETRY_LIMIT_LONG_SHIFT); -} - -bool rtl92e_start_adapter(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 ulRegRead; - bool rtStatus = true; - u8 tmpvalue; - u8 ICVersion, SwitchingRegulatorOutput; - bool bfirmwareok = true; - u32 tmpRegA, TempCCk; - int i = 0; - u32 retry_times = 0; - - priv->being_init_adapter = true; - -start: - rtl92e_reset_desc_ring(dev); - priv->rf_mode = RF_OP_By_SW_3wire; - - rtl92e_writeb(dev, ANAPAR, 0x37); - mdelay(500); - - priv->fw_info->status = FW_STATUS_0_INIT; - - ulRegRead = rtl92e_readl(dev, CPU_GEN); - if (priv->fw_info->status == FW_STATUS_0_INIT) - ulRegRead |= CPU_GEN_SYSTEM_RESET; - else if (priv->fw_info->status == FW_STATUS_5_READY) - ulRegRead |= CPU_GEN_FIRMWARE_RESET; - else - netdev_err(dev, "%s(): undefined firmware state: %d.\n", - __func__, priv->fw_info->status); - - rtl92e_writel(dev, CPU_GEN, ulRegRead); - - ICVersion = rtl92e_readb(dev, IC_VERRSION); - if (ICVersion >= 0x4) { - SwitchingRegulatorOutput = rtl92e_readb(dev, SWREGULATOR); - if (SwitchingRegulatorOutput != 0xb8) { - rtl92e_writeb(dev, SWREGULATOR, 0xa8); - mdelay(1); - rtl92e_writeb(dev, SWREGULATOR, 0xb8); - } - } - rtStatus = rtl92e_config_bb(dev); - if (!rtStatus) { - netdev_warn(dev, "%s(): Failed to configure BB\n", __func__); - return rtStatus; - } - - priv->loopback_mode = RTL819X_NO_LOOPBACK; - ulRegRead = rtl92e_readl(dev, CPU_GEN); - if (priv->loopback_mode == RTL819X_NO_LOOPBACK) - ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | - CPU_GEN_NO_LOOPBACK_SET; - else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK) - ulRegRead |= CPU_CCK_LOOPBACK; - else - netdev_err(dev, "%s: Invalid loopback mode setting.\n", - __func__); - - rtl92e_writel(dev, CPU_GEN, ulRegRead); - - udelay(500); - - _rtl92e_hwconfig(dev); - rtl92e_writeb(dev, CMDR, CR_RE | CR_TE); - - rtl92e_writeb(dev, PCIF, ((MXDMA2_NO_LIMIT << MXDMA2_RX_SHIFT) | - (MXDMA2_NO_LIMIT << MXDMA2_TX_SHIFT))); - rtl92e_writel(dev, MAC0, ((u32 *)dev->dev_addr)[0]); - rtl92e_writew(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]); - rtl92e_writel(dev, RCR, priv->receive_config); - - rtl92e_writel(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << - RSVD_FW_QUEUE_PAGE_BK_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_BE << - RSVD_FW_QUEUE_PAGE_BE_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VI << - RSVD_FW_QUEUE_PAGE_VI_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VO << - RSVD_FW_QUEUE_PAGE_VO_SHIFT); - rtl92e_writel(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << - RSVD_FW_QUEUE_PAGE_MGNT_SHIFT); - rtl92e_writel(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW | - NUM_OF_PAGE_IN_FW_QUEUE_BCN << - RSVD_FW_QUEUE_PAGE_BCN_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_PUB << - RSVD_FW_QUEUE_PAGE_PUB_SHIFT); - - rtl92e_tx_enable(dev); - rtl92e_rx_enable(dev); - ulRegRead = (0xFFF00000 & rtl92e_readl(dev, RRSR)) | - RATE_ALL_OFDM_AG | RATE_ALL_CCK; - rtl92e_writel(dev, RRSR, ulRegRead); - rtl92e_writel(dev, RATR0 + 4 * 7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK)); - - rtl92e_writeb(dev, ACK_TIMEOUT, 0x30); - - rtl92e_set_wireless_mode(dev, priv->rtllib->mode); - rtl92e_cam_reset(dev); - { - u8 SECR_value = 0x0; - - SECR_value |= SCR_TxEncEnable; - SECR_value |= SCR_RxDecEnable; - SECR_value |= SCR_NoSKMC; - rtl92e_writeb(dev, SECR, SECR_value); - } - rtl92e_writew(dev, ATIMWND, 2); - rtl92e_writew(dev, BCN_INTERVAL, 100); - - for (i = 0; i < QOS_QUEUE_NUM; i++) - rtl92e_writel(dev, WDCAPARA_ADD[i], 0x005e4332); - - rtl92e_writeb(dev, 0xbe, 0xc0); - - rtl92e_config_mac(dev); - - if (priv->card_8192_version > VERSION_8190_BD) { - rtl92e_get_tx_power(dev); - rtl92e_set_tx_power(dev, priv->chan); - } - - tmpvalue = rtl92e_readb(dev, IC_VERRSION); - priv->ic_cut = tmpvalue; - - bfirmwareok = rtl92e_init_fw(dev); - if (!bfirmwareok) { - if (retry_times < 10) { - retry_times++; - goto start; - } else { - rtStatus = false; - goto end; - } - } - - rtStatus = rtl92e_config_rf(dev); - if (!rtStatus) { - netdev_info(dev, "RF Config failed\n"); - return rtStatus; - } - - rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); - rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); - - rtl92e_writeb(dev, 0x87, 0x0); - - if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_PS) { - rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason); - } else if (priv->rtllib->rf_off_reason >= RF_CHANGE_BY_IPS) { - rtl92e_set_rf_state(dev, rf_off, priv->rtllib->rf_off_reason); - } else { - priv->rtllib->rf_power_state = rf_on; - priv->rtllib->rf_off_reason = 0; - } - - if (priv->rtllib->FwRWRF) - priv->rf_mode = RF_OP_By_FW; - else - priv->rf_mode = RF_OP_By_SW_3wire; - - rtl92e_dm_init_txpower_tracking(dev); - - if (priv->ic_cut >= IC_VersionCut_D) { - tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord); - rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord); - - for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) { - if (tmpRegA == dm_tx_bb_gain[i]) { - priv->rfa_txpowertrackingindex = i; - priv->rfa_txpowertrackingindex_real = i; - priv->rfa_txpowertracking_default = - priv->rfa_txpowertrackingindex; - break; - } - } - - TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, - bMaskByte2); - - for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) { - if (TempCCk == dm_cck_tx_bb_gain[i][0]) { - priv->cck_present_attn_20m_def = i; - break; - } - } - priv->cck_present_attn_40m_def = 0; - priv->cck_present_attn_diff = 0; - priv->cck_present_attn = - priv->cck_present_attn_20m_def; - priv->btxpower_tracking = false; - } - rtl92e_irq_enable(dev); -end: - priv->being_init_adapter = false; - return rtStatus; -} - -static void _rtl92e_net_update(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_network *net; - u16 rate_config = 0; - - net = &priv->rtllib->current_network; - rtl92e_config_rate(dev, &rate_config); - priv->dot11_current_preamble_mode = PREAMBLE_AUTO; - priv->basic_rate = rate_config &= 0x15f; - rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid); - rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2)); -} - -void rtl92e_link_change(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - if (!priv->up) - return; - - if (ieee->link_state == MAC80211_LINKED) { - _rtl92e_net_update(dev); - rtl92e_update_ratr_table(dev); - if ((ieee->pairwise_key_type == KEY_TYPE_WEP40) || - (ieee->pairwise_key_type == KEY_TYPE_WEP104)) - rtl92e_enable_hw_security_config(dev); - } else { - rtl92e_writeb(dev, 0x173, 0); - } - _rtl92e_update_msr(dev); - - if (ieee->iw_mode == IW_MODE_INFRA) { - u32 reg; - - reg = rtl92e_readl(dev, RCR); - if (priv->rtllib->link_state == MAC80211_LINKED) - priv->receive_config = reg |= RCR_CBSSID; - else - priv->receive_config = reg &= ~RCR_CBSSID; - - rtl92e_writel(dev, RCR, reg); - } -} - -void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da, - bool write_into_reg) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (allow_all_da) - priv->receive_config |= RCR_AAP; - else - priv->receive_config &= ~RCR_AAP; - - if (write_into_reg) - rtl92e_writel(dev, RCR, priv->receive_config); -} - -static u8 _rtl92e_rate_mgn_to_hw(u8 rate) -{ - u8 ret = DESC90_RATE1M; - - switch (rate) { - case MGN_1M: - ret = DESC90_RATE1M; - break; - case MGN_2M: - ret = DESC90_RATE2M; - break; - case MGN_5_5M: - ret = DESC90_RATE5_5M; - break; - case MGN_11M: - ret = DESC90_RATE11M; - break; - case MGN_6M: - ret = DESC90_RATE6M; - break; - case MGN_9M: - ret = DESC90_RATE9M; - break; - case MGN_12M: - ret = DESC90_RATE12M; - break; - case MGN_18M: - ret = DESC90_RATE18M; - break; - case MGN_24M: - ret = DESC90_RATE24M; - break; - case MGN_36M: - ret = DESC90_RATE36M; - break; - case MGN_48M: - ret = DESC90_RATE48M; - break; - case MGN_54M: - ret = DESC90_RATE54M; - break; - case MGN_MCS0: - ret = DESC90_RATEMCS0; - break; - case MGN_MCS1: - ret = DESC90_RATEMCS1; - break; - case MGN_MCS2: - ret = DESC90_RATEMCS2; - break; - case MGN_MCS3: - ret = DESC90_RATEMCS3; - break; - case MGN_MCS4: - ret = DESC90_RATEMCS4; - break; - case MGN_MCS5: - ret = DESC90_RATEMCS5; - break; - case MGN_MCS6: - ret = DESC90_RATEMCS6; - break; - case MGN_MCS7: - ret = DESC90_RATEMCS7; - break; - case MGN_MCS8: - ret = DESC90_RATEMCS8; - break; - case MGN_MCS9: - ret = DESC90_RATEMCS9; - break; - case MGN_MCS10: - ret = DESC90_RATEMCS10; - break; - case MGN_MCS11: - ret = DESC90_RATEMCS11; - break; - case MGN_MCS12: - ret = DESC90_RATEMCS12; - break; - case MGN_MCS13: - ret = DESC90_RATEMCS13; - break; - case MGN_MCS14: - ret = DESC90_RATEMCS14; - break; - case MGN_MCS15: - ret = DESC90_RATEMCS15; - break; - case (0x80 | 0x20): - ret = DESC90_RATEMCS32; - break; - default: - break; - } - return ret; -} - -static u8 _rtl92e_hw_queue_to_fw_queue(struct net_device *dev, u8 QueueID, - u8 priority) -{ - u8 QueueSelect = 0x0; - - switch (QueueID) { - case BE_QUEUE: - QueueSelect = QSLT_BE; - break; - - case BK_QUEUE: - QueueSelect = QSLT_BK; - break; - - case VO_QUEUE: - QueueSelect = QSLT_VO; - break; - - case VI_QUEUE: - QueueSelect = QSLT_VI; - break; - case MGNT_QUEUE: - QueueSelect = QSLT_MGNT; - break; - case BEACON_QUEUE: - QueueSelect = QSLT_BEACON; - break; - case TXCMD_QUEUE: - QueueSelect = QSLT_CMD; - break; - case HIGH_QUEUE: - QueueSelect = QSLT_HIGH; - break; - default: - netdev_warn(dev, "%s(): Impossible Queue Selection: %d\n", - __func__, QueueID); - break; - } - return QueueSelect; -} - -static u8 _rtl92e_query_is_short(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc) -{ - u8 tmp_Short; - - tmp_Short = (TxHT == 1) ? ((tcb_desc->use_short_gi) ? 1 : 0) : - ((tcb_desc->use_short_preamble) ? 1 : 0); - if (TxHT == 1 && TxRate != DESC90_RATEMCS15) - tmp_Short = 0; - - return tmp_Short; -} - -void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, - struct cb_desc *cb_desc, struct sk_buff *skb) -{ - struct r8192_priv *priv = rtllib_priv(dev); - dma_addr_t mapping; - struct tx_fwinfo_8190pci *pTxFwInfo; - - pTxFwInfo = (struct tx_fwinfo_8190pci *)skb->data; - memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); - pTxFwInfo->TxHT = (cb_desc->data_rate & 0x80) ? 1 : 0; - pTxFwInfo->TxRate = _rtl92e_rate_mgn_to_hw(cb_desc->data_rate); - pTxFwInfo->EnableCPUDur = cb_desc->tx_enable_fw_calc_dur; - pTxFwInfo->Short = _rtl92e_query_is_short(pTxFwInfo->TxHT, - pTxFwInfo->TxRate, cb_desc); - - if (cb_desc->ampdu_enable) { - pTxFwInfo->AllowAggregation = 1; - pTxFwInfo->RxMF = cb_desc->ampdu_factor; - pTxFwInfo->RxAMD = cb_desc->ampdu_density; - } else { - pTxFwInfo->AllowAggregation = 0; - pTxFwInfo->RxMF = 0; - pTxFwInfo->RxAMD = 0; - } - - pTxFwInfo->RtsEnable = (cb_desc->rts_enable) ? 1 : 0; - pTxFwInfo->CtsEnable = (cb_desc->cts_enable) ? 1 : 0; - pTxFwInfo->RtsSTBC = (cb_desc->rtsstbc) ? 1 : 0; - pTxFwInfo->RtsHT = (cb_desc->rts_rate & 0x80) ? 1 : 0; - pTxFwInfo->RtsRate = _rtl92e_rate_mgn_to_hw(cb_desc->rts_rate); - pTxFwInfo->RtsBandwidth = 0; - pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC; - pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? - (cb_desc->rts_use_short_preamble ? 1 : 0) : - (cb_desc->rts_use_short_gi ? 1 : 0); - if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20_40) { - if (cb_desc->packet_bw) { - pTxFwInfo->TxBandwidth = 1; - pTxFwInfo->TxSubCarrier = 0; - } else { - pTxFwInfo->TxBandwidth = 0; - pTxFwInfo->TxSubCarrier = priv->n_cur_40mhz_prime_sc; - } - } else { - pTxFwInfo->TxBandwidth = 0; - pTxFwInfo->TxSubCarrier = 0; - } - - memset((u8 *)pdesc, 0, 12); - - mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len, - DMA_TO_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, mapping)) { - netdev_err(dev, "%s(): DMA Mapping error\n", __func__); - return; - } - - pdesc->LINIP = 0; - pdesc->CmdInit = 1; - pdesc->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; - pdesc->PktSize = skb->len - sizeof(struct tx_fwinfo_8190pci); - - pdesc->SecCAMID = 0; - pdesc->RATid = cb_desc->ratr_index; - - pdesc->NoEnc = 1; - pdesc->SecType = 0x0; - if (cb_desc->hw_sec) { - static u8 tmp; - - if (!tmp) - tmp = 1; - switch (priv->rtllib->pairwise_key_type) { - case KEY_TYPE_WEP40: - case KEY_TYPE_WEP104: - pdesc->SecType = 0x1; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_TKIP: - pdesc->SecType = 0x2; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_CCMP: - pdesc->SecType = 0x3; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_NA: - pdesc->SecType = 0x0; - pdesc->NoEnc = 1; - break; - } - } - - pdesc->PktId = 0x0; - - pdesc->QueueSelect = _rtl92e_hw_queue_to_fw_queue(dev, - cb_desc->queue_index, - cb_desc->priority); - pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci); - - pdesc->DISFB = cb_desc->tx_dis_rate_fallback; - pdesc->USERATE = cb_desc->tx_use_drv_assinged_rate; - - pdesc->FirstSeg = 1; - pdesc->LastSeg = 1; - pdesc->TxBufferSize = skb->len; - - pdesc->TxBuffAddr = mapping; -} - -void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, - struct cb_desc *cb_desc, struct sk_buff *skb) -{ - struct r8192_priv *priv = rtllib_priv(dev); - dma_addr_t mapping = dma_map_single(&priv->pdev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - - if (dma_mapping_error(&priv->pdev->dev, mapping)) - netdev_err(dev, "%s(): DMA Mapping error\n", __func__); - memset(entry, 0, 12); - entry->LINIP = cb_desc->bLastIniPkt; - entry->FirstSeg = 1; - entry->LastSeg = 1; - if (cb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { - entry->CmdInit = DESC_PACKET_TYPE_INIT; - } else { - struct tx_desc *entry_tmp = (struct tx_desc *)entry; - - entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL; - entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; - entry_tmp->PktSize = cb_desc->pkt_size + entry_tmp->Offset; - entry_tmp->QueueSelect = QSLT_CMD; - entry_tmp->TxFWInfoSize = 0x08; - entry_tmp->RATid = DESC_PACKET_TYPE_INIT; - } - entry->TxBufferSize = skb->len; - entry->TxBuffAddr = mapping; - entry->OWN = 1; -} - -static u8 _rtl92e_rate_hw_to_mgn(bool bIsHT, u8 rate) -{ - u8 ret_rate = 0x02; - - if (!bIsHT) { - switch (rate) { - case DESC90_RATE1M: - ret_rate = MGN_1M; - break; - case DESC90_RATE2M: - ret_rate = MGN_2M; - break; - case DESC90_RATE5_5M: - ret_rate = MGN_5_5M; - break; - case DESC90_RATE11M: - ret_rate = MGN_11M; - break; - case DESC90_RATE6M: - ret_rate = MGN_6M; - break; - case DESC90_RATE9M: - ret_rate = MGN_9M; - break; - case DESC90_RATE12M: - ret_rate = MGN_12M; - break; - case DESC90_RATE18M: - ret_rate = MGN_18M; - break; - case DESC90_RATE24M: - ret_rate = MGN_24M; - break; - case DESC90_RATE36M: - ret_rate = MGN_36M; - break; - case DESC90_RATE48M: - ret_rate = MGN_48M; - break; - case DESC90_RATE54M: - ret_rate = MGN_54M; - break; - } - - } else { - switch (rate) { - case DESC90_RATEMCS0: - ret_rate = MGN_MCS0; - break; - case DESC90_RATEMCS1: - ret_rate = MGN_MCS1; - break; - case DESC90_RATEMCS2: - ret_rate = MGN_MCS2; - break; - case DESC90_RATEMCS3: - ret_rate = MGN_MCS3; - break; - case DESC90_RATEMCS4: - ret_rate = MGN_MCS4; - break; - case DESC90_RATEMCS5: - ret_rate = MGN_MCS5; - break; - case DESC90_RATEMCS6: - ret_rate = MGN_MCS6; - break; - case DESC90_RATEMCS7: - ret_rate = MGN_MCS7; - break; - case DESC90_RATEMCS8: - ret_rate = MGN_MCS8; - break; - case DESC90_RATEMCS9: - ret_rate = MGN_MCS9; - break; - case DESC90_RATEMCS10: - ret_rate = MGN_MCS10; - break; - case DESC90_RATEMCS11: - ret_rate = MGN_MCS11; - break; - case DESC90_RATEMCS12: - ret_rate = MGN_MCS12; - break; - case DESC90_RATEMCS13: - ret_rate = MGN_MCS13; - break; - case DESC90_RATEMCS14: - ret_rate = MGN_MCS14; - break; - case DESC90_RATEMCS15: - ret_rate = MGN_MCS15; - break; - case DESC90_RATEMCS32: - ret_rate = 0x80 | 0x20; - break; - } - } - - return ret_rate; -} - -static long _rtl92e_signal_scale_mapping(struct r8192_priv *priv, long currsig) -{ - long retsig; - - if (currsig >= 61 && currsig <= 100) - retsig = 90 + ((currsig - 60) / 4); - else if (currsig >= 41 && currsig <= 60) - retsig = 78 + ((currsig - 40) / 2); - else if (currsig >= 31 && currsig <= 40) - retsig = 66 + (currsig - 30); - else if (currsig >= 21 && currsig <= 30) - retsig = 54 + (currsig - 20); - else if (currsig >= 5 && currsig <= 20) - retsig = 42 + (((currsig - 5) * 2) / 3); - else if (currsig == 4) - retsig = 36; - else if (currsig == 3) - retsig = 27; - else if (currsig == 2) - retsig = 18; - else if (currsig == 1) - retsig = 9; - else - retsig = currsig; - - return retsig; -} - -#define rx_hal_is_cck_rate(_pdrvinfo)\ - ((_pdrvinfo->RxRate == DESC90_RATE1M ||\ - _pdrvinfo->RxRate == DESC90_RATE2M ||\ - _pdrvinfo->RxRate == DESC90_RATE5_5M ||\ - _pdrvinfo->RxRate == DESC90_RATE11M) &&\ - !_pdrvinfo->RxHT) - -static void _rtl92e_query_rxphystatus( - struct r8192_priv *priv, - struct rtllib_rx_stats *pstats, - struct rx_desc *pdesc, - struct rx_fwinfo *pdrvinfo, - struct rtllib_rx_stats *precord_stats, - bool bpacket_match_bssid, - bool bpacket_toself, - bool bPacketBeacon, - bool bToSelfBA - ) -{ - struct phy_sts_ofdm_819xpci *pofdm_buf; - struct phy_sts_cck_819xpci *pcck_buf; - u8 *prxpkt; - u8 i, max_spatial_stream, tmp_rxevm; - s8 rx_pwr[4], rx_pwr_all = 0; - s8 rx_evmX; - u8 evm, pwdb_all; - u32 RSSI, total_rssi = 0; - u8 is_cck_rate = 0; - u8 rf_rx_num = 0; - static u8 check_reg824; - static u32 reg824_bit9; - - is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); - memset(precord_stats, 0, sizeof(struct rtllib_rx_stats)); - pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = - bpacket_match_bssid; - pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; - pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate; - pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; - pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; - if (check_reg824 == 0) { - reg824_bit9 = rtl92e_get_bb_reg(priv->rtllib->dev, - rFPGA0_XA_HSSIParameter2, - 0x200); - check_reg824 = 1; - } - - prxpkt = (u8 *)pdrvinfo; - - prxpkt += sizeof(struct rx_fwinfo); - - pcck_buf = (struct phy_sts_cck_819xpci *)prxpkt; - pofdm_buf = (struct phy_sts_ofdm_819xpci *)prxpkt; - - pstats->RxMIMOSignalQuality[0] = -1; - pstats->RxMIMOSignalQuality[1] = -1; - precord_stats->RxMIMOSignalQuality[0] = -1; - precord_stats->RxMIMOSignalQuality[1] = -1; - - if (is_cck_rate) { - u8 report; - - if (!reg824_bit9) { - report = pcck_buf->cck_agc_rpt & 0xc0; - report >>= 6; - switch (report) { - case 0x3: - rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x2: - rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x1: - rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x0: - rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - } - } else { - report = pcck_buf->cck_agc_rpt & 0x60; - report >>= 5; - switch (report) { - case 0x3: - rx_pwr_all = -35 - - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -23 - - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -11 - - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = -8 - - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - } - } - - pwdb_all = rtl92e_rx_db_to_percent(rx_pwr_all); - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RecvSignalPower = rx_pwr_all; - - if (bpacket_match_bssid) { - u8 sq; - - if (pstats->RxPWDBAll > 40) { - sq = 100; - } else { - sq = pcck_buf->sq_rpt; - - if (pcck_buf->sq_rpt > 64) - sq = 0; - else if (pcck_buf->sq_rpt < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - pstats->SignalQuality = sq; - precord_stats->SignalQuality = sq; - pstats->RxMIMOSignalQuality[0] = sq; - precord_stats->RxMIMOSignalQuality[0] = sq; - pstats->RxMIMOSignalQuality[1] = -1; - precord_stats->RxMIMOSignalQuality[1] = -1; - } - } else { - for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { - if (priv->brfpath_rxenable[i]) - rf_rx_num++; - - rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i] & 0x3F) * - 2) - 110; - - RSSI = rtl92e_rx_db_to_percent(rx_pwr[i]); - if (priv->brfpath_rxenable[i]) - total_rssi += RSSI; - - if (bpacket_match_bssid) { - pstats->RxMIMOSignalStrength[i] = RSSI; - precord_stats->RxMIMOSignalStrength[i] = RSSI; - } - } - - rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106; - pwdb_all = rtl92e_rx_db_to_percent(rx_pwr_all); - - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RecvSignalPower = rx_pwr_all; - if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 && - pdrvinfo->RxRate <= DESC90_RATEMCS15) - max_spatial_stream = 2; - else - max_spatial_stream = 1; - - for (i = 0; i < max_spatial_stream; i++) { - tmp_rxevm = pofdm_buf->rxevm_X[i]; - rx_evmX = (s8)(tmp_rxevm); - - rx_evmX /= 2; - - evm = rtl92e_evm_db_to_percent(rx_evmX); - if (bpacket_match_bssid) { - if (i == 0) { - pstats->SignalQuality = evm & 0xff; - precord_stats->SignalQuality = evm & 0xff; - } - pstats->RxMIMOSignalQuality[i] = evm & 0xff; - precord_stats->RxMIMOSignalQuality[i] = evm & 0xff; - } - } - } - - if (is_cck_rate) { - pstats->SignalStrength = precord_stats->SignalStrength = - _rtl92e_signal_scale_mapping(priv, - (long)pwdb_all); - - } else { - if (rf_rx_num != 0) - pstats->SignalStrength = precord_stats->SignalStrength = - _rtl92e_signal_scale_mapping(priv, - (long)(total_rssi /= rf_rx_num)); - } -} - -static void _rtl92e_process_phyinfo(struct r8192_priv *priv, u8 *buffer, - struct rtllib_rx_stats *prev_st, - struct rtllib_rx_stats *curr_st) -{ - bool bcheck = false; - u8 rfpath; - u32 ij, tmp_val; - static u32 slide_rssi_index, slide_rssi_statistics; - static u32 slide_evm_index, slide_evm_statistics; - static u32 last_rssi, last_evm; - static u32 slide_beacon_adc_pwdb_index; - static u32 slide_beacon_adc_pwdb_statistics; - static u32 last_beacon_adc_pwdb; - - if (!prev_st->bIsAMPDU) - bcheck = true; - - if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { - slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; - last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; - priv->stats.slide_rssi_total -= last_rssi; - } - priv->stats.slide_rssi_total += prev_st->SignalStrength; - - priv->stats.slide_signal_strength[slide_rssi_index++] = - prev_st->SignalStrength; - if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) - slide_rssi_index = 0; - - tmp_val = priv->stats.slide_rssi_total / slide_rssi_statistics; - priv->stats.signal_strength = rtl92e_translate_to_dbm(priv, tmp_val); - curr_st->rssi = priv->stats.signal_strength; - if (!prev_st->bPacketMatchBSSID) { - if (!prev_st->bToSelfBA) - return; - } - - if (!bcheck) - return; - - if (!prev_st->bIsCCK && prev_st->bPacketToSelf) { - for (rfpath = RF90_PATH_A; rfpath < priv->num_total_rf_path; rfpath++) { - if (priv->stats.rx_rssi_percentage[rfpath] == 0) { - priv->stats.rx_rssi_percentage[rfpath] = - prev_st->RxMIMOSignalStrength[rfpath]; - } - if (prev_st->RxMIMOSignalStrength[rfpath] > - priv->stats.rx_rssi_percentage[rfpath]) { - priv->stats.rx_rssi_percentage[rfpath] = - ((priv->stats.rx_rssi_percentage[rfpath] - * (RX_SMOOTH - 1)) + - (prev_st->RxMIMOSignalStrength - [rfpath])) / (RX_SMOOTH); - priv->stats.rx_rssi_percentage[rfpath] = - priv->stats.rx_rssi_percentage[rfpath] - + 1; - } else { - priv->stats.rx_rssi_percentage[rfpath] = - ((priv->stats.rx_rssi_percentage[rfpath] * - (RX_SMOOTH - 1)) + - (prev_st->RxMIMOSignalStrength[rfpath])) / - (RX_SMOOTH); - } - } - } - - if (prev_st->bPacketBeacon) { - if (slide_beacon_adc_pwdb_statistics++ >= - PHY_Beacon_RSSI_SLID_WIN_MAX) { - slide_beacon_adc_pwdb_statistics = - PHY_Beacon_RSSI_SLID_WIN_MAX; - last_beacon_adc_pwdb = priv->stats.slide_beacon_pwdb - [slide_beacon_adc_pwdb_index]; - priv->stats.slide_beacon_total -= last_beacon_adc_pwdb; - } - priv->stats.slide_beacon_total += prev_st->RxPWDBAll; - priv->stats.slide_beacon_pwdb[slide_beacon_adc_pwdb_index] = - prev_st->RxPWDBAll; - slide_beacon_adc_pwdb_index++; - if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) - slide_beacon_adc_pwdb_index = 0; - prev_st->RxPWDBAll = priv->stats.slide_beacon_total / - slide_beacon_adc_pwdb_statistics; - if (prev_st->RxPWDBAll >= 3) - prev_st->RxPWDBAll -= 3; - } - if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || - prev_st->bToSelfBA) { - if (priv->undecorated_smoothed_pwdb < 0) - priv->undecorated_smoothed_pwdb = prev_st->RxPWDBAll; - if (prev_st->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) { - priv->undecorated_smoothed_pwdb = - (((priv->undecorated_smoothed_pwdb) * - (RX_SMOOTH - 1)) + - (prev_st->RxPWDBAll)) / (RX_SMOOTH); - priv->undecorated_smoothed_pwdb = - priv->undecorated_smoothed_pwdb + 1; - } else { - priv->undecorated_smoothed_pwdb = - (((priv->undecorated_smoothed_pwdb) * - (RX_SMOOTH - 1)) + - (prev_st->RxPWDBAll)) / (RX_SMOOTH); - } - rtl92e_update_rx_statistics(priv, prev_st); - } - - if (prev_st->SignalQuality != 0) { - if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || - prev_st->bToSelfBA) { - if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { - slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; - last_evm = - priv->stats.slide_evm[slide_evm_index]; - priv->stats.slide_evm_total -= last_evm; - } - - priv->stats.slide_evm_total += prev_st->SignalQuality; - - priv->stats.slide_evm[slide_evm_index++] = - prev_st->SignalQuality; - if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) - slide_evm_index = 0; - - tmp_val = priv->stats.slide_evm_total / - slide_evm_statistics; - priv->stats.last_signal_strength_inpercent = tmp_val; - } - - if (prev_st->bPacketToSelf || - prev_st->bPacketBeacon || - prev_st->bToSelfBA) { - for (ij = 0; ij < 2; ij++) { - if (prev_st->RxMIMOSignalQuality[ij] != -1) { - if (priv->stats.rx_evm_percentage[ij] == 0) - priv->stats.rx_evm_percentage[ij] = - prev_st->RxMIMOSignalQuality[ij]; - priv->stats.rx_evm_percentage[ij] = - ((priv->stats.rx_evm_percentage[ij] * - (RX_SMOOTH - 1)) + - (prev_st->RxMIMOSignalQuality[ij])) / - (RX_SMOOTH); - } - } - } - } -} - -static void _rtl92e_translate_rx_signal_stats(struct net_device *dev, - struct sk_buff *skb, - struct rtllib_rx_stats *pstats, - struct rx_desc *pdesc, - struct rx_fwinfo *pdrvinfo) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - bool bpacket_match_bssid, bpacket_toself; - bool bPacketBeacon = false; - struct ieee80211_hdr_3addr *hdr; - bool bToSelfBA = false; - static struct rtllib_rx_stats previous_stats; - u16 fc, type; - u8 *tmp_buf; - u8 *praddr; - - tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift; - - hdr = (struct ieee80211_hdr_3addr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - - bpacket_match_bssid = - ((type != RTLLIB_FTYPE_CTL) && - ether_addr_equal(priv->rtllib->current_network.bssid, - (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : - (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : - hdr->addr3) && - (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV)); - bpacket_toself = bpacket_match_bssid && /* check this */ - ether_addr_equal(praddr, priv->rtllib->dev->dev_addr); - if (ieee80211_is_beacon(hdr->frame_control)) - bPacketBeacon = true; - _rtl92e_process_phyinfo(priv, tmp_buf, &previous_stats, pstats); - _rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, - &previous_stats, bpacket_match_bssid, - bpacket_toself, bPacketBeacon, bToSelfBA); - rtl92e_copy_mpdu_stats(pstats, &previous_stats); -} - -static void _rtl92e_update_received_rate_histogram_stats( - struct net_device *dev, - struct rtllib_rx_stats *pstats) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - u32 rcvType = 1; - u32 rate_index; - - if (pstats->bCRC) - rcvType = 2; - else if (pstats->bICV) - rcvType = 3; - - switch (pstats->rate) { - case MGN_1M: - rate_index = 0; - break; - case MGN_2M: - rate_index = 1; - break; - case MGN_5_5M: - rate_index = 2; - break; - case MGN_11M: - rate_index = 3; - break; - case MGN_6M: - rate_index = 4; - break; - case MGN_9M: - rate_index = 5; - break; - case MGN_12M: - rate_index = 6; - break; - case MGN_18M: - rate_index = 7; - break; - case MGN_24M: - rate_index = 8; - break; - case MGN_36M: - rate_index = 9; - break; - case MGN_48M: - rate_index = 10; - break; - case MGN_54M: - rate_index = 11; - break; - case MGN_MCS0: - rate_index = 12; - break; - case MGN_MCS1: - rate_index = 13; - break; - case MGN_MCS2: - rate_index = 14; - break; - case MGN_MCS3: - rate_index = 15; - break; - case MGN_MCS4: - rate_index = 16; - break; - case MGN_MCS5: - rate_index = 17; - break; - case MGN_MCS6: - rate_index = 18; - break; - case MGN_MCS7: - rate_index = 19; - break; - case MGN_MCS8: - rate_index = 20; - break; - case MGN_MCS9: - rate_index = 21; - break; - case MGN_MCS10: - rate_index = 22; - break; - case MGN_MCS11: - rate_index = 23; - break; - case MGN_MCS12: - rate_index = 24; - break; - case MGN_MCS13: - rate_index = 25; - break; - case MGN_MCS14: - rate_index = 26; - break; - case MGN_MCS15: - rate_index = 27; - break; - default: - rate_index = 28; - break; - } - priv->stats.received_rate_histogram[0][rate_index]++; - priv->stats.received_rate_histogram[rcvType][rate_index]++; -} - -bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats, - struct rx_desc *pdesc, struct sk_buff *skb) -{ - struct rx_fwinfo *pDrvInfo = NULL; - - stats->bICV = pdesc->ICV; - stats->bCRC = pdesc->CRC32; - stats->bHwError = pdesc->CRC32 | pdesc->ICV; - - stats->Length = pdesc->Length; - if (stats->Length < 24) - stats->bHwError |= 1; - - if (stats->bHwError) - return false; - - stats->RxDrvInfoSize = pdesc->RxDrvInfoSize; - stats->RxBufShift = (pdesc->Shift) & 0x03; - stats->decrypted = !pdesc->SWDec; - - pDrvInfo = (struct rx_fwinfo *)(skb->data + stats->RxBufShift); - - stats->rate = _rtl92e_rate_hw_to_mgn((bool)pDrvInfo->RxHT, - pDrvInfo->RxRate); - - _rtl92e_update_received_rate_histogram_stats(dev, stats); - - stats->bIsAMPDU = (pDrvInfo->PartAggr == 1); - stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) && - (pDrvInfo->FirstAGGR == 1); - - stats->time_stamp_low = pDrvInfo->TSFL; - stats->time_stamp_high = rtl92e_readl(dev, TSFR + 4); - - _rtl92e_translate_rx_signal_stats(dev, skb, stats, pdesc, pDrvInfo); - skb_trim(skb, skb->len - S_CRC_LEN); - - return true; -} - -void rtl92e_stop_adapter(struct net_device *dev, bool reset) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int i; - u8 op_mode; - u8 u1bTmp; - u32 ulRegRead; - - op_mode = RT_OP_MODE_NO_LINK; - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_MEDIA_STATUS, &op_mode); - - if (!priv->rtllib->bSupportRemoteWakeUp) { - u1bTmp = 0x0; - rtl92e_writeb(dev, CMDR, u1bTmp); - } - - mdelay(20); - - if (!reset) { - mdelay(150); - - priv->hw_rf_off_action = 2; - - if (!priv->rtllib->bSupportRemoteWakeUp) { - rtl92e_set_rf_off(dev); - ulRegRead = rtl92e_readl(dev, CPU_GEN); - ulRegRead |= CPU_GEN_SYSTEM_RESET; - rtl92e_writel(dev, CPU_GEN, ulRegRead); - } else { - rtl92e_writel(dev, WFCRC0, 0xffffffff); - rtl92e_writel(dev, WFCRC1, 0xffffffff); - rtl92e_writel(dev, WFCRC2, 0xffffffff); - - rtl92e_writeb(dev, PMR, 0x5); - rtl92e_writeb(dev, MAC_BLK_CTRL, 0xa); - } - } - - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_purge(&priv->rtllib->skb_waitq[i]); - - skb_queue_purge(&priv->skb_queue); -} - -void rtl92e_update_ratr_table(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - u8 *pMcsRate = ieee->dot11ht_oper_rate_set; - u32 ratr_value = 0; - u16 rate_config = 0; - u8 rate_index = 0; - - rtl92e_config_rate(dev, &rate_config); - ratr_value = rate_config | *pMcsRate << 12; - switch (ieee->mode) { - case WIRELESS_MODE_B: - ratr_value &= 0x0000000F; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_G | WIRELESS_MODE_B: - ratr_value &= 0x00000FF7; - break; - case WIRELESS_MODE_N_24G: - ratr_value &= 0x000FF007; - break; - default: - break; - } - ratr_value &= 0x0FFFFFFF; - if (ieee->ht_info->cur_tx_bw40mhz && - ieee->ht_info->cur_short_gi_40mhz) - ratr_value |= 0x80000000; - else if (!ieee->ht_info->cur_tx_bw40mhz && - ieee->ht_info->cur_short_gi_20mhz) - ratr_value |= 0x80000000; - rtl92e_writel(dev, RATR0 + rate_index * 4, ratr_value); - rtl92e_writeb(dev, UFWP, 1); -} - -void -rtl92e_init_variables(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - strscpy(priv->nick, "rtl8192E", sizeof(priv->nick)); - - priv->rtllib->softmac_features = IEEE_SOFTMAC_SCAN | - IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | - IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE; - - priv->rtllib->tx_headroom = sizeof(struct tx_fwinfo_8190pci); - - priv->short_retry_limit = 0x30; - priv->long_retry_limit = 0x30; - - priv->receive_config = RCR_ADD3 | - RCR_AMF | RCR_ADF | - RCR_AICV | - RCR_AB | RCR_AM | RCR_APM | - RCR_AAP | ((u32)7 << RCR_MXDMA_OFFSET) | - ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT; - - priv->irq_mask[0] = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | - IMR_BEDOK | IMR_BKDOK | IMR_HCCADOK | - IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | - IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | - IMR_RDU | IMR_RXFOVW | IMR_TXFOVW | - IMR_TBDOK | IMR_TBDER); - - priv->bfirst_after_down = false; -} - -void rtl92e_irq_enable(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - priv->irq_enabled = 1; - - rtl92e_writel(dev, INTA_MASK, priv->irq_mask[0]); -} - -void rtl92e_irq_disable(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - rtl92e_writel(dev, INTA_MASK, 0); - - priv->irq_enabled = 0; -} - -void rtl92e_enable_rx(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - rtl92e_writel(dev, RDQDA, priv->rx_ring_dma); -} - -static const u32 TX_DESC_BASE[] = { - BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA -}; - -void rtl92e_enable_tx(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - u32 i; - - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - rtl92e_writel(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma); -} - -void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta) -{ - *p_inta = rtl92e_readl(dev, ISR); - rtl92e_writel(dev, ISR, *p_inta); -} - -bool rtl92e_is_rx_stuck(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u16 RegRxCounter = rtl92e_readw(dev, 0x130); - bool bStuck = false; - static u8 rx_chk_cnt; - u32 slot_index = 0, TotalRxStuckCount = 0; - u8 i; - u8 SilentResetRxSoltNum = 4; - - rx_chk_cnt++; - if (priv->undecorated_smoothed_pwdb >= (RATE_ADAPTIVE_TH_HIGH + 5)) { - rx_chk_cnt = 0; - } else if ((priv->undecorated_smoothed_pwdb < (RATE_ADAPTIVE_TH_HIGH + 5)) - && (((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) && - (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_40M)) - || ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) && - (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_20M)))) { - if (rx_chk_cnt < 2) - return bStuck; - rx_chk_cnt = 0; - } else if ((((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) && - (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_40M)) || - ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) && - (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_20M))) && - priv->undecorated_smoothed_pwdb >= VERY_LOW_RSSI) { - if (rx_chk_cnt < 4) - return bStuck; - rx_chk_cnt = 0; - } else { - if (rx_chk_cnt < 8) - return bStuck; - rx_chk_cnt = 0; - } - - - slot_index = (priv->silent_reset_rx_slot_index++) % SilentResetRxSoltNum; - - if (priv->rx_ctr == RegRxCounter) { - priv->silent_reset_rx_stuck_event[slot_index] = 1; - - for (i = 0; i < SilentResetRxSoltNum; i++) - TotalRxStuckCount += priv->silent_reset_rx_stuck_event[i]; - - if (TotalRxStuckCount == SilentResetRxSoltNum) { - bStuck = true; - for (i = 0; i < SilentResetRxSoltNum; i++) - TotalRxStuckCount += - priv->silent_reset_rx_stuck_event[i]; - } - } else { - priv->silent_reset_rx_stuck_event[slot_index] = 0; - } - - priv->rx_ctr = RegRxCounter; - - return bStuck; -} - -bool rtl92e_is_tx_stuck(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - bool bStuck = false; - u16 RegTxCounter = rtl92e_readw(dev, 0x128); - - if (priv->tx_counter == RegTxCounter) - bStuck = true; - - priv->tx_counter = RegTxCounter; - - return bStuck; -} - -bool rtl92e_get_nmode_support_by_sec(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - if (ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(priv->rtllib) & (SEC_ALG_WEP | - SEC_ALG_TKIP))) { - return false; - } else { - return true; - } -} - -bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - return ieee->half_wireless_n24g_mode; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h deleted file mode 100644 index 9d9c5051c7fe..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _RTL8192E_H -#define _RTL8192E_H - -#include "r8190P_def.h" - -bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev); -bool rtl92e_get_nmode_support_by_sec(struct net_device *dev); -bool rtl92e_is_tx_stuck(struct net_device *dev); -bool rtl92e_is_rx_stuck(struct net_device *dev); -void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta); -void rtl92e_enable_rx(struct net_device *dev); -void rtl92e_enable_tx(struct net_device *dev); -void rtl92e_init_variables(struct net_device *dev); -void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val); -void rtl92e_get_eeprom_size(struct net_device *dev); -bool rtl92e_start_adapter(struct net_device *dev); -void rtl92e_link_change(struct net_device *dev); -void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da, - bool write_into_reg); -void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, - struct cb_desc *cb_desc, struct sk_buff *skb); -void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, - struct cb_desc *cb_desc, struct sk_buff *skb); -bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats, - struct rx_desc *pdesc, struct sk_buff *skb); -void rtl92e_stop_adapter(struct net_device *dev, bool reset); -void rtl92e_update_ratr_table(struct net_device *dev); -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c deleted file mode 100644 index ddf998cf2041..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +++ /dev/null @@ -1,189 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_hw.h" -#include "table.h" -#include "r8192E_firmware.h" -#include "r8192E_cmdpkt.h" -#include - -static bool _rtl92e_wait_for_fw(struct net_device *dev, u32 mask, u32 timeout) -{ - unsigned long deadline = jiffies + msecs_to_jiffies(timeout); - - while (time_before(jiffies, deadline)) { - if (rtl92e_readl(dev, CPU_GEN) & mask) - return true; - mdelay(2); - } - return false; -} - -static bool _rtl92e_fw_boot_cpu(struct net_device *dev) -{ - u32 CPU_status = 0; - - if (!_rtl92e_wait_for_fw(dev, CPU_GEN_PUT_CODE_OK, 200)) { - netdev_err(dev, "Firmware download failed.\n"); - return false; - } - netdev_dbg(dev, "Download Firmware: Put code ok!\n"); - - CPU_status = rtl92e_readl(dev, CPU_GEN); - rtl92e_writeb(dev, CPU_GEN, (CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff); - mdelay(1); - - if (!_rtl92e_wait_for_fw(dev, CPU_GEN_BOOT_RDY, 200)) { - netdev_err(dev, "Firmware boot failed.\n"); - return false; - } - - netdev_dbg(dev, "Download Firmware: Boot ready!\n"); - - return true; -} - -static bool _rtl92e_fw_check_ready(struct net_device *dev, - u8 load_fw_status) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_firmware *pfirmware = priv->fw_info; - bool rt_status = true; - - switch (load_fw_status) { - case FW_INIT_STEP0_BOOT: - pfirmware->status = FW_STATUS_1_MOVE_BOOT_CODE; - break; - - case FW_INIT_STEP1_MAIN: - pfirmware->status = FW_STATUS_2_MOVE_MAIN_CODE; - - rt_status = _rtl92e_fw_boot_cpu(dev); - if (rt_status) - pfirmware->status = FW_STATUS_3_TURNON_CPU; - else - netdev_dbg(dev, "_rtl92e_fw_boot_cpu fail!\n"); - - break; - - case FW_INIT_STEP2_DATA: - pfirmware->status = FW_STATUS_4_MOVE_DATA_CODE; - mdelay(1); - - rt_status = _rtl92e_wait_for_fw(dev, CPU_GEN_FIRM_RDY, 20); - if (rt_status) - pfirmware->status = FW_STATUS_5_READY; - break; - default: - rt_status = false; - netdev_dbg(dev, "Unknown firmware status"); - break; - } - - return rt_status; -} - -static bool _rtl92e_fw_prepare(struct net_device *dev, struct rt_fw_blob *blob, - const char *name, u8 padding) -{ - const struct firmware *fw; - int rc, i; - bool ret = true; - - rc = request_firmware(&fw, name, &dev->dev); - if (rc < 0) - return false; - - if (round_up(fw->size, 4) > MAX_FW_SIZE - padding) { - netdev_err(dev, "Firmware image %s too big for the device.\n", - name); - ret = false; - goto out; - } - - if (padding) - memset(blob->data, 0, padding); - if (fw->size % 4) - memset(blob->data + padding + fw->size, 0, 4); - memcpy(blob->data + padding, fw->data, fw->size); - - blob->size = round_up(fw->size, 4) + padding; - - /* Swap endian - firmware is packaged in invalid endiannes*/ - for (i = padding; i < blob->size; i += 4) { - u32 *data = (u32 *)(blob->data + i); - *data = swab32p(data); - } -out: - release_firmware(fw); - return ret; -} - -bool rtl92e_init_fw(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - bool rt_status = true; - - u32 file_length = 0; - u8 *mapped_file = NULL; - u8 i = 0; - enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; - enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; - - struct rt_firmware *pfirmware = priv->fw_info; - - netdev_dbg(dev, " PlatformInitFirmware()==>\n"); - - if (pfirmware->status == FW_STATUS_0_INIT) { - rst_opt = OPT_SYSTEM_RESET; - starting_state = FW_INIT_STEP0_BOOT; - - } else if (pfirmware->status == FW_STATUS_5_READY) { - rst_opt = OPT_FIRMWARE_RESET; - starting_state = FW_INIT_STEP2_DATA; - } - - for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) { - if (rst_opt == OPT_SYSTEM_RESET) { - if (pfirmware->blobs[i].size == 0) { - const char *fw_name[3] = { - RTL8192E_BOOT_IMG_FW, - RTL8192E_MAIN_IMG_FW, - RTL8192E_DATA_IMG_FW - }; - int pad = 0; - - if (i == FW_INIT_STEP1_MAIN) - pad = 128; - - if (!_rtl92e_fw_prepare(dev, - &pfirmware->blobs[i], - fw_name[i], - pad)) - goto download_firmware_fail; - } - } - - mapped_file = pfirmware->blobs[i].data; - file_length = pfirmware->blobs[i].size; - - rt_status = rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_INIT, - mapped_file, file_length); - if (!rt_status) - goto download_firmware_fail; - - if (!_rtl92e_fw_check_ready(dev, i)) - goto download_firmware_fail; - } - - netdev_dbg(dev, "Firmware Download Success\n"); - return rt_status; - -download_firmware_fail: - netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__); - return false; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h deleted file mode 100644 index b9059abc901b..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef __INC_FIRMWARE_H -#define __INC_FIRMWARE_H - -#define RTL8192E_BOOT_IMG_FW "RTL8192E/boot.img" -#define RTL8192E_MAIN_IMG_FW "RTL8192E/main.img" -#define RTL8192E_DATA_IMG_FW "RTL8192E/data.img" - -enum firmware_init_step { - FW_INIT_STEP0_BOOT = 0, - FW_INIT_STEP1_MAIN = 1, - FW_INIT_STEP2_DATA = 2, -}; - -enum opt_rst_type { - OPT_SYSTEM_RESET = 0, - OPT_FIRMWARE_RESET = 1, -}; - -enum desc_packet_type { - DESC_PACKET_TYPE_INIT = 0, - DESC_PACKET_TYPE_NORMAL = 1, -}; - -enum firmware_status { - FW_STATUS_0_INIT = 0, - FW_STATUS_1_MOVE_BOOT_CODE = 1, - FW_STATUS_2_MOVE_MAIN_CODE = 2, - FW_STATUS_3_TURNON_CPU = 3, - FW_STATUS_4_MOVE_DATA_CODE = 4, - FW_STATUS_5_READY = 5, -}; - -#define MAX_FW_SIZE 64000 -struct rt_fw_blob { - u16 size; - u8 data[MAX_FW_SIZE]; -}; - -#define FW_BLOBS 3 -struct rt_firmware { - enum firmware_status status; - struct rt_fw_blob blobs[FW_BLOBS]; -}; - -bool rtl92e_init_fw(struct net_device *dev); -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h deleted file mode 100644 index 1b444529b59c..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h +++ /dev/null @@ -1,244 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef R8180_HW -#define R8180_HW - -enum baseband_config { - BB_CONFIG_PHY_REG = 0, - BB_CONFIG_AGC_TAB = 1, -}; - -#define RTL8190_EEPROM_ID 0x8129 -#define EEPROM_VID 0x02 -#define EEPROM_DID 0x04 -#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C - -#define EEPROM_Default_ThermalMeter 0x77 -#define EEPROM_Default_AntTxPowerDiff 0x0 -#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 -#define EEPROM_Default_TxPower 0x1010 -#define EEPROM_ICVersion_ChannelPlan 0x7C -#define EEPROM_Customer_ID 0x7B -#define EEPROM_RFInd_PowerDiff 0x28 - -#define EEPROM_ThermalMeter 0x29 -#define EEPROM_TxPwDiff_CrystalCap 0x2A -#define EEPROM_TxPwIndex_CCK 0x2C -#define EEPROM_TxPwIndex_OFDM_24G 0x3A - -#define EEPROM_CID_TOSHIBA 0x4 -#define EEPROM_CID_NetCore 0x5 -enum _RTL8192PCI_HW { - MAC0 = 0x000, - MAC4 = 0x004, - PCIF = 0x009, -#define MXDMA2_NO_LIMIT 0x7 - -#define MXDMA2_RX_SHIFT 4 -#define MXDMA2_TX_SHIFT 0 - PMR = 0x00c, - EPROM_CMD = 0x00e, - -#define EPROM_CMD_9356SEL BIT(4) -#define EPROM_CMD_OPERATING_MODE_SHIFT 6 -#define EPROM_CMD_NORMAL 0 -#define EPROM_CMD_PROGRAM 2 -#define EPROM_CS_BIT 3 -#define EPROM_CK_BIT 2 -#define EPROM_W_BIT 1 -#define EPROM_R_BIT 0 - - ANAPAR = 0x17, -#define BB_GLOBAL_RESET_BIT 0x1 - BB_GLOBAL_RESET = 0x020, - BSSIDR = 0x02E, - CMDR = 0x037, -#define CR_RE 0x08 -#define CR_TE 0x04 - SIFS = 0x03E, - RCR = 0x044, -#define RCR_ONLYERLPKT BIT(31) -#define RCR_CBSSID BIT(23) -#define RCR_ADD3 BIT(21) -#define RCR_AMF BIT(20) -#define RCR_ADF BIT(18) -#define RCR_AICV BIT(12) -#define RCR_AB BIT(3) -#define RCR_AM BIT(2) -#define RCR_APM BIT(1) -#define RCR_AAP BIT(0) -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 - SLOT_TIME = 0x049, - ACK_TIMEOUT = 0x04c, - EDCAPARA_BE = 0x050, - EDCAPARA_BK = 0x054, - EDCAPARA_VO = 0x058, - EDCAPARA_VI = 0x05C, -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - BCN_TCFG = 0x062, -#define BCN_TCFG_CW_SHIFT 8 -#define BCN_TCFG_IFS 0 - BCN_INTERVAL = 0x070, - ATIMWND = 0x072, - BCN_DRV_EARLY_INT = 0x074, - BCN_DMATIME = 0x076, - BCN_ERR_THRESH = 0x078, - RWCAM = 0x0A0, -#define TOTAL_CAM_ENTRY 32 - WCAMI = 0x0A4, - SECR = 0x0B0, -#define SCR_TxUseDK BIT(0) -#define SCR_RxUseDK BIT(1) -#define SCR_TxEncEnable BIT(2) -#define SCR_RxDecEnable BIT(3) -#define SCR_NoSKMC BIT(5) - SWREGULATOR = 0x0BD, - INTA_MASK = 0x0f4, -#define IMR_TBDOK BIT(27) -#define IMR_TBDER BIT(26) -#define IMR_TXFOVW BIT(15) -#define IMR_TIMEOUT0 BIT(14) -#define IMR_BcnInt BIT(13) -#define IMR_RXFOVW BIT(12) -#define IMR_RDU BIT(11) -#define IMR_RXCMDOK BIT(10) -#define IMR_BDOK BIT(9) -#define IMR_HIGHDOK BIT(8) -#define IMR_COMDOK BIT(7) -#define IMR_MGNTDOK BIT(6) -#define IMR_HCCADOK BIT(5) -#define IMR_BKDOK BIT(4) -#define IMR_BEDOK BIT(3) -#define IMR_VIDOK BIT(2) -#define IMR_VODOK BIT(1) -#define IMR_ROK BIT(0) - ISR = 0x0f8, - TP_POLL = 0x0fd, -#define TP_POLL_CQ BIT(5) - PSR = 0x0ff, - CPU_GEN = 0x100, -#define CPU_CCK_LOOPBACK 0x00030000 -#define CPU_GEN_SYSTEM_RESET 0x00000001 -#define CPU_GEN_FIRMWARE_RESET 0x00000008 -#define CPU_GEN_BOOT_RDY 0x00000010 -#define CPU_GEN_FIRM_RDY 0x00000020 -#define CPU_GEN_PUT_CODE_OK 0x00000080 -#define CPU_GEN_BB_RST 0x00000100 -#define CPU_GEN_PWR_STB_CPU 0x00000004 -#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF -#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 - ACM_HW_CTRL = 0x171, -#define ACM_HW_BEQ_EN BIT(1) -#define ACM_HW_VIQ_EN BIT(2) -#define ACM_HW_VOQ_EN BIT(3) - RQPN1 = 0x180, - RQPN2 = 0x184, - RQPN3 = 0x188, - QPNR = 0x1F0, - BQDA = 0x200, - HQDA = 0x204, - CQDA = 0x208, - MQDA = 0x20C, - HCCAQDA = 0x210, - VOQDA = 0x214, - VIQDA = 0x218, - BEQDA = 0x21C, - BKQDA = 0x220, - RDQDA = 0x228, - - WFCRC0 = 0x2f0, - WFCRC1 = 0x2f4, - WFCRC2 = 0x2f8, - - BW_OPMODE = 0x300, -#define BW_OPMODE_20MHZ BIT(2) - IC_VERRSION = 0x301, - MSR = 0x303, -#define MSR_LINK_MASK (BIT(1) | BIT(0)) -#define MSR_LINK_MANAGED 2 -#define MSR_LINK_ADHOC 1 -#define MSR_LINK_MASTER 3 - -#define MSR_NOLINK 0x00 -#define MSR_ADHOC 0x01 -#define MSR_INFRA 0x02 -#define MSR_AP 0x03 - - RETRY_LIMIT = 0x304, -#define RETRY_LIMIT_SHORT_SHIFT 8 -#define RETRY_LIMIT_LONG_SHIFT 0 - TSFR = 0x308, - RRSR = 0x310, -#define RRSR_SHORT_OFFSET 23 -#define RRSR_1M BIT(0) -#define RRSR_2M BIT(1) -#define RRSR_5_5M BIT(2) -#define RRSR_11M BIT(3) -#define RRSR_6M BIT(4) -#define RRSR_9M BIT(5) -#define RRSR_12M BIT(6) -#define RRSR_18M BIT(7) -#define RRSR_24M BIT(8) -#define RRSR_36M BIT(9) -#define RRSR_48M BIT(10) -#define RRSR_54M BIT(11) -#define BRSR_AckShortPmb BIT(23) - UFWP = 0x318, - RATR0 = 0x320, -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \ - RATR_24M | RATR_36M | RATR_48M | RATR_54M) -#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ - RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ - RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ - RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ - RATR_MCS14|RATR_MCS15) - - DRIVER_RSSI = 0x32c, - MCS_TXAGC = 0x340, - CCK_TXAGC = 0x348, - MAC_BLK_CTRL = 0x403, -}; - -#define GPI 0x108 - -#define ANAPAR_FOR_8192PCIE 0x17 - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c deleted file mode 100644 index 18b948d4d86d..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ /dev/null @@ -1,1109 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include -#include "rtl_core.h" -#include "r8192E_hw.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" -#include "r8192E_phy.h" -#include "rtl_dm.h" - -#include "table.h" - -/*************************Define local function prototype**********************/ - -static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset); -static void _rtl92e_phy_rf_fw_write(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset, - u32 Data); - -static u32 _rtl92e_calculate_bit_shift(u32 dwBitMask) -{ - if (!dwBitMask) - return 32; - return ffs(dwBitMask) - 1; -} - -void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask, - u32 dwData) -{ - u32 OriginalValue, BitShift, NewValue; - - if (dwBitMask != bMaskDWord) { - OriginalValue = rtl92e_readl(dev, dwRegAddr); - BitShift = _rtl92e_calculate_bit_shift(dwBitMask); - NewValue = (OriginalValue & ~dwBitMask) | (dwData << BitShift); - rtl92e_writel(dev, dwRegAddr, NewValue); - } else { - rtl92e_writel(dev, dwRegAddr, dwData); - } -} - -u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask) -{ - u32 OriginalValue, BitShift; - - OriginalValue = rtl92e_readl(dev, dwRegAddr); - BitShift = _rtl92e_calculate_bit_shift(dwBitMask); - - return (OriginalValue & dwBitMask) >> BitShift; -} - -static u32 _rtl92e_phy_rf_read(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 ret = 0; - u32 NewOffset = 0; - struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath]; - - Offset &= 0x3f; - - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0); - if (Offset >= 31) { - priv->rf_reg_0value[eRFPath] |= 0x140; - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - NewOffset = Offset - 30; - } else if (Offset >= 16) { - priv->rf_reg_0value[eRFPath] |= 0x100; - priv->rf_reg_0value[eRFPath] &= (~0x40); - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - NewOffset = Offset - 15; - } else { - NewOffset = Offset; - } - rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, - NewOffset); - rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); - rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - - mdelay(1); - - ret = rtl92e_get_bb_reg(dev, pPhyReg->rfLSSIReadBack, - bLSSIReadBackData); - - priv->rf_reg_0value[eRFPath] &= 0xebf; - - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3); - - return ret; -} - -static void _rtl92e_phy_rf_write(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset, - u32 Data) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 DataAndAddr = 0, NewOffset = 0; - struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath]; - - Offset &= 0x3f; - - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0); - - if (Offset >= 31) { - priv->rf_reg_0value[eRFPath] |= 0x140; - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - NewOffset = Offset - 30; - } else if (Offset >= 16) { - priv->rf_reg_0value[eRFPath] |= 0x100; - priv->rf_reg_0value[eRFPath] &= (~0x40); - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - NewOffset = Offset - 15; - } else { - NewOffset = Offset; - } - - DataAndAddr = (NewOffset & 0x3f) | (Data << 16); - - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); - - if (Offset == 0x0) - priv->rf_reg_0value[eRFPath] = Data; - - if (Offset != 0) { - priv->rf_reg_0value[eRFPath] &= 0xebf; - rtl92e_set_bb_reg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->rf_reg_0value[eRFPath] << 16)); - } - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3); -} - -void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, - u32 RegAddr, u32 BitMask, u32 Data) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 Original_Value, BitShift, New_Value; - - if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter) - return; - - if (priv->rf_mode == RF_OP_By_FW) { - if (BitMask != bMask12Bits) { - Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, - RegAddr); - BitShift = _rtl92e_calculate_bit_shift(BitMask); - New_Value = (Original_Value & ~BitMask) | (Data << BitShift); - - _rtl92e_phy_rf_fw_write(dev, eRFPath, RegAddr, - New_Value); - } else { - _rtl92e_phy_rf_fw_write(dev, eRFPath, RegAddr, Data); - } - udelay(200); - } else { - if (BitMask != bMask12Bits) { - Original_Value = _rtl92e_phy_rf_read(dev, eRFPath, - RegAddr); - BitShift = _rtl92e_calculate_bit_shift(BitMask); - New_Value = (Original_Value & ~BitMask) | (Data << BitShift); - - _rtl92e_phy_rf_write(dev, eRFPath, RegAddr, New_Value); - } else { - _rtl92e_phy_rf_write(dev, eRFPath, RegAddr, Data); - } - } -} - -u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, - u32 RegAddr, u32 BitMask) -{ - u32 Original_Value, Readback_Value, BitShift; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter) - return 0; - mutex_lock(&priv->rf_mutex); - if (priv->rf_mode == RF_OP_By_FW) { - Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, RegAddr); - udelay(200); - } else { - Original_Value = _rtl92e_phy_rf_read(dev, eRFPath, RegAddr); - } - BitShift = _rtl92e_calculate_bit_shift(BitMask); - Readback_Value = (Original_Value & BitMask) >> BitShift; - mutex_unlock(&priv->rf_mutex); - return Readback_Value; -} - -static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset) -{ - u32 Data = 0; - u8 time = 0; - - Data |= ((Offset & 0xFF) << 12); - Data |= ((eRFPath & 0x3) << 20); - Data |= 0x80000000; - while (rtl92e_readl(dev, QPNR) & 0x80000000) { - if (time++ < 100) - udelay(10); - else - break; - } - rtl92e_writel(dev, QPNR, Data); - while (rtl92e_readl(dev, QPNR) & 0x80000000) { - if (time++ < 100) - udelay(10); - else - return 0; - } - return rtl92e_readl(dev, RF_DATA); -} - -static void _rtl92e_phy_rf_fw_write(struct net_device *dev, - enum rf90_radio_path eRFPath, u32 Offset, - u32 Data) -{ - u8 time = 0; - - Data |= ((Offset & 0xFF) << 12); - Data |= ((eRFPath & 0x3) << 20); - Data |= 0x400000; - Data |= 0x80000000; - - while (rtl92e_readl(dev, QPNR) & 0x80000000) { - if (time++ < 100) - udelay(10); - else - break; - } - rtl92e_writel(dev, QPNR, Data); -} - -void rtl92e_config_mac(struct net_device *dev) -{ - u32 dwArrayLen = 0, i = 0; - u32 *pdwArray = NULL; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->tx_pwr_data_read_from_eeprom) { - dwArrayLen = RTL8192E_MACPHY_ARR_PG_LEN; - pdwArray = RTL8192E_MACPHY_ARR_PG; - - } else { - dwArrayLen = RTL8192E_MACPHY_ARR_LEN; - pdwArray = RTL8192E_MACPHY_ARR; - } - for (i = 0; i < dwArrayLen; i += 3) { - if (pdwArray[i] == 0x318) - pdwArray[i + 2] = 0x00000800; - rtl92e_set_bb_reg(dev, pdwArray[i], pdwArray[i + 1], - pdwArray[i + 2]); - } -} - -static void _rtl92e_phy_config_bb(struct net_device *dev, u8 ConfigType) -{ - int i; - u32 *Rtl819XPHY_REGArray_Table = NULL; - u32 *Rtl819XAGCTAB_Array_Table = NULL; - u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0; - - AGCTAB_ArrayLen = RTL8192E_AGCTAB_ARR_LEN; - Rtl819XAGCTAB_Array_Table = RTL8192E_AGCTAB_ARR; - PHY_REGArrayLen = RTL8192E_PHY_REG_1T2R_ARR_LEN; - Rtl819XPHY_REGArray_Table = RTL8192E_PHY_REG_1T2R_ARR; - - if (ConfigType == BB_CONFIG_PHY_REG) { - for (i = 0; i < PHY_REGArrayLen; i += 2) { - rtl92e_set_bb_reg(dev, Rtl819XPHY_REGArray_Table[i], - bMaskDWord, - Rtl819XPHY_REGArray_Table[i + 1]); - } - } else if (ConfigType == BB_CONFIG_AGC_TAB) { - for (i = 0; i < AGCTAB_ArrayLen; i += 2) { - rtl92e_set_bb_reg(dev, Rtl819XAGCTAB_Array_Table[i], - bMaskDWord, - Rtl819XAGCTAB_Array_Table[i + 1]); - } - } -} - -static void _rtl92e_init_bb_rf_reg_def(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->phy_reg_def[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; - priv->phy_reg_def[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; - - priv->phy_reg_def[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; - priv->phy_reg_def[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; - - priv->phy_reg_def[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; - priv->phy_reg_def[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; - - priv->phy_reg_def[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; - priv->phy_reg_def[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; - - priv->phy_reg_def[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; - priv->phy_reg_def[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; - - priv->phy_reg_def[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; - priv->phy_reg_def[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; -} - -bool rtl92e_check_bb_and_rf(struct net_device *dev, enum hw90_block CheckBlock, - enum rf90_radio_path eRFPath) -{ - bool ret = true; - u32 i, CheckTimes = 4, dwRegRead = 0; - u32 WriteAddr[4]; - u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; - - WriteAddr[HW90_BLOCK_MAC] = 0x100; - WriteAddr[HW90_BLOCK_PHY0] = 0x900; - WriteAddr[HW90_BLOCK_PHY1] = 0x800; - WriteAddr[HW90_BLOCK_RF] = 0x3; - - if (CheckBlock == HW90_BLOCK_MAC) { - netdev_warn(dev, "%s(): No checks available for MAC block.\n", - __func__); - return ret; - } - - for (i = 0; i < CheckTimes; i++) { - switch (CheckBlock) { - case HW90_BLOCK_PHY0: - case HW90_BLOCK_PHY1: - rtl92e_writel(dev, WriteAddr[CheckBlock], - WriteData[i]); - dwRegRead = rtl92e_readl(dev, WriteAddr[CheckBlock]); - break; - - case HW90_BLOCK_RF: - WriteData[i] &= 0xfff; - rtl92e_set_rf_reg(dev, eRFPath, - WriteAddr[HW90_BLOCK_RF], - bMask12Bits, WriteData[i]); - mdelay(10); - dwRegRead = rtl92e_get_rf_reg(dev, eRFPath, - WriteAddr[HW90_BLOCK_RF], - bMaskDWord); - mdelay(10); - break; - - default: - ret = false; - break; - } - - if (dwRegRead != WriteData[i]) { - netdev_warn(dev, "%s(): Check failed.\n", __func__); - ret = false; - break; - } - } - - return ret; -} - -static bool _rtl92e_bb_config_para_file(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - bool rtStatus = true; - u8 bRegValue = 0, eCheckItem = 0; - u32 dwRegValue = 0; - - bRegValue = rtl92e_readb(dev, BB_GLOBAL_RESET); - rtl92e_writeb(dev, BB_GLOBAL_RESET, (bRegValue | BB_GLOBAL_RESET_BIT)); - - dwRegValue = rtl92e_readl(dev, CPU_GEN); - rtl92e_writel(dev, CPU_GEN, (dwRegValue & (~CPU_GEN_BB_RST))); - - for (eCheckItem = (enum hw90_block)HW90_BLOCK_PHY0; - eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) { - rtStatus = rtl92e_check_bb_and_rf(dev, - (enum hw90_block)eCheckItem, - (enum rf90_radio_path)0); - if (!rtStatus) - return rtStatus; - } - rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn | bOFDMEn, 0x0); - _rtl92e_phy_config_bb(dev, BB_CONFIG_PHY_REG); - - dwRegValue = rtl92e_readl(dev, CPU_GEN); - rtl92e_writel(dev, CPU_GEN, (dwRegValue | CPU_GEN_BB_RST)); - - _rtl92e_phy_config_bb(dev, BB_CONFIG_AGC_TAB); - - if (priv->ic_cut > VERSION_8190_BD) { - dwRegValue = 0x0; - rtl92e_set_bb_reg(dev, rFPGA0_TxGainStage, - (bXBTxAGC | bXCTxAGC | bXDTxAGC), dwRegValue); - - dwRegValue = priv->crystal_cap; - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, - dwRegValue); - } - - return rtStatus; -} -bool rtl92e_config_bb(struct net_device *dev) -{ - _rtl92e_init_bb_rf_reg_def(dev); - return _rtl92e_bb_config_para_file(dev); -} - -void rtl92e_get_tx_power(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->mcs_tx_pwr_level_org_offset[0] = - rtl92e_readl(dev, rTxAGC_Rate18_06); - priv->mcs_tx_pwr_level_org_offset[1] = - rtl92e_readl(dev, rTxAGC_Rate54_24); - priv->mcs_tx_pwr_level_org_offset[2] = - rtl92e_readl(dev, rTxAGC_Mcs03_Mcs00); - priv->mcs_tx_pwr_level_org_offset[3] = - rtl92e_readl(dev, rTxAGC_Mcs07_Mcs04); - priv->mcs_tx_pwr_level_org_offset[4] = - rtl92e_readl(dev, rTxAGC_Mcs11_Mcs08); - priv->mcs_tx_pwr_level_org_offset[5] = - rtl92e_readl(dev, rTxAGC_Mcs15_Mcs12); - - priv->def_initial_gain[0] = rtl92e_readb(dev, rOFDM0_XAAGCCore1); - priv->def_initial_gain[1] = rtl92e_readb(dev, rOFDM0_XBAGCCore1); - priv->def_initial_gain[2] = rtl92e_readb(dev, rOFDM0_XCAGCCore1); - priv->def_initial_gain[3] = rtl92e_readb(dev, rOFDM0_XDAGCCore1); - - priv->framesync = rtl92e_readb(dev, rOFDM0_RxDetector3); -} - -void rtl92e_set_tx_power(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 powerlevel = 0, powerlevelOFDM24G = 0; - - if (priv->epromtype == EEPROM_93C46) { - powerlevel = priv->tx_pwr_level_cck[channel - 1]; - powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1]; - } - - rtl92e_set_cck_tx_power(dev, powerlevel); - rtl92e_set_ofdm_tx_power(dev, powerlevelOFDM24G); -} - -u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath) -{ - int i; - - switch (eRFPath) { - case RF90_PATH_A: - for (i = 0; i < RTL8192E_RADIO_A_ARR_LEN; i += 2) { - if (RTL8192E_RADIO_A_ARR[i] == 0xfe) { - msleep(100); - continue; - } - rtl92e_set_rf_reg(dev, eRFPath, RTL8192E_RADIO_A_ARR[i], - bMask12Bits, - RTL8192E_RADIO_A_ARR[i + 1]); - } - break; - case RF90_PATH_B: - for (i = 0; i < RTL8192E_RADIO_B_ARR_LEN; i += 2) { - if (RTL8192E_RADIO_B_ARR[i] == 0xfe) { - msleep(100); - continue; - } - rtl92e_set_rf_reg(dev, eRFPath, RTL8192E_RADIO_B_ARR[i], - bMask12Bits, - RTL8192E_RADIO_B_ARR[i + 1]); - } - break; - default: - break; - } - - return 0; -} - -static void _rtl92e_set_tx_power_level(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 powerlevel = priv->tx_pwr_level_cck[channel - 1]; - u8 powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1]; - - rtl92e_set_cck_tx_power(dev, powerlevel); - rtl92e_set_ofdm_tx_power(dev, powerlevelOFDM24G); -} - -static u8 _rtl92e_phy_set_sw_chnl_cmd_array(struct net_device *dev, - struct sw_chnl_cmd *CmdTable, - u32 CmdTableIdx, u32 CmdTableSz, - enum sw_chnl_cmd_id CmdID, - u32 Para1, u32 Para2, u32 msDelay) -{ - struct sw_chnl_cmd *pCmd; - - if (!CmdTable) { - netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__); - return false; - } - if (CmdTableIdx >= CmdTableSz) { - netdev_err(dev, "%s(): Invalid index requested.\n", __func__); - return false; - } - - pCmd = CmdTable + CmdTableIdx; - pCmd->CmdID = CmdID; - pCmd->Para1 = Para1; - pCmd->Para2 = Para2; - pCmd->msDelay = msDelay; - - return true; -} - -static u8 _rtl92e_phy_switch_channel_step(struct net_device *dev, u8 channel, - u8 *stage, u8 *step, u32 *delay) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - u32 PreCommonCmdCnt; - u32 PostCommonCmdCnt; - u32 RfDependCmdCnt; - struct sw_chnl_cmd *CurrentCmd = NULL; - u8 eRFPath; - - if (!rtllib_legal_channel(priv->rtllib, channel)) { - netdev_err(dev, "Invalid channel requested: %d\n", channel); - return true; - } - - { - PreCommonCmdCnt = 0; - _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PreCommonCmd, - PreCommonCmdCnt++, - MAX_PRECMD_CNT, - CmdID_SetTxPowerLevel, - 0, 0, 0); - _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PreCommonCmd, - PreCommonCmdCnt++, - MAX_PRECMD_CNT, CmdID_End, - 0, 0, 0); - - PostCommonCmdCnt = 0; - - _rtl92e_phy_set_sw_chnl_cmd_array(dev, ieee->PostCommonCmd, - PostCommonCmdCnt++, - MAX_POSTCMD_CNT, CmdID_End, - 0, 0, 0); - - RfDependCmdCnt = 0; - - if (!(channel >= 1 && channel <= 14)) { - netdev_err(dev, - "Invalid channel requested for 8256: %d\n", - channel); - return false; - } - _rtl92e_phy_set_sw_chnl_cmd_array(dev, - ieee->RfDependCmd, - RfDependCmdCnt++, - MAX_RFDEPENDCMD_CNT, - CmdID_RF_WriteReg, - rZebra1_Channel, - channel, 10); - _rtl92e_phy_set_sw_chnl_cmd_array(dev, - ieee->RfDependCmd, - RfDependCmdCnt++, - MAX_RFDEPENDCMD_CNT, - CmdID_End, 0, 0, 0); - - do { - switch (*stage) { - case 0: - CurrentCmd = &ieee->PreCommonCmd[*step]; - break; - case 1: - CurrentCmd = &ieee->RfDependCmd[*step]; - break; - case 2: - CurrentCmd = &ieee->PostCommonCmd[*step]; - break; - } - - if (CurrentCmd && CurrentCmd->CmdID == CmdID_End) { - if ((*stage) == 2) - return true; - (*stage)++; - (*step) = 0; - continue; - } - - if (!CurrentCmd) - continue; - switch (CurrentCmd->CmdID) { - case CmdID_SetTxPowerLevel: - if (priv->ic_cut > VERSION_8190_BD) - _rtl92e_set_tx_power_level(dev, - channel); - break; - case CmdID_WritePortUlong: - rtl92e_writel(dev, CurrentCmd->Para1, - CurrentCmd->Para2); - break; - case CmdID_WritePortUshort: - rtl92e_writew(dev, CurrentCmd->Para1, - CurrentCmd->Para2); - break; - case CmdID_WritePortUchar: - rtl92e_writeb(dev, CurrentCmd->Para1, - CurrentCmd->Para2); - break; - case CmdID_RF_WriteReg: - for (eRFPath = 0; eRFPath < - priv->num_total_rf_path; eRFPath++) - rtl92e_set_rf_reg(dev, - (enum rf90_radio_path)eRFPath, - CurrentCmd->Para1, bMask12Bits, - CurrentCmd->Para2 << 7); - break; - default: - break; - } - - break; - } while (true); - } /*for (Number of RF paths)*/ - - (*delay) = CurrentCmd->msDelay; - (*step)++; - return false; -} - -static void _rtl92e_phy_switch_channel(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 delay = 0; - - while (!_rtl92e_phy_switch_channel_step(dev, channel, - &priv->sw_chnl_stage, - &priv->sw_chnl_step, &delay)) { - if (delay > 0) - msleep(delay); - if (!priv->up) - break; - } -} - -static void _rtl92e_phy_switch_channel_work_item(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - _rtl92e_phy_switch_channel(dev, priv->chan); -} - -void rtl92e_set_channel(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (!priv->up) { - netdev_err(dev, "%s(): Driver is not initialized\n", __func__); - return; - } - if (priv->sw_chnl_in_progress) - return; - - switch (priv->rtllib->mode) { - case WIRELESS_MODE_B: - if (channel > 14) { - netdev_warn(dev, - "Channel %d not available in 802.11b.\n", - channel); - return; - } - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - if (channel > 14) { - netdev_warn(dev, - "Channel %d not available in 802.11g.\n", - channel); - return; - } - break; - } - - priv->sw_chnl_in_progress = true; - if (channel == 0) - channel = 1; - - priv->chan = channel; - - priv->sw_chnl_stage = 0; - priv->sw_chnl_step = 0; - - if (priv->up) - _rtl92e_phy_switch_channel_work_item(dev); - priv->sw_chnl_in_progress = false; -} - -static void _rtl92e_cck_tx_power_track_bw_switch_tssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - switch (priv->current_chnl_bw) { - case HT_CHANNEL_WIDTH_20: - priv->cck_present_attn = - priv->cck_present_attn_20m_def + - priv->cck_present_attn_diff; - - if (priv->cck_present_attn > - (CCK_TX_BB_GAIN_TABLE_LEN - 1)) - priv->cck_present_attn = - CCK_TX_BB_GAIN_TABLE_LEN - 1; - if (priv->cck_present_attn < 0) - priv->cck_present_attn = 0; - - if (priv->rtllib->current_network.channel == 14 && - !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->rtllib->current_network.channel != - 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else { - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - break; - - case HT_CHANNEL_WIDTH_20_40: - priv->cck_present_attn = - priv->cck_present_attn_40m_def + - priv->cck_present_attn_diff; - - if (priv->cck_present_attn > - (CCK_TX_BB_GAIN_TABLE_LEN - 1)) - priv->cck_present_attn = - CCK_TX_BB_GAIN_TABLE_LEN - 1; - if (priv->cck_present_attn < 0) - priv->cck_present_attn = 0; - - if (priv->rtllib->current_network.channel == 14 && - !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->rtllib->current_network.channel != 14 - && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else { - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - break; - } -} - -static void _rtl92e_cck_tx_power_track_bw_switch_thermal(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->rtllib->current_network.channel == 14 && - !priv->bcck_in_ch14) - priv->bcck_in_ch14 = true; - else if (priv->rtllib->current_network.channel != 14 && - priv->bcck_in_ch14) - priv->bcck_in_ch14 = false; - - switch (priv->current_chnl_bw) { - case HT_CHANNEL_WIDTH_20: - if (priv->rec_cck_20m_idx == 0) - priv->rec_cck_20m_idx = 6; - priv->cck_index = priv->rec_cck_20m_idx; - break; - - case HT_CHANNEL_WIDTH_20_40: - priv->cck_index = priv->rec_cck_40m_idx; - break; - } - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); -} - -static void _rtl92e_cck_tx_power_track_bw_switch(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->ic_cut >= IC_VersionCut_D) - _rtl92e_cck_tx_power_track_bw_switch_tssi(dev); - else - _rtl92e_cck_tx_power_track_bw_switch_thermal(dev); -} - -static void _rtl92e_set_bw_mode_work_item(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 regBwOpMode; - - if (!priv->up) { - netdev_err(dev, "%s(): Driver is not initialized\n", __func__); - return; - } - regBwOpMode = rtl92e_readb(dev, BW_OPMODE); - - switch (priv->current_chnl_bw) { - case HT_CHANNEL_WIDTH_20: - regBwOpMode |= BW_OPMODE_20MHZ; - rtl92e_writeb(dev, BW_OPMODE, regBwOpMode); - break; - - case HT_CHANNEL_WIDTH_20_40: - regBwOpMode &= ~BW_OPMODE_20MHZ; - rtl92e_writeb(dev, BW_OPMODE, regBwOpMode); - break; - - default: - netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__, - priv->current_chnl_bw); - break; - } - - switch (priv->current_chnl_bw) { - case HT_CHANNEL_WIDTH_20: - rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); - rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); - - if (!priv->btxpower_tracking) { - rtl92e_writel(dev, rCCK0_TxFilter1, 0x1a1b0000); - rtl92e_writel(dev, rCCK0_TxFilter2, 0x090e1317); - rtl92e_writel(dev, rCCK0_DebugPort, 0x00000204); - } else { - _rtl92e_cck_tx_power_track_bw_switch(dev); - } - - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); - - break; - case HT_CHANNEL_WIDTH_20_40: - rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); - rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); - - if (!priv->btxpower_tracking) { - rtl92e_writel(dev, rCCK0_TxFilter1, 0x35360000); - rtl92e_writel(dev, rCCK0_TxFilter2, 0x121c252e); - rtl92e_writel(dev, rCCK0_DebugPort, 0x00000409); - } else { - _rtl92e_cck_tx_power_track_bw_switch(dev); - } - - rtl92e_set_bb_reg(dev, rCCK0_System, bCCKSideBand, - (priv->n_cur_40mhz_prime_sc >> 1)); - rtl92e_set_bb_reg(dev, rOFDM1_LSTF, 0xC00, - priv->n_cur_40mhz_prime_sc); - - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); - break; - default: - netdev_err(dev, "%s(): unknown Bandwidth: %#X\n", __func__, - priv->current_chnl_bw); - break; - } - - rtl92e_set_bandwidth(dev, priv->current_chnl_bw); - - atomic_dec(&(priv->rtllib->atm_swbw)); - priv->set_bw_mode_in_progress = false; -} - -void rtl92e_set_bw_mode(struct net_device *dev, enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->set_bw_mode_in_progress) - return; - - atomic_inc(&(priv->rtllib->atm_swbw)); - priv->set_bw_mode_in_progress = true; - - priv->current_chnl_bw = bandwidth; - - if (Offset == HT_EXTCHNL_OFFSET_LOWER) - priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_UPPER; - else if (Offset == HT_EXTCHNL_OFFSET_UPPER) - priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_LOWER; - else - priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - - _rtl92e_set_bw_mode_work_item(dev); -} - -void rtl92e_init_gain(struct net_device *dev, u8 Operation) -{ -#define SCAN_RX_INITIAL_GAIN 0x17 -#define POWER_DETECTION_TH 0x08 - struct r8192_priv *priv = rtllib_priv(dev); - u32 BitMask; - u8 initial_gain; - - if (priv->up) { - switch (Operation) { - case IG_Backup: - initial_gain = SCAN_RX_INITIAL_GAIN; - BitMask = bMaskByte0; - priv->initgain_backup.xaagccore1 = - rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, - BitMask); - priv->initgain_backup.xbagccore1 = - rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, - BitMask); - priv->initgain_backup.xcagccore1 = - rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, - BitMask); - priv->initgain_backup.xdagccore1 = - rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, - BitMask); - BitMask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, - rCCK0_CCA, BitMask); - - rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain); - rtl92e_writeb(dev, 0xa0a, POWER_DETECTION_TH); - break; - case IG_Restore: - BitMask = 0x7f; - rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask, - (u32)priv->initgain_backup.xaagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, BitMask, - (u32)priv->initgain_backup.xbagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, BitMask, - (u32)priv->initgain_backup.xcagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, BitMask, - (u32)priv->initgain_backup.xdagccore1); - BitMask = bMaskByte2; - rtl92e_set_bb_reg(dev, rCCK0_CCA, BitMask, - (u32)priv->initgain_backup.cca); - - rtl92e_set_tx_power(dev, - priv->rtllib->current_network.channel); - break; - } - } -} - -void rtl92e_set_rf_off(struct net_device *dev) -{ - rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4), 0x0); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); - rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0); - rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0); - rtl92e_writeb(dev, ANAPAR_FOR_8192PCIE, 0x07); -} - -static bool _rtl92e_set_rf_power_state(struct net_device *dev, - enum rt_rf_power_state rf_power_state) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - bool bResult = true; - u8 i = 0, QueueID = 0; - struct rtl8192_tx_ring *ring = NULL; - - if (priv->set_rf_pwr_state_in_progress) - return false; - priv->set_rf_pwr_state_in_progress = true; - - switch (rf_power_state) { - case rf_on: - if ((priv->rtllib->rf_power_state == rf_off) && - RT_IN_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC)) { - bool rtstatus; - u32 InitilizeCount = 3; - - do { - InitilizeCount--; - rtstatus = rtl92e_enable_nic(dev); - } while (!rtstatus && (InitilizeCount > 0)); - if (!rtstatus) { - netdev_err(dev, - "%s(): Failed to initialize Adapter.\n", - __func__); - priv->set_rf_pwr_state_in_progress = false; - return false; - } - RT_CLEAR_PS_LEVEL(psc, - RT_RF_OFF_LEVL_HALT_NIC); - } else { - rtl92e_writeb(dev, ANAPAR, 0x37); - mdelay(1); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, - 0x4, 0x1); - priv->hw_rf_off_action = 0; - rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, - BIT(4), 0x1); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, - 0x300, 0x3); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, - 0x18, 0x3); - rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, - 0x3, 0x3); - rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, - 0x3, 0x3); - rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, - 0x60, 0x3); - } - break; - case rf_sleep: - if (priv->rtllib->rf_power_state == rf_off) - break; - for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { - ring = &priv->tx_ring[QueueID]; - if (skb_queue_len(&ring->queue) == 0) { - QueueID++; - continue; - } else { - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) - break; - } - rtl92e_set_rf_off(dev); - break; - case rf_off: - for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { - ring = &priv->tx_ring[QueueID]; - if (skb_queue_len(&ring->queue) == 0) { - QueueID++; - continue; - } else { - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) - break; - } - rtl92e_set_rf_off(dev); - break; - default: - bResult = false; - netdev_warn(dev, - "%s(): Unknown state requested: 0x%X.\n", - __func__, rf_power_state); - break; - } - - if (bResult) - priv->rtllib->rf_power_state = rf_power_state; - - priv->set_rf_pwr_state_in_progress = false; - return bResult; -} - -bool rtl92e_set_rf_power_state(struct net_device *dev, - enum rt_rf_power_state rf_power_state) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - bool bResult = false; - - if (rf_power_state == priv->rtllib->rf_power_state && - priv->hw_rf_off_action == 0) { - return bResult; - } - - bResult = _rtl92e_set_rf_power_state(dev, rf_power_state); - return bResult; -} - -void rtl92e_scan_op_backup(struct net_device *dev, u8 Operation) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->up) { - switch (Operation) { - case SCAN_OPT_BACKUP: - priv->rtllib->init_gain_handler(dev, IG_Backup); - break; - - case SCAN_OPT_RESTORE: - priv->rtllib->init_gain_handler(dev, IG_Restore); - break; - } - } -} diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h deleted file mode 100644 index ff4b4004b0d0..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _R819XU_PHY_H -#define _R819XU_PHY_H - -#define MAX_DOZE_WAITING_TIMES_9x 64 - -enum hw90_block { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, -}; - -enum rf90_radio_path { - RF90_PATH_A = 0, - RF90_PATH_B = 1, - RF90_PATH_C = 2, - RF90_PATH_D = 3, - RF90_PATH_MAX -}; - -void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr, - u32 dwBitMask, u32 dwData); -u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask); -void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, - u32 RegAddr, u32 BitMask, u32 Data); -u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, - u32 RegAddr, u32 BitMask); -void rtl92e_config_mac(struct net_device *dev); -bool rtl92e_check_bb_and_rf(struct net_device *dev, - enum hw90_block CheckBlock, - enum rf90_radio_path eRFPath); -bool rtl92e_config_bb(struct net_device *dev); -void rtl92e_get_tx_power(struct net_device *dev); -void rtl92e_set_tx_power(struct net_device *dev, u8 channel); -u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath); - -void rtl92e_set_channel(struct net_device *dev, u8 channel); -void rtl92e_set_bw_mode(struct net_device *dev, - enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset); -void rtl92e_init_gain(struct net_device *dev, u8 Operation); - -void rtl92e_set_rf_off(struct net_device *dev); - -bool rtl92e_set_rf_power_state(struct net_device *dev, - enum rt_rf_power_state rf_power_state); - -void rtl92e_scan_op_backup(struct net_device *dev, u8 Operation); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h deleted file mode 100644 index c48c56869c19..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h +++ /dev/null @@ -1,773 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _R819XU_PHYREG_H -#define _R819XU_PHYREG_H - -#define RF_DATA 0x1d4 - -#define rPMAC_Reset 0x100 -#define rPMAC_TxStart 0x104 -#define rPMAC_TxLegacySIG 0x108 -#define rPMAC_TxHTSIG1 0x10c -#define rPMAC_TxHTSIG2 0x110 -#define rPMAC_PHYDebug 0x114 -#define rPMAC_TxPacketNum 0x118 -#define rPMAC_TxIdle 0x11c -#define rPMAC_TxMACHeader0 0x120 -#define rPMAC_TxMACHeader1 0x124 -#define rPMAC_TxMACHeader2 0x128 -#define rPMAC_TxMACHeader3 0x12c -#define rPMAC_TxMACHeader4 0x130 -#define rPMAC_TxMACHeader5 0x134 -#define rPMAC_TxDataType 0x138 -#define rPMAC_TxRandomSeed 0x13c -#define rPMAC_CCKPLCPPreamble 0x140 -#define rPMAC_CCKPLCPHeader 0x144 -#define rPMAC_CCKCRC16 0x148 -#define rPMAC_OFDMRxCRC32OK 0x170 -#define rPMAC_OFDMRxCRC32Er 0x174 -#define rPMAC_OFDMRxParityEr 0x178 -#define rPMAC_OFDMRxCRC8Er 0x17c -#define rPMAC_CCKCRxRC16Er 0x180 -#define rPMAC_CCKCRxRC32Er 0x184 -#define rPMAC_CCKCRxRC32OK 0x188 -#define rPMAC_TxStatus 0x18c - -#define MCS_TXAGC 0x340 -#define CCK_TXAGC 0x348 - -/* Mac block on/off control register */ -#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC */ -#define rFPGA0_TxInfo 0x804 -#define rFPGA0_PSDFunction 0x808 -#define rFPGA0_TxGainStage 0x80c -#define rFPGA0_RFTiming1 0x810 -#define rFPGA0_RFTiming2 0x814 -#define rFPGA0_XA_HSSIParameter2 0x824 -#define rFPGA0_XB_HSSIParameter2 0x82c -#define rFPGA0_XA_LSSIParameter 0x840 -#define rFPGA0_XB_LSSIParameter 0x844 -#define rFPGA0_RFWakeUpParameter 0x850 -#define rFPGA0_RFSleepUpParameter 0x854 -#define rFPGA0_XA_RFInterfaceOE 0x860 -#define rFPGA0_XB_RFInterfaceOE 0x864 -#define rFPGA0_XAB_RFInterfaceSW 0x870 -#define rFPGA0_AnalogParameter1 0x880 -#define rFPGA0_AnalogParameter2 0x884 -#define rFPGA0_AnalogParameter3 0x888 -#define rFPGA0_AnalogParameter4 0x88c -#define rFPGA0_XA_LSSIReadBack 0x8a0 -#define rFPGA0_XB_LSSIReadBack 0x8a4 -#define rFPGA0_PSDReport 0x8b4 - -/* Page 9 - RF mode & OFDM TxSC */ -#define rFPGA1_RFMOD 0x900 -#define rFPGA1_TxBlock 0x904 -#define rFPGA1_DebugSelect 0x908 -#define rFPGA1_TxInfo 0x90c - -#define rCCK0_System 0xa00 -#define rCCK0_AFESetting 0xa04 -#define rCCK0_CCA 0xa08 -/* AGC default value, saturation level */ -#define rCCK0_RxAGC1 0xa0c -#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ -#define rCCK0_RxHP 0xa14 -/* Timing recovery & channel estimation threshold */ -#define rCCK0_DSPParameter1 0xa18 -#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 /* Debug port and TX filter 3 */ -#define rCCK0_FalseAlarmReport 0xa2c -#define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 -#define rCCK0_FACounterLower 0xa5c -#define rCCK0_FACounterUpper 0xa58 - -#define rOFDM0_LSTF 0xc00 -#define rOFDM0_TRxPathEnable 0xc04 -#define rOFDM0_TRMuxPar 0xc08 -#define rOFDM0_TRSWIsolation 0xc0c -#define rOFDM0_RxDetector1 0xc30 /* PD, BW & SBD */ -#define rOFDM0_RxDetector2 0xc34 /* SBD */ -#define rOFDM0_RxDetector3 0xc38 /* Frame Sync */ -/* PD, SBD, Frame Sync & Short-GI */ -#define rOFDM0_RxDetector4 0xc3c -#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ -#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ -#define rOFDM0_CCADropThreshold 0xc48 -#define rOFDM0_ECCAThreshold 0xc4c /* Energy CCA */ -#define rOFDM0_XAAGCCore1 0xc50 -#define rOFDM0_XBAGCCore1 0xc58 -#define rOFDM0_XCAGCCore1 0xc60 -#define rOFDM0_XDAGCCore1 0xc68 -#define rOFDM0_AGCParameter1 0xc70 -#define rOFDM0_AGCParameter2 0xc74 -#define rOFDM0_AGCRSSITable 0xc78 -#define rOFDM0_HTSTFAGC 0xc7c -#define rOFDM0_XATxIQImbalance 0xc80 -#define rOFDM0_XATxAFE 0xc84 -#define rOFDM0_XCTxIQImbalance 0xc90 -#define rOFDM0_RxHPParameter 0xce0 -#define rOFDM0_TxPseudoNoiseWgt 0xce4 -#define rOFDM0_FrameSync 0xcf0 -#define rOFDM0_DFSReport 0xcf4 -#define rOFDM0_TxCoeff1 0xca4 -#define rOFDM0_TxCoeff2 0xca8 -#define rOFDM0_TxCoeff3 0xcac -#define rOFDM0_TxCoeff4 0xcb0 -#define rOFDM0_TxCoeff5 0xcb4 -#define rOFDM0_TxCoeff6 0xcb8 - -#define rOFDM1_LSTF 0xd00 -#define rOFDM1_TRxPathEnable 0xd04 -#define rOFDM1_CFO 0xd08 -#define rOFDM1_CSI1 0xd10 -#define rOFDM1_SBD 0xd14 -#define rOFDM1_CSI2 0xd18 -#define rOFDM1_CFOTracking 0xd2c -#define rOFDM1_TRxMesaure1 0xd34 -#define rOFDM1_IntfDet 0xd3c -#define rOFDM1_PseudoNoiseStateAB 0xd50 -#define rOFDM1_PseudoNoiseStateCD 0xd54 -#define rOFDM1_RxPseudoNoiseWgt 0xd58 -#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ -#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ -#define rOFDM_PHYCounter3 0xda8 /* MCS not supported */ -#define rOFDM_ShortCFOAB 0xdac -#define rOFDM_ShortCFOCD 0xdb0 -#define rOFDM_LongCFOAB 0xdb4 -#define rOFDM_LongCFOCD 0xdb8 -#define rOFDM_TailCFOAB 0xdbc -#define rOFDM_TailCFOCD 0xdc0 -#define rOFDM_PWMeasure1 0xdc4 -#define rOFDM_PWMeasure2 0xdc8 -#define rOFDM_BWReport 0xdcc -#define rOFDM_AGCReport 0xdd0 -#define rOFDM_RxSNR 0xdd4 -#define rOFDM_RxEVMCSI 0xdd8 -#define rOFDM_SIGReport 0xddc - -#define rTxAGC_Rate18_06 0xe00 -#define rTxAGC_Rate54_24 0xe04 -#define rTxAGC_CCK_Mcs32 0xe08 -#define rTxAGC_Mcs03_Mcs00 0xe10 -#define rTxAGC_Mcs07_Mcs04 0xe14 -#define rTxAGC_Mcs11_Mcs08 0xe18 -#define rTxAGC_Mcs15_Mcs12 0xe1c - -#define rZebra1_HSSIEnable 0x0 -#define rZebra1_TRxEnable1 0x1 -#define rZebra1_TRxEnable2 0x2 -#define rZebra1_AGC 0x4 -#define rZebra1_ChargePump 0x5 -#define rZebra1_Channel 0x7 -#define rZebra1_TxGain 0x8 -#define rZebra1_TxLPF 0x9 -#define rZebra1_RxLPF 0xb -#define rZebra1_RxHPFCorner 0xc - -/* Zebra 4 */ -#define rGlobalCtrl 0 -#define rRTL8256_TxLPF 19 -#define rRTL8256_RxLPF 11 - -/* RTL8258 */ -#define rRTL8258_TxLPF 0x11 -#define rRTL8258_RxLPF 0x13 -#define rRTL8258_RSSILPF 0xa - -/* Bit Mask - Page 1*/ -#define bBBResetB 0x100 -#define bGlobalResetB 0x200 -#define bOFDMTxStart 0x4 -#define bCCKTxStart 0x8 -#define bCRC32Debug 0x100 -#define bPMACLoopback 0x10 -#define bTxLSIG 0xffffff -#define bOFDMTxRate 0xf -#define bOFDMTxReserved 0x10 -#define bOFDMTxLength 0x1ffe0 -#define bOFDMTxParity 0x20000 -#define bTxHTSIG1 0xffffff -#define bTxHTMCSRate 0x7f -#define bTxHTBW 0x80 -#define bTxHTLength 0xffff00 -#define bTxHTSIG2 0xffffff -#define bTxHTSmoothing 0x1 -#define bTxHTSounding 0x2 -#define bTxHTReserved 0x4 -#define bTxHTAggreation 0x8 -#define bTxHTSTBC 0x30 -#define bTxHTAdvanceCoding 0x40 -#define bTxHTShortGI 0x80 -#define bTxHTNumberHT_LTF 0x300 -#define bTxHTCRC8 0x3fc00 -#define bCounterReset 0x10000 -#define bNumOfOFDMTx 0xffff -#define bNumOfCCKTx 0xffff0000 -#define bTxIdleInterval 0xffff -#define bOFDMService 0xffff0000 -#define bTxMACHeader 0xffffffff -#define bTxDataInit 0xff -#define bTxHTMode 0x100 -#define bTxDataType 0x30000 -#define bTxRandomSeed 0xffffffff -#define bCCKTxPreamble 0x1 -#define bCCKTxSFD 0xffff0000 -#define bCCKTxSIG 0xff -#define bCCKTxService 0xff00 -#define bCCKLengthExt 0x8000 -#define bCCKTxLength 0xffff0000 -#define bCCKTxCRC16 0xffff -#define bCCKTxStatus 0x1 -#define bOFDMTxStatus 0x2 -/* Bit Mask - Page 8 */ -#define bRFMOD 0x1 -#define bJapanMode 0x2 -#define bCCKTxSC 0x30 -#define bCCKEn 0x1000000 -#define bOFDMEn 0x2000000 -#define bOFDMRxADCPhase 0x10000 -#define bOFDMTxDACPhase 0x40000 -#define bXATxAGC 0x3f -#define bXBTxAGC 0xf00 -#define bXCTxAGC 0xf000 -#define bXDTxAGC 0xf0000 -#define bPAStart 0xf0000000 -#define bTRStart 0x00f00000 -#define bRFStart 0x0000f000 -#define bBBStart 0x000000f0 -#define bBBCCKStart 0x0000000f -/* Bit Mask - rFPGA0_RFTiming2 */ -#define bPAEnd 0xf -#define bTREnd 0x0f000000 -#define bRFEnd 0x000f0000 -/* Channel gain at continue TX. */ -#define b3WireDataLength 0x800 -#define b3WireAddressLength 0x400 -/* 3-wire total control */ -#define bRFSI_RFENV 0x10 -#define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */ -#define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */ -#define bLSSIReadBackData 0xfff - -#define bDA6Swing 0x380000 -#define bADClkPhase 0x4000000 -#define b80MClkDelay 0x18000000 -#define bAFEWatchDogEnable 0x20000000 -#define bXtalCap 0x0f000000 -#define bXtalCap01 0xc0000000 -#define bXtalCap23 0x3 -#define bXtalCap92x 0x0f000000 -#define bIntDifClkEnable 0x400 -#define bExtSigClkEnable 0x800 -#define bBandgapMbiasPowerUp 0x10000 -#define bAD11SHGain 0xc0000 -#define bAD11InputRange 0x700000 -#define bAD11OPCurrent 0x3800000 -#define bIPathLoopback 0x4000000 -#define bQPathLoopback 0x8000000 -#define bAFELoopback 0x10000000 -#define bDA10Swing 0x7e0 -#define bDA10Reverse 0x800 -#define bDAClkSource 0x1000 -#define bAD7InputRange 0x6000 -#define bAD7Gain 0x38000 -#define bAD7OutputCMMode 0x40000 -#define bAD7InputCMMode 0x380000 -#define bAD7Current 0xc00000 -#define bRegulatorAdjust 0x7000000 -#define bAD11PowerUpAtTx 0x1 -#define bDA10PSAtTx 0x10 -#define bAD11PowerUpAtRx 0x100 -#define bDA10PSAtRx 0x1000 - -#define bCCKRxAGCFormat 0x200 - -#define bPSDFFTSamplepPoint 0xc000 -#define bPSDAverageNum 0x3000 -#define bIQPathControl 0xc00 -#define bPSDFreq 0x3ff -#define bPSDAntennaPath 0x30 -#define bPSDIQSwitch 0x40 -#define bPSDRxTrigger 0x400000 -#define bPSDTxTrigger 0x80000000 -#define bPSDSineToneScale 0x7f000000 -#define bPSDReport 0xffff - -/* Page 8 */ -#define bOFDMTxSC 0x30000000 -#define bCCKTxOn 0x1 -#define bOFDMTxOn 0x2 -/* Reset debug page and also HWord, LWord */ -#define bDebugPage 0xfff -/* Reset debug page and LWord */ -#define bDebugItem 0xff -#define bAntL 0x10 -#define bAntNonHT 0x100 -#define bAntHT1 0x1000 -#define bAntHT2 0x10000 -#define bAntHT1S1 0x100000 -#define bAntNonHTS1 0x1000000 - -/* Page a */ -#define bCCKBBMode 0x3 -#define bCCKTxPowerSaving 0x80 -#define bCCKRxPowerSaving 0x40 -#define bCCKSideBand 0x10 -#define bCCKScramble 0x8 -#define bCCKAntDiversity 0x8000 -#define bCCKCarrierRecovery 0x4000 -#define bCCKTxRate 0x3000 -#define bCCKDCCancel 0x0800 -#define bCCKISICancel 0x0400 -#define bCCKMatchFilter 0x0200 -#define bCCKEqualizer 0x0100 -#define bCCKPreambleDetect 0x800000 -#define bCCKFastFalseCCA 0x400000 -#define bCCKChEstStart 0x300000 -#define bCCKCCACount 0x080000 -#define bCCKcs_lim 0x070000 -#define bCCKBistMode 0x80000000 -#define bCCKCCAMask 0x40000000 -#define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ -#define bCCKr_cp_mode0 0x0100 -#define bCCKTxDCOffset 0xf0 -#define bCCKRxDCOffset 0xf -#define bCCKCCAMode 0xc000 -#define bCCKFalseCS_lim 0x3f00 -#define bCCKCS_ratio 0xc00000 -#define bCCKCorgBit_sel 0x300000 -#define bCCKPD_lim 0x0f0000 -#define bCCKNewCCA 0x80000000 -#define bCCKRxHPofIG 0x8000 -#define bCCKRxIG 0x7f00 -#define bCCKLNAPolarity 0x800000 -#define bCCKRx1stGain 0x7f0000 -/* CCK Rx Initial gain polarity */ -#define bCCKRFExtend 0x20000000 -#define bCCKRxAGCSatLevel 0x1f000000 -#define bCCKRxAGCSatCount 0xe0 -/* AGCSAmp_dly */ -#define bCCKRxRFSettle 0x1f -#define bCCKFixedRxAGC 0x8000 -/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */ -#define bCCKAntennaPolarity 0x2000 -#define bCCKTxFilterType 0x0c00 -#define bCCKRxAGCReportType 0x0300 -#define bCCKRxDAGCEn 0x80000000 -#define bCCKRxDAGCPeriod 0x20000000 -#define bCCKRxDAGCSatLevel 0x1f000000 -#define bCCKTimingRecovery 0x800000 -#define bCCKTxC0 0x3f0000 -#define bCCKTxC1 0x3f000000 -#define bCCKTxC2 0x3f -#define bCCKTxC3 0x3f00 -#define bCCKTxC4 0x3f0000 -#define bCCKTxC5 0x3f000000 -#define bCCKTxC6 0x3f -#define bCCKTxC7 0x3f00 -#define bCCKDebugPort 0xff0000 -#define bCCKDACDebug 0x0f000000 -#define bCCKFalseAlarmEnable 0x8000 -#define bCCKFalseAlarmRead 0x4000 -#define bCCKTRSSI 0x7f -#define bCCKRxAGCReport 0xfe -#define bCCKRxReport_AntSel 0x80000000 -#define bCCKRxReport_MFOff 0x40000000 -#define bCCKRxRxReport_SQLoss 0x20000000 -#define bCCKRxReport_Pktloss 0x10000000 -#define bCCKRxReport_Lockedbit 0x08000000 -#define bCCKRxReport_RateError 0x04000000 -#define bCCKRxReport_RxRate 0x03000000 -#define bCCKRxFACounterLower 0xff -#define bCCKRxFACounterUpper 0xff000000 -#define bCCKRxHPAGCStart 0xe000 -#define bCCKRxHPAGCFinal 0x1c00 - -#define bCCKRxFalseAlarmEnable 0x8000 -#define bCCKFACounterFreeze 0x4000 - -#define bCCKTxPathSel 0x10000000 -#define bCCKDefaultRxPath 0xc000000 -#define bCCKOptionRxPath 0x3000000 - -/* Page c */ -#define bNumOfSTF 0x3 -#define bShift_L 0xc0 -#define bGI_TH 0xc -#define bRxPathA 0x1 -#define bRxPathB 0x2 -#define bRxPathC 0x4 -#define bRxPathD 0x8 -#define bTxPathA 0x1 -#define bTxPathB 0x2 -#define bTxPathC 0x4 -#define bTxPathD 0x8 -#define bTRSSIFreq 0x200 -#define bADCBackoff 0x3000 -#define bDFIRBackoff 0xc000 -#define bTRSSILatchPhase 0x10000 -#define bRxIDCOffset 0xff -#define bRxQDCOffset 0xff00 -#define bRxDFIRMode 0x1800000 -#define bRxDCNFType 0xe000000 -#define bRXIQImb_A 0x3ff -#define bRXIQImb_B 0xfc00 -#define bRXIQImb_C 0x3f0000 -#define bRXIQImb_D 0xffc00000 -#define bDC_dc_Notch 0x60000 -#define bRxNBINotch 0x1f000000 -#define bPD_TH 0xf -#define bPD_TH_Opt2 0xc000 -#define bPWED_TH 0x700 -#define bIfMF_Win_L 0x800 -#define bPD_Option 0x1000 -#define bMF_Win_L 0xe000 -#define bBW_Search_L 0x30000 -#define bwin_enh_L 0xc0000 -#define bBW_TH 0x700000 -#define bED_TH2 0x3800000 -#define bBW_option 0x4000000 -#define bRatio_TH 0x18000000 -#define bWindow_L 0xe0000000 -#define bSBD_Option 0x1 -#define bFrame_TH 0x1c -#define bFS_Option 0x60 -#define bDC_Slope_check 0x80 -#define bFGuard_Counter_DC_L 0xe00 -#define bFrame_Weight_Short 0x7000 -#define bSub_Tune 0xe00000 -#define bFrame_DC_Length 0xe000000 -#define bSBD_start_offset 0x30000000 -#define bFrame_TH_2 0x7 -#define bFrame_GI2_TH 0x38 -#define bGI2_Sync_en 0x40 -#define bSarch_Short_Early 0x300 -#define bSarch_Short_Late 0xc00 -#define bSarch_GI2_Late 0x70000 -#define bCFOAntSum 0x1 -#define bCFOAcc 0x2 -#define bCFOStartOffset 0xc -#define bCFOLookBack 0x70 -#define bCFOSumWeight 0x80 -#define bDAGCEnable 0x10000 -#define bTXIQImb_A 0x3ff -#define bTXIQImb_B 0xfc00 -#define bTXIQImb_C 0x3f0000 -#define bTXIQImb_D 0xffc00000 -#define bTxIDCOffset 0xff -#define bTxQDCOffset 0xff00 -#define bTxDFIRMode 0x10000 -#define bTxPesudoNoiseOn 0x4000000 -#define bTxPesudoNoise_A 0xff -#define bTxPesudoNoise_B 0xff00 -#define bTxPesudoNoise_C 0xff0000 -#define bTxPesudoNoise_D 0xff000000 -#define bCCADropOption 0x20000 -#define bCCADropThres 0xfff00000 -#define bEDCCA_H 0xf -#define bEDCCA_L 0xf0 -#define bLambda_ED 0x300 -#define bRxInitialGain 0x7f -#define bRxAntDivEn 0x80 -#define bRxAGCAddressForLNA 0x7f00 -#define bRxHighPowerFlow 0x8000 -#define bRxAGCFreezeThres 0xc0000 -#define bRxFreezeStep_AGC1 0x300000 -#define bRxFreezeStep_AGC2 0xc00000 -#define bRxFreezeStep_AGC3 0x3000000 -#define bRxFreezeStep_AGC0 0xc000000 -#define bRxRssi_Cmp_En 0x10000000 -#define bRxQuickAGCEn 0x20000000 -#define bRxAGCFreezeThresMode 0x40000000 -#define bRxOverFlowCheckType 0x80000000 -#define bRxAGCShift 0x7f -#define bTRSW_Tri_Only 0x80 -#define bPowerThres 0x300 -#define bRxAGCEn 0x1 -#define bRxAGCTogetherEn 0x2 -#define bRxAGCMin 0x4 -#define bRxHP_Ini 0x7 -#define bRxHP_TRLNA 0x70 -#define bRxHP_RSSI 0x700 -#define bRxHP_BBP1 0x7000 -#define bRxHP_BBP2 0x70000 -#define bRxHP_BBP3 0x700000 -/* The threshold for high power */ -#define bRSSI_H 0x7f0000 -/* The threshold for ant diversity */ -#define bRSSI_Gen 0x7f000000 -#define bRxSettle_TRSW 0x7 -#define bRxSettle_LNA 0x38 -#define bRxSettle_RSSI 0x1c0 -#define bRxSettle_BBP 0xe00 -#define bRxSettle_RxHP 0x7000 -#define bRxSettle_AntSW_RSSI 0x38000 -#define bRxSettle_AntSW 0xc0000 -#define bRxProcessTime_DAGC 0x300000 -#define bRxSettle_HSSI 0x400000 -#define bRxProcessTime_BBPPW 0x800000 -#define bRxAntennaPowerShift 0x3000000 -#define bRSSITableSelect 0xc000000 -#define bRxHP_Final 0x7000000 -#define bRxHTSettle_BBP 0x7 -#define bRxHTSettle_HSSI 0x8 -#define bRxHTSettle_RxHP 0x70 -#define bRxHTSettle_BBPPW 0x80 -#define bRxHTSettle_Idle 0x300 -#define bRxHTSettle_Reserved 0x1c00 -#define bRxHTRxHPEn 0x8000 -#define bRxHTAGCFreezeThres 0x30000 -#define bRxHTAGCTogetherEn 0x40000 -#define bRxHTAGCMin 0x80000 -#define bRxHTAGCEn 0x100000 -#define bRxHTDAGCEn 0x200000 -#define bRxHTRxHP_BBP 0x1c00000 -#define bRxHTRxHP_Final 0xe0000000 -#define bRxPWRatioTH 0x3 -#define bRxPWRatioEn 0x4 -#define bRxMFHold 0x3800 -#define bRxPD_Delay_TH1 0x38 -#define bRxPD_Delay_TH2 0x1c0 -#define bRxPD_DC_COUNT_MAX 0x600 -/*#define bRxMF_Hold 0x3800*/ -#define bRxPD_Delay_TH 0x8000 -#define bRxProcess_Delay 0xf0000 -#define bRxSearchrange_GI2_Early 0x700000 -#define bRxFrame_Guard_Counter_L 0x3800000 -#define bRxSGI_Guard_L 0xc000000 -#define bRxSGI_Search_L 0x30000000 -#define bRxSGI_TH 0xc0000000 -#define bDFSCnt0 0xff -#define bDFSCnt1 0xff00 -#define bDFSFlag 0xf0000 - -#define bMFWeightSum 0x300000 -#define bMinIdxTH 0x7f000000 - -#define bDAFormat 0x40000 - -#define bTxChEmuEnable 0x01000000 - -#define bTRSWIsolation_A 0x7f -#define bTRSWIsolation_B 0x7f00 -#define bTRSWIsolation_C 0x7f0000 -#define bTRSWIsolation_D 0x7f000000 - -#define bExtLNAGain 0x7c00 - -/* Page d */ -#define bSTBCEn 0x4 -#define bAntennaMapping 0x10 -#define bNss 0x20 -#define bCFOAntSumD 0x200 -#define bPHYCounterReset 0x8000000 -#define bCFOReportGet 0x4000000 -#define bOFDMContinueTx 0x10000000 -#define bOFDMSingleCarrier 0x20000000 -#define bOFDMSingleTone 0x40000000 -/* #define bRxPath1 0x01 - * #define bRxPath2 0x02 - * #define bRxPath3 0x04 - * #define bRxPath4 0x08 - * #define bTxPath1 0x10 - * #define bTxPath2 0x20 - */ -#define bHTDetect 0x100 -#define bCFOEn 0x10000 -#define bCFOValue 0xfff00000 -#define bSigTone_Re 0x3f -#define bSigTone_Im 0x7f00 -#define bCounter_CCA 0xffff -#define bCounter_ParityFail 0xffff0000 -#define bCounter_RateIllegal 0xffff -#define bCounter_CRC8Fail 0xffff0000 -#define bCounter_MCSNoSupport 0xffff -#define bCounter_FastSync 0xffff -#define bShortCFO 0xfff -#define bShortCFOTLength 12 /* total */ -#define bShortCFOFLength 11 /* fraction */ -#define bLongCFO 0x7ff -#define bLongCFOTLength 11 -#define bLongCFOFLength 11 -#define bTailCFO 0x1fff -#define bTailCFOTLength 13 -#define bTailCFOFLength 12 - -#define bmax_en_pwdB 0xffff -#define bCC_power_dB 0xffff0000 -#define bnoise_pwdB 0xffff -#define bPowerMeasTLength 10 -#define bPowerMeasFLength 3 -#define bRx_HT_BW 0x1 -#define bRxSC 0x6 -#define bRx_HT 0x8 - -#define bNB_intf_det_on 0x1 -#define bIntf_win_len_cfg 0x30 -#define bNB_Intf_TH_cfg 0x1c0 - -#define bRFGain 0x3f -#define bTableSel 0x40 -#define bTRSW 0x80 - -#define bRxSNR_A 0xff -#define bRxSNR_B 0xff00 -#define bRxSNR_C 0xff0000 -#define bRxSNR_D 0xff000000 -#define bSNREVMTLength 8 -#define bSNREVMFLength 1 - -#define bCSI1st 0xff -#define bCSI2nd 0xff00 -#define bRxEVM1st 0xff0000 -#define bRxEVM2nd 0xff000000 - -#define bSIGEVM 0xff -#define bPWDB 0xff00 -#define bSGIEN 0x10000 - -#define bSFactorQAM1 0xf -#define bSFactorQAM2 0xf0 -#define bSFactorQAM3 0xf00 -#define bSFactorQAM4 0xf000 -#define bSFactorQAM5 0xf0000 -#define bSFactorQAM6 0xf0000 -#define bSFactorQAM7 0xf00000 -#define bSFactorQAM8 0xf000000 -#define bSFactorQAM9 0xf0000000 -#define bCSIScheme 0x100000 - -#define bNoiseLvlTopSet 0x3 -#define bChSmooth 0x4 -#define bChSmoothCfg1 0x38 -#define bChSmoothCfg2 0x1c0 -#define bChSmoothCfg3 0xe00 -#define bChSmoothCfg4 0x7000 -#define bMRCMode 0x800000 -#define bTHEVMCfg 0x7000000 - -#define bLoopFitType 0x1 -#define bUpdCFO 0x40 -#define bUpdCFOOffData 0x80 -#define bAdvUpdCFO 0x100 -#define bAdvTimeCtrl 0x800 -#define bUpdClko 0x1000 -#define bFC 0x6000 -#define bTrackingMode 0x8000 -#define bPhCmpEnable 0x10000 -#define bUpdClkoLTF 0x20000 -#define bComChCFO 0x40000 -#define bCSIEstiMode 0x80000 -#define bAdvUpdEqz 0x100000 -#define bUChCfg 0x7000000 -#define bUpdEqz 0x8000000 - -/* Page e */ -#define bTxAGCRate18_06 0x7f7f7f7f -#define bTxAGCRate54_24 0x7f7f7f7f -#define bTxAGCRateMCS32 0x7f -#define bTxAGCRateCCK 0x7f00 -#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f -#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f -#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f -#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f - -#define bRxPesudoNoiseOn 0x20000000 /* Rx Pseduo noise */ -#define bRxPesudoNoise_A 0xff -#define bRxPesudoNoise_B 0xff00 -#define bRxPesudoNoise_C 0xff0000 -#define bRxPesudoNoise_D 0xff000000 -#define bPesudoNoiseState_A 0xffff -#define bPesudoNoiseState_B 0xffff0000 -#define bPesudoNoiseState_C 0xffff -#define bPesudoNoiseState_D 0xffff0000 - -/* RF Zebra 1 */ -#define bZebra1_HSSIEnable 0x8 -#define bZebra1_TRxControl 0xc00 -#define bZebra1_TRxGainSetting 0x07f -#define bZebra1_RxCorner 0xc00 -#define bZebra1_TxChargePump 0x38 -#define bZebra1_RxChargePump 0x7 -#define bZebra1_ChannelNum 0xf80 -#define bZebra1_TxLPFBW 0x400 -#define bZebra1_RxLPFBW 0x600 - -/* Zebra4 */ -#define bRTL8256RegModeCtrl1 0x100 -#define bRTL8256RegModeCtrl0 0x40 -#define bRTL8256_TxLPFBW 0x18 -#define bRTL8256_RxLPFBW 0x600 - -/* RTL8258 */ -#define bRTL8258_TxLPFBW 0xc -#define bRTL8258_RxLPFBW 0xc00 -#define bRTL8258_RSSILPFBW 0xc0 - -/* byte enable for sb_write */ -#define bByte0 0x1 -#define bByte1 0x2 -#define bByte2 0x4 -#define bByte3 0x8 -#define bWord0 0x3 -#define bWord1 0xc -#define bDWord 0xf - -/* for PutRegsetting & GetRegSetting BitMask */ -#define bMaskByte0 0xff -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -/* for PutRFRegsetting & GetRFRegSetting BitMask */ -#define bMask12Bits 0xfff - -#define bEnable 0x1 -#define bDisable 0x0 - -#define LeftAntenna 0x0 -#define RightAntenna 0x1 - -#define tCheckTxStatus 500 /* 500 ms */ -#define tUpdateRxCounter 100 /* 100 ms */ - -#define rateCCK 0 -#define rateOFDM 1 -#define rateHT 2 - -#define bPMAC_End 0x1ff /* define Register-End */ -#define bFPGAPHY0_End 0x8ff -#define bFPGAPHY1_End 0x9ff -#define bCCKPHY0_End 0xaff -#define bOFDMPHY0_End 0xcff -#define bOFDMPHY1_End 0xdff - -#define bPMACControl 0x0 -#define bWMACControl 0x1 -#define bWNICControl 0x2 - -#define PathA 0x0 -#define PathB 0x1 -#define PathC 0x2 -#define PathD 0x3 - -#define rRTL8256RxMixerPole 0xb -#define bZebraRxMixerPole 0x6 -#define rRTL8256TxBBOPBias 0x9 -#define bRTL8256TxBBOPBias 0x400 -#define rRTL8256TxBBBW 19 -#define bRTL8256TxBBBW 0x18 - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c deleted file mode 100644 index 69298c7c129a..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ -#include "r8192E_cmdpkt.h" - -void rtl92e_cam_reset(struct net_device *dev) -{ - u32 ulcommand = 0; - - ulcommand |= BIT(31) | BIT(30); - rtl92e_writel(dev, RWCAM, ulcommand); -} - -void rtl92e_enable_hw_security_config(struct net_device *dev) -{ - u8 SECR_value = 0x0; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; - if (((ieee->pairwise_key_type == KEY_TYPE_WEP40) || - (ieee->pairwise_key_type == KEY_TYPE_WEP104)) && - (priv->rtllib->auth_mode != 2)) { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } - - ieee->hwsec_active = 1; - if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { - ieee->hwsec_active = 0; - SECR_value &= ~SCR_RxDecEnable; - } - rtl92e_writeb(dev, SECR, SECR_value); -} - -void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, - u16 KeyType, const u8 *MacAddr, u32 *KeyContent) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - if (EntryNo >= TOTAL_CAM_ENTRY) - return; - - ieee->swcamtable[EntryNo].bused = true; - ieee->swcamtable[EntryNo].key_index = KeyIndex; - ieee->swcamtable[EntryNo].key_type = KeyType; - memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6); - ieee->swcamtable[EntryNo].useDK = 0; - memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16); -} - -void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, - u16 KeyType, const u8 *MacAddr, u8 DefaultKey, - u32 *KeyContent) -{ - u32 TargetCommand = 0; - u32 TargetContent = 0; - u16 usConfig = 0; - u8 i; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - enum rt_rf_power_state rt_state; - - rt_state = priv->rtllib->rf_power_state; - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - return; - } - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); - } - priv->rtllib->is_set_key = true; - if (EntryNo >= TOTAL_CAM_ENTRY) { - netdev_info(dev, "%s(): Invalid CAM entry\n", __func__); - return; - } - - if (DefaultKey) - usConfig |= BIT(15) | (KeyType << 2); - else - usConfig |= BIT(15) | (KeyType << 2) | KeyIndex; - - for (i = 0; i < CAM_CONTENT_COUNT; i++) { - TargetCommand = i + CAM_CONTENT_COUNT * EntryNo; - TargetCommand |= BIT(31) | BIT(16); - - if (i == 0) { - TargetContent = (u32)(*(MacAddr + 0)) << 16 | - (u32)(*(MacAddr + 1)) << 24 | - (u32)usConfig; - - rtl92e_writel(dev, WCAMI, TargetContent); - rtl92e_writel(dev, RWCAM, TargetCommand); - } else if (i == 1) { - TargetContent = (u32)(*(MacAddr + 2)) | - (u32)(*(MacAddr + 3)) << 8 | - (u32)(*(MacAddr + 4)) << 16 | - (u32)(*(MacAddr + 5)) << 24; - rtl92e_writel(dev, WCAMI, TargetContent); - rtl92e_writel(dev, RWCAM, TargetCommand); - } else { - if (KeyContent) { - rtl92e_writel(dev, WCAMI, - (u32)(*(KeyContent + i - 2))); - rtl92e_writel(dev, RWCAM, TargetCommand); - udelay(100); - } - } - } -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h deleted file mode 100644 index 9deffdf96072..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#ifndef _RTL_CAM_H -#define _RTL_CAM_H - -#include - -struct net_device; - -void rtl92e_cam_reset(struct net_device *dev); -void rtl92e_enable_hw_security_config(struct net_device *dev); -void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, - u16 KeyType, const u8 *MacAddr, u8 DefaultKey, - u32 *KeyContent); -void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, - u16 KeyType, const u8 *MacAddr, u32 *KeyContent); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c deleted file mode 100644 index 9eeae01dc98d..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ /dev/null @@ -1,2016 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include -#include -#include -#include -#include "rtl_core.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" -#include "r8192E_cmdpkt.h" - -#include "rtl_wx.h" -#include "rtl_dm.h" - -#include "rtl_pm.h" - -int hwwep = 1; -static char *ifname = "wlan%d"; - -static struct pci_device_id rtl8192_pci_id_tbl[] = { - {PCI_DEVICE(0x10ec, 0x8192)}, - {PCI_DEVICE(0x07aa, 0x0044)}, - {PCI_DEVICE(0x07aa, 0x0047)}, - {} -}; - -MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); - -static int _rtl92e_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); -static void _rtl92e_pci_disconnect(struct pci_dev *pdev); -static irqreturn_t _rtl92e_irq(int irq, void *netdev); - -static SIMPLE_DEV_PM_OPS(rtl92e_pm_ops, rtl92e_suspend, rtl92e_resume); - -static struct pci_driver rtl8192_pci_driver = { - .name = DRV_NAME, /* Driver name */ - .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ - .probe = _rtl92e_pci_probe, /* probe fn */ - .remove = _rtl92e_pci_disconnect, /* remove fn */ - .driver.pm = &rtl92e_pm_ops, -}; - -static short _rtl92e_is_tx_queue_empty(struct net_device *dev); -static void _rtl92e_watchdog_wq_cb(void *data); -static void _rtl92e_watchdog_timer_cb(struct timer_list *t); -static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, - int rate); -static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb); -static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb); -static short _rtl92e_pci_initdescring(struct net_device *dev); -static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t); -static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t); -static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv); -static int _rtl92e_up(struct net_device *dev); -static int _rtl92e_try_up(struct net_device *dev); -static int _rtl92e_down(struct net_device *dev, bool shutdownrf); -static void _rtl92e_restart(void *data); - -/**************************************************************************** - * -----------------------------IO STUFF------------------------- - ****************************************************************************/ - -u8 rtl92e_readb(struct net_device *dev, int x) -{ - return 0xff & readb((u8 __iomem *)dev->mem_start + x); -} - -u32 rtl92e_readl(struct net_device *dev, int x) -{ - return readl((u8 __iomem *)dev->mem_start + x); -} - -u16 rtl92e_readw(struct net_device *dev, int x) -{ - return readw((u8 __iomem *)dev->mem_start + x); -} - -void rtl92e_writeb(struct net_device *dev, int x, u8 y) -{ - writeb(y, (u8 __iomem *)dev->mem_start + x); - - udelay(20); -} - -void rtl92e_writel(struct net_device *dev, int x, u32 y) -{ - writel(y, (u8 __iomem *)dev->mem_start + x); - - udelay(20); -} - -void rtl92e_writew(struct net_device *dev, int x, u16 y) -{ - writew(y, (u8 __iomem *)dev->mem_start + x); - - udelay(20); -} - -/**************************************************************************** - * -----------------------------GENERAL FUNCTION------------------------- - ****************************************************************************/ -bool rtl92e_set_rf_state(struct net_device *dev, - enum rt_rf_power_state state_to_set, - RT_RF_CHANGE_SOURCE change_source) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - bool action_allowed = false; - bool connect_by_ssid = false; - enum rt_rf_power_state rt_state; - u16 rf_wait_counter = 0; - unsigned long flag; - - while (true) { - spin_lock_irqsave(&priv->rf_ps_lock, flag); - if (priv->rf_change_in_progress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - - while (priv->rf_change_in_progress) { - rf_wait_counter++; - mdelay(1); - - if (rf_wait_counter > 100) { - netdev_warn(dev, - "%s(): Timeout waiting for RF change.\n", - __func__); - return false; - } - } - } else { - priv->rf_change_in_progress = true; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - break; - } - } - - rt_state = priv->rtllib->rf_power_state; - - switch (state_to_set) { - case rf_on: - priv->rtllib->rf_off_reason &= (~change_source); - - if ((change_source == RF_CHANGE_BY_HW) && priv->hw_radio_off) - priv->hw_radio_off = false; - - if (!priv->rtllib->rf_off_reason) { - priv->rtllib->rf_off_reason = 0; - action_allowed = true; - - if (rt_state == rf_off && - change_source >= RF_CHANGE_BY_HW) - connect_by_ssid = true; - } - break; - - case rf_off: - - if (priv->rtllib->iw_mode == IW_MODE_INFRA) { - if ((priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) || - (change_source > RF_CHANGE_BY_IPS)) { - if (ieee->link_state == MAC80211_LINKED) - priv->blinked_ingpio = true; - else - priv->blinked_ingpio = false; - rtllib_mgnt_disconnect(priv->rtllib, - WLAN_REASON_DISASSOC_STA_HAS_LEFT); - } - } - if ((change_source == RF_CHANGE_BY_HW) && !priv->hw_radio_off) - priv->hw_radio_off = true; - priv->rtllib->rf_off_reason |= change_source; - action_allowed = true; - break; - - case rf_sleep: - priv->rtllib->rf_off_reason |= change_source; - action_allowed = true; - break; - - default: - break; - } - - if (action_allowed) { - rtl92e_set_rf_power_state(dev, state_to_set); - if (state_to_set == rf_on) { - if (connect_by_ssid && priv->blinked_ingpio) { - schedule_delayed_work( - &ieee->associate_procedure_wq, 0); - priv->blinked_ingpio = false; - } - } - } - - spin_lock_irqsave(&priv->rf_ps_lock, flag); - priv->rf_change_in_progress = false; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - return action_allowed; -} - -static short _rtl92e_check_nic_enough_desc(struct net_device *dev, int prio) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - if (ring->entries - skb_queue_len(&ring->queue) >= 2) - return 1; - return 0; -} - -static void _rtl92e_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - schedule_work(&priv->reset_wq); - netdev_info(dev, "TXTIMEOUT"); -} - -static void _rtl92e_update_cap(struct net_device *dev, u16 cap) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_network *net = &priv->rtllib->current_network; - bool ShortPreamble; - - if (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) { - if (priv->dot11_current_preamble_mode != PREAMBLE_SHORT) { - ShortPreamble = true; - priv->dot11_current_preamble_mode = PREAMBLE_SHORT; - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACK_PREAMBLE, - (unsigned char *)&ShortPreamble); - } - } else { - if (priv->dot11_current_preamble_mode != PREAMBLE_LONG) { - ShortPreamble = false; - priv->dot11_current_preamble_mode = PREAMBLE_LONG; - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACK_PREAMBLE, - (unsigned char *)&ShortPreamble); - } - } - - if (net->mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) { - u8 slot_time_val; - u8 cur_slot_time = priv->slot_time; - - if ((cap & WLAN_CAPABILITY_SHORT_SLOT_TIME) && - (!priv->rtllib->ht_info->current_rt2rt_long_slot_time)) { - if (cur_slot_time != SHORT_SLOT_TIME) { - slot_time_val = SHORT_SLOT_TIME; - priv->rtllib->set_hw_reg_handler(dev, - HW_VAR_SLOT_TIME, &slot_time_val); - } - } else { - if (cur_slot_time != NON_SHORT_SLOT_TIME) { - slot_time_val = NON_SHORT_SLOT_TIME; - priv->rtllib->set_hw_reg_handler(dev, - HW_VAR_SLOT_TIME, &slot_time_val); - } - } - } -} - -static const struct rtllib_qos_parameters def_qos_parameters = { - {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, - {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, - {2, 2, 2, 2}, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static void _rtl92e_update_beacon(void *data) -{ - struct r8192_priv *priv = container_of(data, struct r8192_priv, update_beacon_wq.work); - struct net_device *dev = priv->rtllib->dev; - struct rtllib_device *ieee = priv->rtllib; - struct rtllib_network *net = &ieee->current_network; - - if (ieee->ht_info->current_ht_support) - HT_update_self_and_peer_setting(ieee, net); - ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time; - _rtl92e_update_cap(dev, net->capability); -} - -static void _rtl92e_qos_activate(void *data) -{ - struct r8192_priv *priv = container_of(data, struct r8192_priv, qos_activate); - struct net_device *dev = priv->rtllib->dev; - int i; - - mutex_lock(&priv->mutex); - if (priv->rtllib->link_state != MAC80211_LINKED) - goto success; - - for (i = 0; i < QOS_QUEUE_NUM; i++) - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM, (u8 *)(&i)); - -success: - mutex_unlock(&priv->mutex); -} - -static int _rtl92e_qos_handle_probe_response(struct r8192_priv *priv, - int active_network, - struct rtllib_network *network) -{ - int ret = 0; - u32 size = sizeof(struct rtllib_qos_parameters); - - if (priv->rtllib->link_state != MAC80211_LINKED) - return ret; - - if (priv->rtllib->iw_mode != IW_MODE_INFRA) - return ret; - - if (network->flags & NETWORK_HAS_QOS_MASK) { - if (active_network && - (network->flags & NETWORK_HAS_QOS_PARAMETERS)) - network->qos_data.active = network->qos_data.supported; - - if ((network->qos_data.active == 1) && (active_network == 1) && - (network->flags & NETWORK_HAS_QOS_PARAMETERS) && - (network->qos_data.old_param_count != - network->qos_data.param_count)) { - network->qos_data.old_param_count = - network->qos_data.param_count; - priv->rtllib->wmm_acm = network->qos_data.wmm_acm; - schedule_work(&priv->qos_activate); - } - } else { - memcpy(&priv->rtllib->current_network.qos_data.parameters, - &def_qos_parameters, size); - - if ((network->qos_data.active == 1) && (active_network == 1)) - schedule_work(&priv->qos_activate); - - network->qos_data.active = 0; - network->qos_data.supported = 0; - } - - return 0; -} - -static int _rtl92e_handle_beacon(struct net_device *dev, - struct rtllib_beacon *beacon, - struct rtllib_network *network) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - _rtl92e_qos_handle_probe_response(priv, 1, network); - - schedule_delayed_work(&priv->update_beacon_wq, 0); - return 0; -} - -static int _rtl92e_qos_assoc_resp(struct r8192_priv *priv, - struct rtllib_network *network) -{ - unsigned long flags; - u32 size = sizeof(struct rtllib_qos_parameters); - int set_qos_param = 0; - - if (!priv || !network) - return 0; - - if (priv->rtllib->link_state != MAC80211_LINKED) - return 0; - - if (priv->rtllib->iw_mode != IW_MODE_INFRA) - return 0; - - spin_lock_irqsave(&priv->rtllib->lock, flags); - if (network->flags & NETWORK_HAS_QOS_PARAMETERS) { - memcpy(&priv->rtllib->current_network.qos_data.parameters, - &network->qos_data.parameters, - sizeof(struct rtllib_qos_parameters)); - priv->rtllib->current_network.qos_data.active = 1; - priv->rtllib->wmm_acm = network->qos_data.wmm_acm; - set_qos_param = 1; - priv->rtllib->current_network.qos_data.old_param_count = - priv->rtllib->current_network.qos_data.param_count; - priv->rtllib->current_network.qos_data.param_count = - network->qos_data.param_count; - } else { - memcpy(&priv->rtllib->current_network.qos_data.parameters, - &def_qos_parameters, size); - priv->rtllib->current_network.qos_data.active = 0; - priv->rtllib->current_network.qos_data.supported = 0; - set_qos_param = 1; - } - - spin_unlock_irqrestore(&priv->rtllib->lock, flags); - - if (set_qos_param == 1) { - rtl92e_dm_init_edca_turbo(priv->rtllib->dev); - schedule_work(&priv->qos_activate); - } - return 0; -} - -static int _rtl92e_handle_assoc_response(struct net_device *dev, - struct rtllib_assoc_response_frame *resp, - struct rtllib_network *network) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - _rtl92e_qos_assoc_resp(priv, network); - return 0; -} - -void rtl92e_config_rate(struct net_device *dev, u16 *rate_config) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_network *net; - u8 i = 0, basic_rate = 0; - - net = &priv->rtllib->current_network; - - for (i = 0; i < net->rates_len; i++) { - basic_rate = net->rates[i] & 0x7f; - switch (basic_rate) { - case MGN_1M: - *rate_config |= RRSR_1M; - break; - case MGN_2M: - *rate_config |= RRSR_2M; - break; - case MGN_5_5M: - *rate_config |= RRSR_5_5M; - break; - case MGN_11M: - *rate_config |= RRSR_11M; - break; - case MGN_6M: - *rate_config |= RRSR_6M; - break; - case MGN_9M: - *rate_config |= RRSR_9M; - break; - case MGN_12M: - *rate_config |= RRSR_12M; - break; - case MGN_18M: - *rate_config |= RRSR_18M; - break; - case MGN_24M: - *rate_config |= RRSR_24M; - break; - case MGN_36M: - *rate_config |= RRSR_36M; - break; - case MGN_48M: - *rate_config |= RRSR_48M; - break; - case MGN_54M: - *rate_config |= RRSR_54M; - break; - } - } - - for (i = 0; i < net->rates_ex_len; i++) { - basic_rate = net->rates_ex[i] & 0x7f; - switch (basic_rate) { - case MGN_1M: - *rate_config |= RRSR_1M; - break; - case MGN_2M: - *rate_config |= RRSR_2M; - break; - case MGN_5_5M: - *rate_config |= RRSR_5_5M; - break; - case MGN_11M: - *rate_config |= RRSR_11M; - break; - case MGN_6M: - *rate_config |= RRSR_6M; - break; - case MGN_9M: - *rate_config |= RRSR_9M; - break; - case MGN_12M: - *rate_config |= RRSR_12M; - break; - case MGN_18M: - *rate_config |= RRSR_18M; - break; - case MGN_24M: - *rate_config |= RRSR_24M; - break; - case MGN_36M: - *rate_config |= RRSR_36M; - break; - case MGN_48M: - *rate_config |= RRSR_48M; - break; - case MGN_54M: - *rate_config |= RRSR_54M; - break; - } - } -} - -static void _rtl92e_refresh_support_rate(struct r8192_priv *priv) -{ - struct rtllib_device *ieee = priv->rtllib; - - if (ieee->mode == WIRELESS_MODE_N_24G) { - memcpy(ieee->reg_dot11ht_oper_rate_set, - ieee->reg_ht_supp_rate_set, 16); - memcpy(ieee->reg_dot11tx_ht_oper_rate_set, - ieee->reg_ht_supp_rate_set, 16); - - } else { - memset(ieee->reg_dot11ht_oper_rate_set, 0, 16); - } -} - -void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 support_mode = (WIRELESS_MODE_N_24G | WIRELESS_MODE_G | WIRELESS_MODE_B); - - if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode & support_mode) == 0)) - wireless_mode = WIRELESS_MODE_N_24G; - - if ((wireless_mode & (WIRELESS_MODE_B | WIRELESS_MODE_G)) == - (WIRELESS_MODE_G | WIRELESS_MODE_B)) - wireless_mode = WIRELESS_MODE_G; - - priv->rtllib->mode = wireless_mode; - - if (wireless_mode == WIRELESS_MODE_N_24G) - priv->rtllib->ht_info->enable_ht = 1; - else - priv->rtllib->ht_info->enable_ht = 0; - - _rtl92e_refresh_support_rate(priv); -} - -static int _rtl92e_sta_up(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - bool init_status; - - priv->up = 1; - priv->rtllib->ieee_up = 1; - - priv->up_first_time = 0; - init_status = rtl92e_start_adapter(dev); - if (!init_status) { - netdev_err(dev, "%s(): Initialization failed!\n", __func__); - return -1; - } - - RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); - - if (priv->polling_timer_on == 0) - rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer); - - if (priv->rtllib->link_state != MAC80211_LINKED) - rtllib_softmac_start_protocol(priv->rtllib); - rtllib_reset_queue(priv->rtllib); - _rtl92e_watchdog_timer_cb(&priv->watch_dog_timer); - - if (!netif_queue_stopped(dev)) - netif_start_queue(dev); - else - netif_wake_queue(dev); - - priv->bfirst_after_down = false; - return 0; -} - -static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) -{ - struct r8192_priv *priv = rtllib_priv(dev); - unsigned long flags = 0; - u8 rf_in_progress_timeout = 0; - - if (priv->up == 0) - return -1; - - priv->rtllib->rtllib_ips_leave(dev); - - if (priv->rtllib->link_state == MAC80211_LINKED) - rtl92e_leisure_ps_leave(dev); - - priv->up = 0; - priv->rtllib->ieee_up = 0; - priv->bfirst_after_down = true; - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - - priv->rtllib->wpa_ie_len = 0; - kfree(priv->rtllib->wpa_ie); - priv->rtllib->wpa_ie = NULL; - rtl92e_cam_reset(dev); - memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); - rtl92e_irq_disable(dev); - - del_timer_sync(&priv->watch_dog_timer); - _rtl92e_cancel_deferred_work(priv); - cancel_delayed_work(&priv->rtllib->hw_wakeup_wq); - - rtllib_softmac_stop_protocol(priv->rtllib); - spin_lock_irqsave(&priv->rf_ps_lock, flags); - while (priv->rf_change_in_progress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - if (rf_in_progress_timeout > 100) { - spin_lock_irqsave(&priv->rf_ps_lock, flags); - break; - } - mdelay(1); - rf_in_progress_timeout++; - spin_lock_irqsave(&priv->rf_ps_lock, flags); - } - priv->rf_change_in_progress = true; - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - rtl92e_stop_adapter(dev, false); - spin_lock_irqsave(&priv->rf_ps_lock, flags); - priv->rf_change_in_progress = false; - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - udelay(100); - memset(&priv->rtllib->current_network, 0, - offsetof(struct rtllib_network, list)); - - return 0; -} - -static void _rtl92e_init_priv_handler(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->rtllib->softmac_hard_start_xmit = _rtl92e_hard_start_xmit; - priv->rtllib->set_chan = rtl92e_set_channel; - priv->rtllib->link_change = rtl92e_link_change; - priv->rtllib->softmac_data_hard_start_xmit = _rtl92e_hard_data_xmit; - priv->rtllib->check_nic_enough_desc = _rtl92e_check_nic_enough_desc; - priv->rtllib->handle_assoc_response = _rtl92e_handle_assoc_response; - priv->rtllib->handle_beacon = _rtl92e_handle_beacon; - priv->rtllib->set_wireless_mode = rtl92e_set_wireless_mode; - priv->rtllib->leisure_ps_leave = rtl92e_leisure_ps_leave; - priv->rtllib->set_bw_mode_handler = rtl92e_set_bw_mode; - - priv->rtllib->sta_wake_up = rtl92e_hw_wakeup; - priv->rtllib->enter_sleep_state = rtl92e_enter_sleep; - priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty; - - priv->rtllib->get_nmode_support_by_sec_cfg = rtl92e_get_nmode_support_by_sec; - priv->rtllib->get_half_nmode_support_by_aps_handler = - rtl92e_is_halfn_supported_by_ap; - - priv->rtllib->set_hw_reg_handler = rtl92e_set_reg; - priv->rtllib->allow_all_dest_addr_handler = rtl92e_set_monitor_mode; - priv->rtllib->init_gain_handler = rtl92e_init_gain; - priv->rtllib->rtllib_ips_leave_wq = rtl92e_rtllib_ips_leave_wq; - priv->rtllib->rtllib_ips_leave = rtl92e_rtllib_ips_leave; - priv->rtllib->ScanOperationBackupHandler = rtl92e_scan_op_backup; -} - -static void _rtl92e_init_priv_variable(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 i; - - priv->dot11_current_preamble_mode = PREAMBLE_AUTO; - priv->rtllib->status = 0; - priv->polling_timer_on = 0; - priv->up_first_time = 1; - priv->blinked_ingpio = false; - priv->being_init_adapter = false; - priv->txringcount = 64; - priv->rxbuffersize = 9100; - priv->rxringcount = MAX_RX_COUNT; - priv->irq_enabled = 0; - priv->chan = 1; - priv->rtllib->mode = WIRELESS_MODE_AUTO; - priv->rtllib->iw_mode = IW_MODE_INFRA; - priv->rtllib->ieee_up = 0; - priv->retry_rts = DEFAULT_RETRY_RTS; - priv->retry_data = DEFAULT_RETRY_DATA; - priv->rtllib->rts = DEFAULT_RTS_THRESHOLD; - priv->rtllib->rate = 110; - priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - priv->bcck_in_ch14 = false; - priv->cck_present_attn = 0; - priv->rfa_txpowertrackingindex = 0; - priv->cck_pwr_enl = 6; - memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); - priv->rx_ctr = 0; - priv->rtllib->wx_set_enc = 0; - priv->hw_radio_off = false; - priv->rtllib->rf_off_reason = 0; - priv->rf_change_in_progress = false; - priv->hw_rf_off_action = 0; - priv->set_rf_pwr_state_in_progress = false; - priv->rtllib->pwr_save_ctrl.bLeisurePs = true; - priv->rtllib->lps_delay_cnt = 0; - priv->rtllib->sta_sleep = LPS_IS_WAKE; - priv->rtllib->rf_power_state = rf_on; - - priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; - priv->rtllib->iw_mode = IW_MODE_INFRA; - priv->rtllib->be_scan_inprogress = false; - - priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; - - priv->fw_info = vzalloc(sizeof(struct rt_firmware)); - if (!priv->fw_info) - netdev_err(dev, - "rtl8192e: Unable to allocate space for firmware\n"); - - skb_queue_head_init(&priv->skb_queue); - - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_head_init(&priv->rtllib->skb_waitq[i]); -} - -static void _rtl92e_init_priv_lock(struct r8192_priv *priv) -{ - spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->irq_th_lock); - spin_lock_init(&priv->rf_ps_lock); - spin_lock_init(&priv->ps_lock); - mutex_init(&priv->wx_mutex); - mutex_init(&priv->rf_mutex); - mutex_init(&priv->mutex); -} - -static void _rtl92e_init_priv_task(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - INIT_WORK(&priv->reset_wq, (void *)_rtl92e_restart); - INIT_WORK(&priv->rtllib->ips_leave_wq, (void *)rtl92e_ips_leave_wq); - INIT_DELAYED_WORK(&priv->watch_dog_wq, (void *)_rtl92e_watchdog_wq_cb); - INIT_DELAYED_WORK(&priv->txpower_tracking_wq, (void *)rtl92e_dm_txpower_tracking_wq); - INIT_DELAYED_WORK(&priv->rfpath_check_wq, (void *)rtl92e_dm_rf_pathcheck_wq); - INIT_DELAYED_WORK(&priv->update_beacon_wq, (void *)_rtl92e_update_beacon); - INIT_WORK(&priv->qos_activate, (void *)_rtl92e_qos_activate); - INIT_DELAYED_WORK(&priv->rtllib->hw_wakeup_wq, (void *)rtl92e_hw_wakeup_wq); - INIT_DELAYED_WORK(&priv->rtllib->hw_sleep_wq, (void *)rtl92e_hw_sleep_wq); - tasklet_setup(&priv->irq_rx_tasklet, _rtl92e_irq_rx_tasklet); - tasklet_setup(&priv->irq_tx_tasklet, _rtl92e_irq_tx_tasklet); -} - -static short _rtl92e_get_channel_map(struct net_device *dev) -{ - int i; - - struct r8192_priv *priv = rtllib_priv(dev); - - for (i = 1; i <= 11; i++) - (priv->rtllib->active_channel_map)[i] = 1; - (priv->rtllib->active_channel_map)[12] = 2; - (priv->rtllib->active_channel_map)[13] = 2; - - return 0; -} - -static short _rtl92e_init(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - memset(&priv->stats, 0, sizeof(struct rt_stats)); - - _rtl92e_init_priv_handler(dev); - _rtl92e_init_priv_variable(dev); - _rtl92e_init_priv_lock(priv); - _rtl92e_init_priv_task(dev); - rtl92e_get_eeprom_size(dev); - rtl92e_init_variables(dev); - _rtl92e_get_channel_map(dev); - - rtl92e_dm_init(dev); - - timer_setup(&priv->watch_dog_timer, _rtl92e_watchdog_timer_cb, 0); - - timer_setup(&priv->gpio_polling_timer, rtl92e_check_rfctrl_gpio_timer, - 0); - - rtl92e_irq_disable(dev); - if (request_irq(dev->irq, _rtl92e_irq, IRQF_SHARED, dev->name, dev)) { - netdev_err(dev, "Error allocating IRQ %d", dev->irq); - return -1; - } - - priv->irq = dev->irq; - - if (_rtl92e_pci_initdescring(dev) != 0) { - netdev_err(dev, "Endopoints initialization failed"); - free_irq(dev->irq, dev); - return -1; - } - - return 0; -} - -/*************************************************************************** - * -------------------------------WATCHDOG STUFF--------------------------- - **************************************************************************/ -static short _rtl92e_is_tx_queue_empty(struct net_device *dev) -{ - int i = 0; - struct r8192_priv *priv = rtllib_priv(dev); - - for (i = 0; i <= MGNT_QUEUE; i++) { - if ((i == TXCMD_QUEUE) || (i == HCCA_QUEUE)) - continue; - if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0) { - netdev_info(dev, "===>tx queue is not empty:%d, %d\n", - i, skb_queue_len(&(&priv->tx_ring[i])->queue)); - return 0; - } - } - return 1; -} - -static enum reset_type _rtl92e_tx_check_stuck(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 QueueID; - bool bCheckFwTxCnt = false; - struct rtl8192_tx_ring *ring = NULL; - struct sk_buff *skb = NULL; - struct cb_desc *tcb_desc = NULL; - unsigned long flags = 0; - - switch (priv->rtllib->ps) { - case RTLLIB_PS_DISABLED: - break; - case (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST): - break; - default: - break; - } - spin_lock_irqsave(&priv->irq_th_lock, flags); - for (QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) { - if (QueueID == TXCMD_QUEUE) - continue; - - if (QueueID == BEACON_QUEUE) - continue; - - ring = &priv->tx_ring[QueueID]; - - if (skb_queue_len(&ring->queue) == 0) { - continue; - } else { - skb = __skb_peek(&ring->queue); - tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - tcb_desc->nStuckCount++; - bCheckFwTxCnt = true; - if (tcb_desc->nStuckCount > 1) - netdev_info(dev, - "%s: QueueID=%d tcb_desc->nStuckCount=%d\n", - __func__, QueueID, - tcb_desc->nStuckCount); - } - } - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - - if (bCheckFwTxCnt) { - if (rtl92e_is_tx_stuck(dev)) - return RESET_TYPE_SILENT; - } - - return RESET_TYPE_NORESET; -} - -static enum reset_type _rtl92e_rx_check_stuck(struct net_device *dev) -{ - if (rtl92e_is_rx_stuck(dev)) - return RESET_TYPE_SILENT; - - return RESET_TYPE_NORESET; -} - -static void _rtl92e_if_check_reset(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - enum reset_type TxResetType = RESET_TYPE_NORESET; - enum reset_type RxResetType = RESET_TYPE_NORESET; - enum rt_rf_power_state rfState; - - rfState = priv->rtllib->rf_power_state; - - if (rfState == rf_on) - TxResetType = _rtl92e_tx_check_stuck(dev); - - if (rfState == rf_on && - (priv->rtllib->iw_mode == IW_MODE_INFRA) && - (priv->rtllib->link_state == MAC80211_LINKED)) - RxResetType = _rtl92e_rx_check_stuck(dev); - - if (TxResetType == RESET_TYPE_SILENT || - RxResetType == RESET_TYPE_SILENT) { - netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n", - __func__, TxResetType, RxResetType); - } -} - -static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, - u32 *TotalRxDataNum) -{ - u16 slot_index; - u8 i; - - *TotalRxBcnNum = 0; - *TotalRxDataNum = 0; - - slot_index = (priv->rtllib->link_detect_info.slot_index++) % - (priv->rtllib->link_detect_info.slot_num); - priv->rtllib->link_detect_info.RxBcnNum[slot_index] = - priv->rtllib->link_detect_info.num_recv_bcn_in_period; - priv->rtllib->link_detect_info.RxDataNum[slot_index] = - priv->rtllib->link_detect_info.num_recv_data_in_period; - for (i = 0; i < priv->rtllib->link_detect_info.slot_num; i++) { - *TotalRxBcnNum += priv->rtllib->link_detect_info.RxBcnNum[i]; - *TotalRxDataNum += priv->rtllib->link_detect_info.RxDataNum[i]; - } -} - -static void _rtl92e_watchdog_wq_cb(void *data) -{ - struct r8192_priv *priv = container_of_dwork_rsl(data, - struct r8192_priv, watch_dog_wq); - struct net_device *dev = priv->rtllib->dev; - struct rtllib_device *ieee = priv->rtllib; - static u8 check_reset_cnt; - unsigned long flags; - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - bool busy_traffic = false; - bool bHigherBusyTraffic = false; - bool bHigherBusyRxTraffic = false; - bool bEnterPS = false; - - if (!priv->up || priv->hw_radio_off) - return; - - if (priv->rtllib->link_state >= MAC80211_LINKED) { - if (priv->rtllib->cnt_after_link < 2) - priv->rtllib->cnt_after_link++; - } else { - priv->rtllib->cnt_after_link = 0; - } - - rtl92e_dm_watchdog(dev); - - if (!rtllib_act_scanning(priv->rtllib, false)) { - if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->link_state == - MAC80211_NOLINK) && - (ieee->rf_power_state == rf_on) && !ieee->is_set_key && - (!ieee->proto_stoppping) && !ieee->wx_set_enc) { - if (ieee->pwr_save_ctrl.return_point == IPS_CALLBACK_NONE) - rtl92e_ips_enter(dev); - } - } - if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode == IW_MODE_INFRA)) { - if (ieee->link_detect_info.num_rx_ok_in_period > 100 || - ieee->link_detect_info.num_tx_ok_in_period > 100) - busy_traffic = true; - - if (ieee->link_detect_info.num_rx_ok_in_period > 4000 || - ieee->link_detect_info.num_tx_ok_in_period > 4000) { - bHigherBusyTraffic = true; - if (ieee->link_detect_info.num_rx_ok_in_period > 5000) - bHigherBusyRxTraffic = true; - else - bHigherBusyRxTraffic = false; - } - - if (((ieee->link_detect_info.num_rx_unicast_ok_in_period + - ieee->link_detect_info.num_tx_ok_in_period) > 8) || - (ieee->link_detect_info.num_rx_unicast_ok_in_period > 2)) - bEnterPS = false; - else - bEnterPS = true; - - if (ieee->current_network.beacon_interval < 95) - bEnterPS = false; - - if (bEnterPS) - rtl92e_leisure_ps_enter(dev); - else - rtl92e_leisure_ps_leave(dev); - - } else { - rtl92e_leisure_ps_leave(dev); - } - - ieee->link_detect_info.num_rx_ok_in_period = 0; - ieee->link_detect_info.num_tx_ok_in_period = 0; - ieee->link_detect_info.num_rx_unicast_ok_in_period = 0; - ieee->link_detect_info.busy_traffic = busy_traffic; - - ieee->link_detect_info.bHigherBusyTraffic = bHigherBusyTraffic; - ieee->link_detect_info.bHigherBusyRxTraffic = bHigherBusyRxTraffic; - - if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) { - u32 TotalRxBcnNum = 0; - u32 TotalRxDataNum = 0; - - _rtl92e_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); - - if ((TotalRxBcnNum + TotalRxDataNum) == 0) - priv->check_roaming_cnt++; - else - priv->check_roaming_cnt = 0; - - if (priv->check_roaming_cnt > 0) { - if (ieee->rf_power_state == rf_off) - netdev_info(dev, "%s(): RF is off\n", __func__); - - netdev_info(dev, - "===>%s(): AP is power off, chan:%d, connect another one\n", - __func__, priv->chan); - - ieee->link_state = RTLLIB_ASSOCIATING; - - remove_peer_ts(priv->rtllib, - priv->rtllib->current_network.bssid); - ieee->is_roaming = true; - ieee->is_set_key = false; - ieee->link_change(dev); - notify_wx_assoc_event(ieee); - - if (!(ieee->rtllib_ap_sec_type(ieee) & - (SEC_ALG_CCMP | SEC_ALG_TKIP))) - schedule_delayed_work( - &ieee->associate_procedure_wq, 0); - - priv->check_roaming_cnt = 0; - } - ieee->link_detect_info.num_recv_bcn_in_period = 0; - ieee->link_detect_info.num_recv_data_in_period = 0; - } - - spin_lock_irqsave(&priv->tx_lock, flags); - if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) && - (!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) { - _rtl92e_if_check_reset(dev); - check_reset_cnt = 3; - } - spin_unlock_irqrestore(&priv->tx_lock, flags); -} - -static void _rtl92e_watchdog_timer_cb(struct timer_list *t) -{ - struct r8192_priv *priv = from_timer(priv, t, watch_dog_timer); - - schedule_delayed_work(&priv->watch_dog_wq, 0); - mod_timer(&priv->watch_dog_timer, jiffies + - msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME)); -} - -/**************************************************************************** - * ---------------------------- NIC TX/RX STUFF--------------------------- - ****************************************************************************/ -void rtl92e_rx_enable(struct net_device *dev) -{ - rtl92e_enable_rx(dev); -} - -void rtl92e_tx_enable(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_enable_tx(dev); - - rtllib_reset_queue(priv->rtllib); -} - -static void _rtl92e_free_rx_ring(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int i; - - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = priv->rx_buf[i]; - - if (!skb) - continue; - - dma_unmap_single(&priv->pdev->dev, - *((dma_addr_t *)skb->cb), - priv->rxbuffersize, DMA_FROM_DEVICE); - kfree_skb(skb); - } - - dma_free_coherent(&priv->pdev->dev, - sizeof(*priv->rx_ring) * priv->rxringcount, - priv->rx_ring, - priv->rx_ring_dma); - priv->rx_ring = NULL; -} - -static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb = __skb_dequeue(&ring->queue); - - dma_unmap_single(&priv->pdev->dev, entry->TxBuffAddr, - skb->len, DMA_TO_DEVICE); - kfree_skb(skb); - ring->idx = (ring->idx + 1) % ring->entries; - } - - dma_free_coherent(&priv->pdev->dev, - sizeof(*ring->desc) * ring->entries, ring->desc, - ring->dma); - ring->desc = NULL; -} - -static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, - int rate) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - if ((priv->rtllib->rf_power_state == rf_off) || !priv->up) { - kfree_skb(skb); - return; - } - - if (queue_index == TXCMD_QUEUE) - netdev_warn(dev, "%s(): queue index == TXCMD_QUEUE\n", - __func__); - - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - skb_push(skb, priv->rtllib->tx_headroom); - ret = _rtl92e_tx(dev, skb); - - if (queue_index != MGNT_QUEUE) { - priv->rtllib->stats.tx_bytes += (skb->len - - priv->rtllib->tx_headroom); - priv->rtllib->stats.tx_packets++; - } - - if (ret != 0) - kfree_skb(skb); -} - -static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - if (queue_index != TXCMD_QUEUE) { - if ((priv->rtllib->rf_power_state == rf_off) || - !priv->up) { - kfree_skb(skb); - return 0; - } - } - - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - if (queue_index == TXCMD_QUEUE) { - _rtl92e_tx_cmd(dev, skb); - return 0; - } - - tcb_desc->ratr_index = 7; - tcb_desc->tx_dis_rate_fallback = 1; - tcb_desc->tx_use_drv_assinged_rate = 1; - tcb_desc->tx_enable_fw_calc_dur = 1; - skb_push(skb, priv->rtllib->tx_headroom); - ret = _rtl92e_tx(dev, skb); - if (ret != 0) - kfree_skb(skb); - return ret; -} - -static void _rtl92e_tx_isr(struct net_device *dev, int prio) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - - if (prio != BEACON_QUEUE) { - if (entry->OWN) - return; - ring->idx = (ring->idx + 1) % ring->entries; - } - - skb = __skb_dequeue(&ring->queue); - dma_unmap_single(&priv->pdev->dev, entry->TxBuffAddr, - skb->len, DMA_TO_DEVICE); - - kfree_skb(skb); - } - if (prio != BEACON_QUEUE) - tasklet_schedule(&priv->irq_tx_tasklet); -} - -static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtl8192_tx_ring *ring; - struct tx_desc_cmd *entry; - unsigned int idx; - struct cb_desc *tcb_desc; - unsigned long flags; - - spin_lock_irqsave(&priv->irq_th_lock, flags); - ring = &priv->tx_ring[TXCMD_QUEUE]; - - idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; - entry = (struct tx_desc_cmd *)&ring->desc[idx]; - - tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - - rtl92e_fill_tx_cmd_desc(dev, entry, tcb_desc, skb); - - __skb_queue_tail(&ring->queue, skb); - spin_unlock_irqrestore(&priv->irq_th_lock, flags); -} - -static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtl8192_tx_ring *ring; - unsigned long flags; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - struct tx_desc *pdesc = NULL; - struct ieee80211_hdr *header = NULL; - u8 *pda_addr = NULL; - int idx; - u32 fwinfo_size = 0; - - priv->rtllib->awake_pkt_sent = true; - - fwinfo_size = sizeof(struct tx_fwinfo_8190pci); - - header = (struct ieee80211_hdr *)(((u8 *)skb->data) + fwinfo_size); - pda_addr = header->addr1; - - if (!is_broadcast_ether_addr(pda_addr) && !is_multicast_ether_addr(pda_addr)) - priv->stats.txbytesunicast += skb->len - fwinfo_size; - - spin_lock_irqsave(&priv->irq_th_lock, flags); - ring = &priv->tx_ring[tcb_desc->queue_index]; - if (tcb_desc->queue_index != BEACON_QUEUE) - idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; - else - idx = 0; - - pdesc = &ring->desc[idx]; - if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { - netdev_warn(dev, - "No more TX desc@%d, ring->idx = %d, idx = %d, skblen = 0x%x queuelen=%d", - tcb_desc->queue_index, ring->idx, idx, skb->len, - skb_queue_len(&ring->queue)); - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return skb->len; - } - rtl92e_fill_tx_desc(dev, pdesc, tcb_desc, skb); - __skb_queue_tail(&ring->queue, skb); - pdesc->OWN = 1; - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - netif_trans_update(dev); - - rtl92e_writew(dev, TP_POLL, 0x01 << tcb_desc->queue_index); - return 0; -} - -static short _rtl92e_alloc_rx_ring(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rx_desc *entry = NULL; - int i; - - priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev, - sizeof(*priv->rx_ring) * priv->rxringcount, - &priv->rx_ring_dma, - GFP_ATOMIC); - if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { - netdev_warn(dev, "Cannot allocate RX ring\n"); - return -ENOMEM; - } - - priv->rx_idx = 0; - - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); - dma_addr_t *mapping; - - entry = &priv->rx_ring[i]; - if (!skb) - return 0; - skb->dev = dev; - priv->rx_buf[i] = skb; - mapping = (dma_addr_t *)skb->cb; - *mapping = dma_map_single(&priv->pdev->dev, - skb_tail_pointer(skb), - priv->rxbuffersize, DMA_FROM_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, *mapping)) { - dev_kfree_skb_any(skb); - return -1; - } - entry->BufferAddress = *mapping; - - entry->Length = priv->rxbuffersize; - entry->OWN = 1; - } - - if (entry) - entry->EOR = 1; - return 0; -} - -static int _rtl92e_alloc_tx_ring(struct net_device *dev, unsigned int prio, - unsigned int entries) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct tx_desc *ring; - dma_addr_t dma; - int i; - - ring = dma_alloc_coherent(&priv->pdev->dev, sizeof(*ring) * entries, - &dma, GFP_ATOMIC); - if (!ring || (unsigned long)ring & 0xFF) { - netdev_warn(dev, "Cannot allocate TX ring (prio = %d)\n", prio); - return -ENOMEM; - } - - priv->tx_ring[prio].desc = ring; - priv->tx_ring[prio].dma = dma; - priv->tx_ring[prio].idx = 0; - priv->tx_ring[prio].entries = entries; - skb_queue_head_init(&priv->tx_ring[prio].queue); - - for (i = 0; i < entries; i++) - ring[i].NextDescAddress = - (u32)dma + ((i + 1) % entries) * - sizeof(*ring); - - return 0; -} - -static short _rtl92e_pci_initdescring(struct net_device *dev) -{ - u32 ret; - int i; - struct r8192_priv *priv = rtllib_priv(dev); - - ret = _rtl92e_alloc_rx_ring(dev); - if (ret) - return ret; - - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - ret = _rtl92e_alloc_tx_ring(dev, i, priv->txringcount); - if (ret) - goto err_free_rings; - } - - return 0; - -err_free_rings: - _rtl92e_free_rx_ring(dev); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - if (priv->tx_ring[i].desc) - _rtl92e_free_tx_ring(dev, i); - return 1; -} - -void rtl92e_reset_desc_ring(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int i; - unsigned long flags = 0; - - if (priv->rx_ring) { - struct rx_desc *entry = NULL; - - for (i = 0; i < priv->rxringcount; i++) { - entry = &priv->rx_ring[i]; - entry->OWN = 1; - } - priv->rx_idx = 0; - } - - spin_lock_irqsave(&priv->irq_th_lock, flags); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - if (priv->tx_ring[i].desc) { - struct rtl8192_tx_ring *ring = &priv->tx_ring[i]; - - while (skb_queue_len(&ring->queue)) { - struct tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb = - __skb_dequeue(&ring->queue); - - dma_unmap_single(&priv->pdev->dev, - entry->TxBuffAddr, skb->len, - DMA_TO_DEVICE); - kfree_skb(skb); - ring->idx = (ring->idx + 1) % ring->entries; - } - ring->idx = 0; - } - } - spin_unlock_irqrestore(&priv->irq_th_lock, flags); -} - -long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index) -{ - long signal_power; - - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -void rtl92e_update_rx_statistics(struct r8192_priv *priv, - struct rtllib_rx_stats *pprevious_stats) -{ - int weighting = 0; - - if (priv->stats.recv_signal_power == 0) - priv->stats.recv_signal_power = - pprevious_stats->RecvSignalPower; - - if (pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power) - weighting = 5; - else if (pprevious_stats->RecvSignalPower < - priv->stats.recv_signal_power) - weighting = (-5); - priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + - pprevious_stats->RecvSignalPower + - weighting) / 6; -} - -u8 rtl92e_rx_db_to_percent(s8 antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; - -} /* QueryRxPwrPercentage */ - -u8 rtl92e_evm_db_to_percent(s8 value) -{ - s8 ret_val = clamp(-value, 0, 33) * 3; - - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} - -void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats, - struct rtllib_rx_stats *ptarget_stats) -{ - ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; - ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; -} - -static void _rtl92e_rx_normal(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct ieee80211_hdr *rtllib_hdr = NULL; - bool unicast_packet = false; - u32 skb_len = 0; - - struct rtllib_rx_stats stats = { - .signal = 0, - .noise = (u8)-98, - .rate = 0, - }; - unsigned int count = priv->rxringcount; - - while (count--) { - struct rx_desc *pdesc = &priv->rx_ring - [priv->rx_idx]; - struct sk_buff *skb = priv->rx_buf - [priv->rx_idx]; - struct sk_buff *new_skb; - - if (pdesc->OWN) - return; - if (!rtl92e_get_rx_stats(dev, &stats, pdesc, skb)) - goto done; - new_skb = dev_alloc_skb(priv->rxbuffersize); - /* if allocation of new skb failed - drop current packet - * and reuse skb - */ - if (unlikely(!new_skb)) - goto done; - - dma_unmap_single(&priv->pdev->dev, *((dma_addr_t *)skb->cb), - priv->rxbuffersize, DMA_FROM_DEVICE); - - skb_put(skb, pdesc->Length); - skb_reserve(skb, stats.RxDrvInfoSize + - stats.RxBufShift); - skb_trim(skb, skb->len - S_CRC_LEN); - rtllib_hdr = (struct ieee80211_hdr *)skb->data; - if (!is_multicast_ether_addr(rtllib_hdr->addr1)) { - /* unicast packet */ - unicast_packet = true; - } - skb_len = skb->len; - - if (!rtllib_rx(priv->rtllib, skb, &stats)) { - dev_kfree_skb_any(skb); - } else { - if (unicast_packet) - priv->stats.rxbytesunicast += skb_len; - } - - skb = new_skb; - skb->dev = dev; - - priv->rx_buf[priv->rx_idx] = skb; - *((dma_addr_t *)skb->cb) = dma_map_single(&priv->pdev->dev, - skb_tail_pointer(skb), - priv->rxbuffersize, DMA_FROM_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, *((dma_addr_t *)skb->cb))) { - dev_kfree_skb_any(skb); - return; - } -done: - pdesc->BufferAddress = *((dma_addr_t *)skb->cb); - pdesc->OWN = 1; - pdesc->Length = priv->rxbuffersize; - if (priv->rx_idx == priv->rxringcount - 1) - pdesc->EOR = 1; - priv->rx_idx = (priv->rx_idx + 1) % - priv->rxringcount; - } -} - -static void _rtl92e_tx_resume(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - struct sk_buff *skb; - int queue_index; - - for (queue_index = BK_QUEUE; - queue_index < MAX_QUEUE_SIZE; queue_index++) { - while ((!skb_queue_empty(&ieee->skb_waitq[queue_index])) && - (priv->rtllib->check_nic_enough_desc(dev, queue_index) > 0)) { - skb = skb_dequeue(&ieee->skb_waitq[queue_index]); - ieee->softmac_data_hard_start_xmit(skb, dev, 0); - } - } -} - -static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t) -{ - struct r8192_priv *priv = from_tasklet(priv, t, irq_tx_tasklet); - - _rtl92e_tx_resume(priv->rtllib->dev); -} - -static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t) -{ - struct r8192_priv *priv = from_tasklet(priv, t, irq_rx_tasklet); - - _rtl92e_rx_normal(priv->rtllib->dev); - - rtl92e_writel(priv->rtllib->dev, INTA_MASK, - rtl92e_readl(priv->rtllib->dev, INTA_MASK) | IMR_RDU); -} - -/**************************************************************************** - * ---------------------------- NIC START/CLOSE STUFF--------------------------- - ****************************************************************************/ -static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv) -{ - cancel_delayed_work_sync(&priv->watch_dog_wq); - cancel_delayed_work_sync(&priv->update_beacon_wq); - cancel_delayed_work(&priv->rtllib->hw_sleep_wq); - cancel_work_sync(&priv->reset_wq); - cancel_work_sync(&priv->qos_activate); -} - -static int _rtl92e_up(struct net_device *dev) -{ - if (_rtl92e_sta_up(dev) == -1) - return -1; - return 0; -} - -static int _rtl92e_open(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - ret = _rtl92e_try_up(dev); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_try_up(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->up == 1) - return -1; - return _rtl92e_up(dev); -} - -static int _rtl92e_close(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - - if ((rtllib_act_scanning(priv->rtllib, false)) && - !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { - rtllib_stop_scan(priv->rtllib); - } - - mutex_lock(&priv->wx_mutex); - - ret = _rtl92e_down(dev, true); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_down(struct net_device *dev, bool shutdownrf) -{ - if (_rtl92e_sta_down(dev, shutdownrf) == -1) - return -1; - - return 0; -} - -void rtl92e_commit(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->up == 0) - return; - rtllib_softmac_stop_protocol(priv->rtllib); - rtl92e_irq_disable(dev); - rtl92e_stop_adapter(dev, true); - _rtl92e_up(dev); -} - -static void _rtl92e_restart(void *data) -{ - struct r8192_priv *priv = container_of(data, struct r8192_priv, reset_wq); - struct net_device *dev = priv->rtllib->dev; - - mutex_lock(&priv->wx_mutex); - - rtl92e_commit(dev); - - mutex_unlock(&priv->wx_mutex); -} - -static void _rtl92e_set_multicast(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - short promisc; - - promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - priv->promisc = promisc; -} - -static int _rtl92e_set_mac_adr(struct net_device *dev, void *mac) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct sockaddr *addr = mac; - - mutex_lock(&priv->wx_mutex); - - eth_hw_addr_set(dev, addr->sa_data); - - schedule_work(&priv->reset_wq); - mutex_unlock(&priv->wx_mutex); - - return 0; -} - -static irqreturn_t _rtl92e_irq(int irq, void *netdev) -{ - struct net_device *dev = netdev; - struct r8192_priv *priv = rtllib_priv(dev); - unsigned long flags; - u32 inta; - - if (priv->irq_enabled == 0) - goto done; - - spin_lock_irqsave(&priv->irq_th_lock, flags); - - rtl92e_ack_irq(dev, &inta); - - if (!inta) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - goto done; - } - - if (inta == 0xffff) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - goto done; - } - - if (!netif_running(dev)) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - goto done; - } - - if (inta & IMR_MGNTDOK) { - _rtl92e_tx_isr(dev, MGNT_QUEUE); - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - if (priv->rtllib->ack_tx_to_ieee) { - if (_rtl92e_is_tx_queue_empty(dev)) { - priv->rtllib->ack_tx_to_ieee = 0; - rtllib_ps_tx_ack(priv->rtllib, 1); - } - } - spin_lock_irqsave(&priv->irq_th_lock, flags); - } - - if (inta & IMR_COMDOK) - _rtl92e_tx_isr(dev, TXCMD_QUEUE); - - if (inta & IMR_HIGHDOK) - _rtl92e_tx_isr(dev, HIGH_QUEUE); - - if (inta & IMR_ROK) - tasklet_schedule(&priv->irq_rx_tasklet); - - if (inta & IMR_RDU) { - rtl92e_writel(dev, INTA_MASK, - rtl92e_readl(dev, INTA_MASK) & ~IMR_RDU); - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & IMR_RXFOVW) - tasklet_schedule(&priv->irq_rx_tasklet); - - if (inta & IMR_BKDOK) { - priv->rtllib->link_detect_info.num_tx_ok_in_period++; - _rtl92e_tx_isr(dev, BK_QUEUE); - } - - if (inta & IMR_BEDOK) { - priv->rtllib->link_detect_info.num_tx_ok_in_period++; - _rtl92e_tx_isr(dev, BE_QUEUE); - } - - if (inta & IMR_VIDOK) { - priv->rtllib->link_detect_info.num_tx_ok_in_period++; - _rtl92e_tx_isr(dev, VI_QUEUE); - } - - if (inta & IMR_VODOK) { - priv->rtllib->link_detect_info.num_tx_ok_in_period++; - _rtl92e_tx_isr(dev, VO_QUEUE); - } - - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - -done: - - return IRQ_HANDLED; -} - -/**************************************************************************** - * ---------------------------- PCI_STUFF--------------------------- - ****************************************************************************/ -static const struct net_device_ops rtl8192_netdev_ops = { - .ndo_open = _rtl92e_open, - .ndo_stop = _rtl92e_close, - .ndo_tx_timeout = _rtl92e_tx_timeout, - .ndo_set_rx_mode = _rtl92e_set_multicast, - .ndo_set_mac_address = _rtl92e_set_mac_adr, - .ndo_validate_addr = eth_validate_addr, - .ndo_start_xmit = rtllib_xmit, -}; - -static int _rtl92e_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - unsigned long ioaddr = 0; - struct net_device *dev = NULL; - struct r8192_priv *priv = NULL; - unsigned long pmem_start, pmem_len, pmem_flags; - int err = -ENOMEM; - - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "Failed to enable PCI device"); - return -EIO; - } - - pci_set_master(pdev); - - if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { - if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) { - dev_info(&pdev->dev, - "Unable to obtain 32bit DMA for consistent allocations\n"); - goto err_pci_disable; - } - } - dev = alloc_rtllib(sizeof(struct r8192_priv)); - if (!dev) - goto err_pci_disable; - - err = -ENODEV; - - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - priv = rtllib_priv(dev); - priv->rtllib = (struct rtllib_device *)netdev_priv_rsl(dev); - priv->pdev = pdev; - priv->rtllib->pdev = pdev; - if ((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK) && - (pdev->subsystem_device == 0x3304)) - priv->rtllib->bSupportRemoteWakeUp = 1; - else - priv->rtllib->bSupportRemoteWakeUp = 0; - - pmem_start = pci_resource_start(pdev, 1); - pmem_len = pci_resource_len(pdev, 1); - pmem_flags = pci_resource_flags(pdev, 1); - - if (!(pmem_flags & IORESOURCE_MEM)) { - netdev_err(dev, "region #1 not a MMIO resource, aborting"); - goto err_rel_rtllib; - } - - dev_info(&pdev->dev, "Memory mapped space start: 0x%08lx\n", - pmem_start); - if (!request_mem_region(pmem_start, pmem_len, DRV_NAME)) { - netdev_err(dev, "request_mem_region failed!"); - goto err_rel_rtllib; - } - - ioaddr = (unsigned long)ioremap(pmem_start, pmem_len); - if (ioaddr == (unsigned long)NULL) { - netdev_err(dev, "ioremap failed!"); - goto err_rel_mem; - } - - dev->mem_start = ioaddr; - dev->mem_end = ioaddr + pci_resource_len(pdev, 0); - - if (!rtl92e_check_adapter(pdev, dev)) - goto err_unmap; - - dev->irq = pdev->irq; - priv->irq = 0; - - dev->netdev_ops = &rtl8192_netdev_ops; - - dev->wireless_handlers = &r8192_wx_handlers_def; - dev->ethtool_ops = &rtl819x_ethtool_ops; - - dev->type = ARPHRD_ETHER; - dev->watchdog_timeo = HZ * 3; - - if (dev_alloc_name(dev, ifname) < 0) - dev_alloc_name(dev, ifname); - - if (_rtl92e_init(dev) != 0) { - netdev_warn(dev, "Initialization failed"); - goto err_free_irq; - } - - netif_carrier_off(dev); - netif_stop_queue(dev); - - if (register_netdev(dev)) - goto err_free_irq; - - if (priv->polling_timer_on == 0) - rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer); - - return 0; - -err_free_irq: - free_irq(dev->irq, dev); - priv->irq = 0; -err_unmap: - iounmap((void __iomem *)ioaddr); -err_rel_mem: - release_mem_region(pmem_start, pmem_len); -err_rel_rtllib: - free_rtllib(dev); -err_pci_disable: - pci_disable_device(pdev); - return err; -} - -static void _rtl92e_pci_disconnect(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct r8192_priv *priv; - u32 i; - - if (dev) { - unregister_netdev(dev); - - priv = rtllib_priv(dev); - - del_timer_sync(&priv->gpio_polling_timer); - cancel_delayed_work_sync(&priv->gpio_change_rf_wq); - priv->polling_timer_on = 0; - _rtl92e_down(dev, true); - rtl92e_dm_deinit(dev); - vfree(priv->fw_info); - priv->fw_info = NULL; - _rtl92e_free_rx_ring(dev); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - _rtl92e_free_tx_ring(dev, i); - - if (priv->irq) { - dev_info(&pdev->dev, "Freeing irq %d\n", dev->irq); - free_irq(dev->irq, dev); - priv->irq = 0; - } - - if (dev->mem_start != 0) { - iounmap((void __iomem *)dev->mem_start); - release_mem_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); - } - - free_rtllib(dev); - } - - pci_disable_device(pdev); -} - -bool rtl92e_enable_nic(struct net_device *dev) -{ - bool init_status = true; - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - - if (!priv->up) { - netdev_warn(dev, "%s(): Driver is already down!\n", __func__); - return false; - } - - init_status = rtl92e_start_adapter(dev); - if (!init_status) { - netdev_warn(dev, "%s(): Initialization failed!\n", __func__); - return false; - } - RT_CLEAR_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC); - - rtl92e_irq_enable(dev); - return init_status; -} - -module_pci_driver(rtl8192_pci_driver); - -void rtl92e_check_rfctrl_gpio_timer(struct timer_list *t) -{ - struct r8192_priv *priv = from_timer(priv, t, gpio_polling_timer); - - priv->polling_timer_on = 1; - - schedule_delayed_work(&priv->gpio_change_rf_wq, 0); - - mod_timer(&priv->gpio_polling_timer, jiffies + - msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME)); -} - -/*************************************************************************** - * ------------------- module init / exit stubs ---------------- - ***************************************************************************/ -MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW); -MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW); -MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW); - -module_param(ifname, charp, 0644); -module_param(hwwep, int, 0644); - -MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); -MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)"); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h deleted file mode 100644 index 1d6d31292f41..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ /dev/null @@ -1,402 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#ifndef _RTL_CORE_H -#define _RTL_CORE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Need this defined before including local include files */ -#define DRV_NAME "rtl819xE" - -#include "../rtllib.h" - -#include "r8192E_firmware.h" -#include "r8192E_hw.h" - -#include "r8190P_def.h" -#include "r8192E_dev.h" - -#include "rtl_eeprom.h" -#include "rtl_ps.h" -#include "rtl_pci.h" -#include "rtl_cam.h" - -#define DRV_COPYRIGHT \ - "Copyright(c) 2008 - 2010 Realsil Semiconductor Corporation" -#define DRV_AUTHOR "" -#define DRV_VERSION "0014.0401.2010" - -#define TOTAL_CAM_ENTRY 32 -#define CAM_CONTENT_COUNT 8 - -#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 -#define HAL_HW_PCI_REVISION_ID_8192SE 0x10 - -#define RTLLIB_WATCH_DOG_TIME 2000 - -#define MAX_DEV_ADDR_SIZE 8 /*support till 64 bit bus width OS*/ -#define MAX_FIRMWARE_INFORMATION_SIZE 32 -#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) -#define ENCRYPTION_MAX_OVERHEAD 128 -#define MAX_FRAGMENT_COUNT 8 -#define MAX_TRANSMIT_BUFFER_SIZE \ - (1600 + (MAX_802_11_HEADER_LENGTH + ENCRYPTION_MAX_OVERHEAD) * \ - MAX_FRAGMENT_COUNT) - -#define CMDPACKET_FRAG_SIZE (4 * (MAX_TRANSMIT_BUFFER_SIZE / 4) - 8) - -#define DEFAULT_FRAG_THRESHOLD 2342U -#define MIN_FRAG_THRESHOLD 256U -#define DEFAULT_BEACONINTERVAL 0x64U - -#define DEFAULT_RETRY_RTS 7 -#define DEFAULT_RETRY_DATA 7 - -#define PHY_RSSI_SLID_WIN_MAX 100 - -#define TX_BB_GAIN_TABLE_LEN 37 -#define CCK_TX_BB_GAIN_TABLE_LEN 23 - -#define CHANNEL_PLAN_LEN 10 -#define S_CRC_LEN 4 - -#define NIC_SEND_HANG_THRESHOLD_NORMAL 4 -#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8 - -#define MAX_TX_QUEUE 9 - -#define MAX_RX_COUNT 64 -#define MAX_TX_QUEUE_COUNT 9 - -extern int hwwep; - -enum nic_t { - NIC_UNKNOWN = 0, - NIC_8192E = 1, - NIC_8190P = 2, - NIC_8192SE = 4, - NIC_8192CE = 5, - NIC_8192CU = 6, - NIC_8192DE = 7, - NIC_8192DU = 8, -}; - -enum rt_eeprom_type { - EEPROM_93C46, - EEPROM_93C56, -}; - -enum dcmg_txcmd_op { - TXCMD_TXRA_HISTORY_CTRL = 0xFF900000, - TXCMD_RESET_TX_PKT_BUFF = 0xFF900001, - TXCMD_RESET_RX_PKT_BUFF = 0xFF900002, - TXCMD_SET_TX_DURATION = 0xFF900003, - TXCMD_SET_RX_RSSI = 0xFF900004, - TXCMD_SET_TX_PWR_TRACKING = 0xFF900005, - TXCMD_XXXX_CTRL, -}; - -enum rt_customer_id { - RT_CID_DEFAULT = 0, - RT_CID_TOSHIBA = 9, - RT_CID_819X_NETCORE = 10, -}; - -enum reset_type { - RESET_TYPE_NORESET = 0x00, - RESET_TYPE_SILENT = 0x02 -}; - -struct rt_stats { - unsigned long received_rate_histogram[4][32]; - unsigned long txbytesunicast; - unsigned long rxbytesunicast; - unsigned long txretrycount; - u8 last_packet_rate; - unsigned long slide_signal_strength[100]; - unsigned long slide_evm[100]; - unsigned long slide_rssi_total; - unsigned long slide_evm_total; - long signal_strength; - long last_signal_strength_inpercent; - long recv_signal_power; - u8 rx_rssi_percentage[4]; - u8 rx_evm_percentage[2]; - u32 slide_beacon_pwdb[100]; - u32 slide_beacon_total; - u32 CurrentShowTxate; -}; - -struct init_gain { - u8 xaagccore1; - u8 xbagccore1; - u8 xcagccore1; - u8 xdagccore1; - u8 cca; - -}; - -struct tx_ring { - u32 *desc; - u8 nStuckCount; - struct tx_ring *next; -} __packed; - -struct rtl8192_tx_ring { - struct tx_desc *desc; - dma_addr_t dma; - unsigned int idx; - unsigned int entries; - struct sk_buff_head queue; -}; - -struct r8192_priv { - struct pci_dev *pdev; - struct pci_dev *bridge_pdev; - - bool bfirst_after_down; - bool being_init_adapter; - - int irq; - short irq_enabled; - - short up; - short up_first_time; - struct delayed_work update_beacon_wq; - struct delayed_work watch_dog_wq; - struct delayed_work txpower_tracking_wq; - struct delayed_work rfpath_check_wq; - struct delayed_work gpio_change_rf_wq; - struct rtllib_device *rtllib; - - struct work_struct reset_wq; - - enum rt_customer_id customer_id; - - enum ht_channel_width current_chnl_bw; - struct bb_reg_definition phy_reg_def[4]; - struct rate_adaptive rate_adaptive; - - struct rt_firmware *fw_info; - enum rtl819x_loopback loopback_mode; - - struct timer_list watch_dog_timer; - struct timer_list fsync_timer; - struct timer_list gpio_polling_timer; - - spinlock_t irq_th_lock; - spinlock_t tx_lock; - spinlock_t rf_ps_lock; - spinlock_t ps_lock; - - struct sk_buff_head skb_queue; - - struct tasklet_struct irq_rx_tasklet; - struct tasklet_struct irq_tx_tasklet; - - struct mutex wx_mutex; - struct mutex rf_mutex; - struct mutex mutex; - - struct rt_stats stats; - struct iw_statistics wstats; - - struct rx_desc *rx_ring; - struct sk_buff *rx_buf[MAX_RX_COUNT]; - dma_addr_t rx_ring_dma; - unsigned int rx_idx; - int rxringcount; - u16 rxbuffersize; - - u32 receive_config; - u8 retry_data; - u8 retry_rts; - u16 rts; - - struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; - int txringcount; - atomic_t tx_pending[0x10]; - - u16 short_retry_limit; - u16 long_retry_limit; - - bool hw_radio_off; - bool blinked_ingpio; - u8 polling_timer_on; - - /**********************************************************/ - struct work_struct qos_activate; - - short promisc; - - short chan; - - u32 irq_mask[2]; - - u8 rf_mode; - enum nic_t card_8192; - u8 card_8192_version; - - u8 ic_cut; - char nick[IW_ESSID_MAX_SIZE + 1]; - u8 check_roaming_cnt; - - u32 silent_reset_rx_slot_index; - u32 silent_reset_rx_stuck_event[MAX_SILENT_RESET_RX_SLOT_NUM]; - - u16 basic_rate; - u8 short_preamble; - u8 dot11_current_preamble_mode; - u8 slot_time; - - bool autoload_fail_flag; - - short epromtype; - u16 eeprom_vid; - u16 eeprom_did; - u8 eeprom_customer_id; - - u8 eeprom_tx_pwr_level_cck[14]; - u8 eeprom_tx_pwr_level_ofdm24g[14]; - u16 eeprom_ant_pwr_diff; - u8 eeprom_thermal_meter; - u8 eeprom_crystal_cap; - - u8 eeprom_legacy_ht_tx_pwr_diff; - - u8 crystal_cap; - u8 thermal_meter[2]; - - u8 sw_chnl_in_progress; - u8 sw_chnl_stage; - u8 sw_chnl_step; - u8 set_bw_mode_in_progress; - - u8 n_cur_40mhz_prime_sc; - - u32 rf_reg_0value[4]; - u8 num_total_rf_path; - bool brfpath_rxenable[4]; - - bool tx_pwr_data_read_from_eeprom; - - u8 hw_rf_off_action; - - bool rf_change_in_progress; - bool set_rf_pwr_state_in_progress; - - u8 cck_pwr_enl; - u16 tssi_13dBm; - u32 pwr_track; - u8 cck_present_attn_20m_def; - u8 cck_present_attn_40m_def; - s8 cck_present_attn_diff; - s8 cck_present_attn; - long undecorated_smoothed_pwdb; - - u32 mcs_tx_pwr_level_org_offset[6]; - u8 tx_pwr_level_cck[14]; - u8 tx_pwr_level_ofdm_24g[14]; - u8 legacy_ht_tx_pwr_diff; - u8 antenna_tx_pwr_diff[3]; - - bool dynamic_tx_high_pwr; - bool dynamic_tx_low_pwr; - bool last_dtp_flag_high; - bool last_dtp_flag_low; - - u8 rfa_txpowertrackingindex; - u8 rfa_txpowertrackingindex_real; - u8 rfa_txpowertracking_default; - bool btxpower_tracking; - bool bcck_in_ch14; - - u8 txpower_count; - bool tx_pwr_tracking_init; - - u8 ofdm_index[2]; - u8 cck_index; - - u8 rec_cck_20m_idx; - u8 rec_cck_40m_idx; - - struct init_gain initgain_backup; - u8 def_initial_gain[4]; - bool bis_any_nonbepkts; - bool bcurrent_turbo_EDCA; - bool bis_cur_rdlstate; - - u32 rate_record; - u32 rate_count_diff_rec; - u32 continue_diff_count; - bool bswitch_fsync; - u8 framesync; - - u16 tx_counter; - u16 rx_ctr; -}; - -extern const struct ethtool_ops rtl819x_ethtool_ops; - -u8 rtl92e_readb(struct net_device *dev, int x); -u32 rtl92e_readl(struct net_device *dev, int x); -u16 rtl92e_readw(struct net_device *dev, int x); -void rtl92e_writeb(struct net_device *dev, int x, u8 y); -void rtl92e_writew(struct net_device *dev, int x, u16 y); -void rtl92e_writel(struct net_device *dev, int x, u32 y); - -void force_pci_posting(struct net_device *dev); - -void rtl92e_rx_enable(struct net_device *dev); -void rtl92e_tx_enable(struct net_device *dev); - -void rtl92e_hw_sleep_wq(void *data); -void rtl92e_commit(struct net_device *dev); - -void rtl92e_check_rfctrl_gpio_timer(struct timer_list *t); - -void rtl92e_hw_wakeup_wq(void *data); - -void rtl92e_reset_desc_ring(struct net_device *dev); -void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode); -void rtl92e_irq_enable(struct net_device *dev); -void rtl92e_config_rate(struct net_device *dev, u16 *rate_config); -void rtl92e_irq_disable(struct net_device *dev); - -long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index); -void rtl92e_update_rx_statistics(struct r8192_priv *priv, - struct rtllib_rx_stats *pprevious_stats); -u8 rtl92e_evm_db_to_percent(s8 value); -u8 rtl92e_rx_db_to_percent(s8 antpower); -void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats, - struct rtllib_rx_stats *ptarget_stats); -bool rtl92e_enable_nic(struct net_device *dev); - -bool rtl92e_set_rf_state(struct net_device *dev, - enum rt_rf_power_state state_to_set, - RT_RF_CHANGE_SOURCE change_source); -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c deleted file mode 100644 index 0c7f38a4a7db..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ /dev/null @@ -1,1857 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "rtl_dm.h" -#include "r8192E_hw.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" -#include "r8192E_cmdpkt.h" - -/*---------------------------Define Local Constant---------------------------*/ -static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { - 0x5e4322, - 0x5e4322, - 0x5ea44f, - 0x5e4322, - 0x604322, - 0xa44f, - 0x5e4322, - 0x5e4332 -}; - -static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = { - 0x5e4322, - 0x5e4322, - 0x5e4322, - 0x5e4322, - 0x604322, - 0xa44f, - 0x5e4322, - 0x5e4322 -}; - -static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { - 0x5e4322, - 0xa44f, - 0x5ea44f, - 0x5e4322, - 0x604322, - 0x5e4322, - 0x5e4322, - 0x5e4332 -}; - -const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN] = { - 0x7f8001fe, /* 12 dB */ - 0x788001e2, /* 11 dB */ - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1a00006c, - 0x1c800072, - 0x18000060, - 0x19800066, - 0x15800056, - 0x26c0005b, - 0x14400051, - 0x24400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, /* -24 dB */ -}; - -const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} -}; - -const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} -}; - -/*---------------------------Define Local Constant---------------------------*/ - - -/*------------------------Define global variable-----------------------------*/ -struct dig_t dm_digtable; - -static struct drx_path_sel dm_rx_path_sel_table; -/*------------------------Define global variable-----------------------------*/ - - -/*------------------------Define local variable------------------------------*/ -/*------------------------Define local variable------------------------------*/ - - - -/*---------------------Define local function prototype-----------------------*/ -static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev); - -static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev); -static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev); - -static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev); - -static void _rtl92e_dm_dig_init(struct net_device *dev); -static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev); -static void _rtl92e_dm_initial_gain(struct net_device *dev); -static void _rtl92e_dm_pd_th(struct net_device *dev); -static void _rtl92e_dm_cs_ratio(struct net_device *dev); - -static void _rtl92e_dm_init_cts_to_self(struct net_device *dev); - -static void _rtl92e_dm_check_edca_turbo(struct net_device *dev); -static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev); -static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev); -static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev); - -static void _rtl92e_dm_init_fsync(struct net_device *dev); -static void _rtl92e_dm_deinit_fsync(struct net_device *dev); - -static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev); -static void _rtl92e_dm_check_fsync(struct net_device *dev); -static void _rtl92e_dm_check_rf_ctrl_gpio(void *data); -static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t); - -/*---------------------Define local function prototype-----------------------*/ - -static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev); -static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev); - -static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev); -static void _rtl92e_dm_cts_to_self(struct net_device *dev); -/*---------------------------Define function prototype------------------------*/ - -void rtl92e_dm_init(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->undecorated_smoothed_pwdb = -1; - - _rtl92e_dm_init_dynamic_tx_power(dev); - - rtl92e_init_adaptive_rate(dev); - - _rtl92e_dm_dig_init(dev); - rtl92e_dm_init_edca_turbo(dev); - _rtl92e_dm_init_bandwidth_autoswitch(dev); - _rtl92e_dm_init_fsync(dev); - _rtl92e_dm_init_rx_path_selection(dev); - _rtl92e_dm_init_cts_to_self(dev); - - INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, (void *)_rtl92e_dm_check_rf_ctrl_gpio); -} - -void rtl92e_dm_deinit(struct net_device *dev) -{ - _rtl92e_dm_deinit_fsync(dev); -} - -void rtl92e_dm_watchdog(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->being_init_adapter) - return; - - _rtl92e_dm_check_txrateandretrycount(dev); - _rtl92e_dm_check_edca_turbo(dev); - - _rtl92e_dm_check_rate_adaptive(dev); - _rtl92e_dm_dynamic_tx_power(dev); - _rtl92e_dm_check_tx_power_tracking(dev); - - _rtl92e_dm_ctrl_initgain_byrssi(dev); - _rtl92e_dm_bandwidth_autoswitch(dev); - - _rtl92e_dm_check_rx_path_selection(dev); - _rtl92e_dm_check_fsync(dev); - - _rtl92e_dm_send_rssi_to_fw(dev); - _rtl92e_dm_cts_to_self(dev); -} - -void rtl92e_init_adaptive_rate(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rate_adaptive *pra = &priv->rate_adaptive; - - pra->ratr_state = DM_RATR_STA_MAX; - pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH; - pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5; - pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5; - - pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5; - pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M; - pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M; - - if (priv->customer_id == RT_CID_819X_NETCORE) - pra->ping_rssi_enable = 1; - else - pra->ping_rssi_enable = 0; - pra->ping_rssi_thresh_for_ra = 15; - - pra->upper_rssi_threshold_ratr = 0x000fc000; - pra->middle_rssi_threshold_ratr = 0x000ff000; - pra->low_rssi_threshold_ratr = 0x000ff001; - pra->low_rssi_threshold_ratr_40M = 0x000ff005; - pra->low_rssi_threshold_ratr_20M = 0x000ff001; - pra->ping_rssi_ratr = 0x0000000d; -} - -static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; - struct rate_adaptive *pra = &priv->rate_adaptive; - u32 current_ratr, target_ratr = 0; - u32 low_rssi_thresh_for_ra = 0, high_rssi_thresh_for_ra = 0; - bool bshort_gi_enabled = false; - static u8 ping_rssi_state; - - if (!priv->up) - return; - - if (priv->rtllib->mode != WIRELESS_MODE_N_24G) - return; - - if (priv->rtllib->link_state == MAC80211_LINKED) { - bshort_gi_enabled = (ht_info->cur_tx_bw40mhz && - ht_info->cur_short_gi_40mhz) || - (!ht_info->cur_tx_bw40mhz && - ht_info->cur_short_gi_20mhz); - - pra->upper_rssi_threshold_ratr = - (pra->upper_rssi_threshold_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - pra->middle_rssi_threshold_ratr = - (pra->middle_rssi_threshold_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - } else { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - } - pra->ping_rssi_ratr = - (pra->ping_rssi_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - if (pra->ratr_state == DM_RATR_STA_HIGH) { - high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra; - low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ? - (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); - } else if (pra->ratr_state == DM_RATR_STA_LOW) { - high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra; - low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ? - (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M); - } else { - high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra; - low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ? - (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); - } - - if (priv->undecorated_smoothed_pwdb >= - (long)high_rssi_thresh_for_ra) { - pra->ratr_state = DM_RATR_STA_HIGH; - target_ratr = pra->upper_rssi_threshold_ratr; - } else if (priv->undecorated_smoothed_pwdb >= - (long)low_rssi_thresh_for_ra) { - pra->ratr_state = DM_RATR_STA_MIDDLE; - target_ratr = pra->middle_rssi_threshold_ratr; - } else { - pra->ratr_state = DM_RATR_STA_LOW; - target_ratr = pra->low_rssi_threshold_ratr; - } - - if (pra->ping_rssi_enable) { - if (priv->undecorated_smoothed_pwdb < - (long)(pra->ping_rssi_thresh_for_ra + 5)) { - if ((priv->undecorated_smoothed_pwdb < - (long)pra->ping_rssi_thresh_for_ra) || - ping_rssi_state) { - pra->ratr_state = DM_RATR_STA_LOW; - target_ratr = pra->ping_rssi_ratr; - ping_rssi_state = 1; - } - } else { - ping_rssi_state = 0; - } - } - - if (priv->rtllib->get_half_nmode_support_by_aps_handler(dev)) - target_ratr &= 0xf00fffff; - - current_ratr = rtl92e_readl(dev, RATR0); - if (target_ratr != current_ratr) { - u32 ratr_value; - - ratr_value = target_ratr; - ratr_value &= ~(RATE_ALL_OFDM_2SS); - rtl92e_writel(dev, RATR0, ratr_value); - rtl92e_writeb(dev, UFWP, 1); - } - - } else { - pra->ratr_state = DM_RATR_STA_MAX; - } -} - -static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; - priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; - priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = false; - priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false; -} - -static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20 || - !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable) - return; - if (!priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz) { - if (priv->undecorated_smoothed_pwdb <= - priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz) - priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = true; - } else { - if (priv->undecorated_smoothed_pwdb >= - priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz) - priv->rtllib->bandwidth_auto_switch.forced_tx_20MHz = false; - } -} - -static u32 OFDMSwingTable[OFDM_TABLE_LEN] = { - 0x7f8001fe, - 0x71c001c7, - 0x65400195, - 0x5a400169, - 0x50800142, - 0x47c0011f, - 0x40000100, - 0x390000e4, - 0x32c000cb, - 0x2d4000b5, - 0x288000a2, - 0x24000090, - 0x20000080, - 0x1c800072, - 0x19800066, - 0x26c0005b, - 0x24400051, - 0x12000048, - 0x10000040 -}; - -static u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_LEN][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} -}; - -static u8 CCKSwingTable_Ch14[CCK_TABLE_LEN][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} -}; - -#define Pw_Track_Flag 0x11d -#define Tssi_Mea_Value 0x13c -#define Tssi_Report_Value1 0x134 -#define Tssi_Report_Value2 0x13e -#define FW_Busy_Flag 0x13f - -static void _rtl92e_dm_tx_update_tssi_weak_signal(struct net_device *dev) -{ - struct r8192_priv *p = rtllib_priv(dev); - - if (p->rfa_txpowertrackingindex > 0) { - p->rfa_txpowertrackingindex--; - if (p->rfa_txpowertrackingindex_real > 4) { - p->rfa_txpowertrackingindex_real--; - rtl92e_set_bb_reg(dev, - rOFDM0_XATxIQImbalance, - bMaskDWord, - dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); - } - } else { - rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord, dm_tx_bb_gain[4]); - } -} - -static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev) -{ - struct r8192_priv *p = rtllib_priv(dev); - - if (p->rfa_txpowertrackingindex < (TX_BB_GAIN_TABLE_LEN - 1)) { - p->rfa_txpowertrackingindex++; - p->rfa_txpowertrackingindex_real++; - rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord, - dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); - } else { - rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord, - dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN - 1]); - } -} - -static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - bool viviflag = false; - struct dcmd_txcmd tx_cmd; - int i = 0, j = 0, k = 0; - u8 tmp_report[5] = {0, 0, 0, 0, 0}; - u8 Pwr_Flag; - u16 Avg_TSSI_Meas, tssi_13dBm, Avg_TSSI_Meas_from_driver = 0; - u32 delta = 0; - - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - priv->rtllib->bdynamic_txpower_enable = false; - - for (j = 0; j <= 30; j++) { - tx_cmd.op = TXCMD_SET_TX_PWR_TRACKING; - tx_cmd.length = 4; - tx_cmd.value = priv->pwr_track >> 24; - rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_NORMAL, (u8 *)&tx_cmd, - sizeof(struct dcmd_txcmd)); - mdelay(1); - for (i = 0; i <= 30; i++) { - Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag); - - if (Pwr_Flag == 0) { - mdelay(1); - - if (priv->rtllib->rf_power_state != rf_on) { - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - return; - } - - continue; - } - - Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value); - - if (Avg_TSSI_Meas == 0) { - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - return; - } - - for (k = 0; k < 5; k++) { - if (k != 4) - tmp_report[k] = rtl92e_readb(dev, - Tssi_Report_Value1 + k); - else - tmp_report[k] = rtl92e_readb(dev, - Tssi_Report_Value2); - - if (tmp_report[k] <= 20) { - viviflag = true; - break; - } - } - - if (viviflag) { - rtl92e_writeb(dev, Pw_Track_Flag, 0); - viviflag = false; - for (k = 0; k < 5; k++) - tmp_report[k] = 0; - break; - } - - for (k = 0; k < 5; k++) - Avg_TSSI_Meas_from_driver += tmp_report[k]; - - Avg_TSSI_Meas_from_driver *= 100 / 5; - tssi_13dBm = priv->tssi_13dBm; - - if (Avg_TSSI_Meas_from_driver > tssi_13dBm) - delta = Avg_TSSI_Meas_from_driver - tssi_13dBm; - else - delta = tssi_13dBm - Avg_TSSI_Meas_from_driver; - - if (delta <= E_FOR_TX_POWER_TRACK) { - priv->rtllib->bdynamic_txpower_enable = true; - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - return; - } - if (Avg_TSSI_Meas_from_driver < tssi_13dBm - E_FOR_TX_POWER_TRACK) - _rtl92e_dm_tx_update_tssi_weak_signal(dev); - else - _rtl92e_dm_tx_update_tssi_strong_signal(dev); - - priv->cck_present_attn_diff - = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default; - - if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) - priv->cck_present_attn = - priv->cck_present_attn_20m_def + - priv->cck_present_attn_diff; - else - priv->cck_present_attn = - priv->cck_present_attn_40m_def + - priv->cck_present_attn_diff; - - if (priv->cck_present_attn > (CCK_TX_BB_GAIN_TABLE_LEN - 1)) - priv->cck_present_attn = CCK_TX_BB_GAIN_TABLE_LEN - 1; - if (priv->cck_present_attn < 0) - priv->cck_present_attn = 0; - - if (priv->cck_present_attn > -1 && - priv->cck_present_attn < CCK_TX_BB_GAIN_TABLE_LEN) { - if (priv->rtllib->current_network.channel == 14 && - !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else { - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - } - - if (priv->cck_present_attn_diff <= -12 || - priv->cck_present_attn_diff >= 24) { - priv->rtllib->bdynamic_txpower_enable = true; - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - return; - } - - rtl92e_writeb(dev, Pw_Track_Flag, 0); - Avg_TSSI_Meas_from_driver = 0; - for (k = 0; k < 5; k++) - tmp_report[k] = 0; - break; - } - rtl92e_writeb(dev, FW_Busy_Flag, 0); - } - priv->rtllib->bdynamic_txpower_enable = true; - rtl92e_writeb(dev, Pw_Track_Flag, 0); -} - -static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev) -{ -#define ThermalMeterVal 9 - struct r8192_priv *priv = rtllib_priv(dev); - u32 tmp_reg, tmp_cck; - u8 tmp_ofdm_index, tmp_cck_index, tmp_cck_20m_index, tmp_cck_40m_index, tmpval; - int i = 0, CCKSwingNeedUpdate = 0; - - if (!priv->tx_pwr_tracking_init) { - tmp_reg = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord); - for (i = 0; i < OFDM_TABLE_LEN; i++) { - if (tmp_reg == OFDMSwingTable[i]) - priv->ofdm_index[0] = i; - } - - tmp_cck = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2); - for (i = 0; i < CCK_TABLE_LEN; i++) { - if (tmp_cck == (u32)CCKSwingTable_Ch1_Ch13[i][0]) { - priv->cck_index = i; - break; - } - } - priv->tx_pwr_tracking_init = true; - return; - } - - tmp_reg = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078); - if (tmp_reg < 3 || tmp_reg > 13) - return; - if (tmp_reg >= 12) - tmp_reg = 12; - priv->thermal_meter[0] = ThermalMeterVal; - priv->thermal_meter[1] = ThermalMeterVal; - - if (priv->thermal_meter[0] >= (u8)tmp_reg) { - tmp_ofdm_index = 6 + (priv->thermal_meter[0] - (u8)tmp_reg); - tmp_cck_20m_index = tmp_ofdm_index; - tmp_cck_40m_index = tmp_cck_20m_index - 6; - if (tmp_ofdm_index >= OFDM_TABLE_LEN) - tmp_ofdm_index = OFDM_TABLE_LEN - 1; - if (tmp_cck_20m_index >= CCK_TABLE_LEN) - tmp_cck_20m_index = CCK_TABLE_LEN - 1; - if (tmp_cck_40m_index >= CCK_TABLE_LEN) - tmp_cck_40m_index = CCK_TABLE_LEN - 1; - } else { - tmpval = (u8)tmp_reg - priv->thermal_meter[0]; - if (tmpval >= 6) { - tmp_ofdm_index = 0; - tmp_cck_20m_index = 0; - } else { - tmp_ofdm_index = 6 - tmpval; - tmp_cck_20m_index = 6 - tmpval; - } - tmp_cck_40m_index = 0; - } - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - tmp_cck_index = tmp_cck_40m_index; - else - tmp_cck_index = tmp_cck_20m_index; - - priv->rec_cck_20m_idx = tmp_cck_20m_index; - priv->rec_cck_40m_idx = tmp_cck_40m_index; - - if (priv->rtllib->current_network.channel == 14 && - !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - CCKSwingNeedUpdate = 1; - } else if (priv->rtllib->current_network.channel != 14 && - priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - CCKSwingNeedUpdate = 1; - } - - if (priv->cck_index != tmp_cck_index) { - priv->cck_index = tmp_cck_index; - CCKSwingNeedUpdate = 1; - } - - if (CCKSwingNeedUpdate) - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - if (priv->ofdm_index[0] != tmp_ofdm_index) { - priv->ofdm_index[0] = tmp_ofdm_index; - rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, - OFDMSwingTable[priv->ofdm_index[0]]); - } - priv->txpower_count = 0; -} - -void rtl92e_dm_txpower_tracking_wq(void *data) -{ - struct r8192_priv *priv = container_of_dwork_rsl(data, - struct r8192_priv, txpower_tracking_wq); - struct net_device *dev = priv->rtllib->dev; - - if (priv->ic_cut >= IC_VersionCut_D) - _rtl92e_dm_tx_power_tracking_callback_tssi(dev); - else - _rtl92e_dm_tx_power_tracking_cb_thermal(dev); -} - -static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->btxpower_tracking = true; - priv->txpower_count = 0; - priv->tx_pwr_tracking_init = false; -} - -static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->rtllib->FwRWRF) - priv->btxpower_tracking = true; - else - priv->btxpower_tracking = false; - priv->txpower_count = 0; - priv->tx_pwr_tracking_init = false; -} - -void rtl92e_dm_init_txpower_tracking(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->ic_cut >= IC_VersionCut_D) - _rtl92e_dm_initialize_tx_power_tracking_tssi(dev); - else - _rtl92e_dm_init_tx_power_tracking_thermal(dev); -} - -static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static u32 tx_power_track_counter; - - if (rtl92e_readb(dev, 0x11e) == 1) - return; - if (!priv->btxpower_tracking) - return; - tx_power_track_counter++; - - if (tx_power_track_counter >= 180) { - schedule_delayed_work(&priv->txpower_tracking_wq, 0); - tx_power_track_counter = 0; - } -} - -static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static u8 TM_Trigger; - u8 TxPowerCheckCnt = 0; - - TxPowerCheckCnt = 2; - if (!priv->btxpower_tracking) - return; - - if (priv->txpower_count <= TxPowerCheckCnt) { - priv->txpower_count++; - return; - } - - if (!TM_Trigger) { - rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - TM_Trigger = 1; - return; - } - netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n"); - schedule_delayed_work(&priv->txpower_tracking_wq, 0); - TM_Trigger = 0; -} - -static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->ic_cut >= IC_VersionCut_D) - _rtl92e_dm_check_tx_power_tracking_tssi(dev); - else - _rtl92e_dm_check_tx_power_tracking_thermal(dev); -} - -static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev, - bool bInCH14) -{ - u32 TempVal; - struct r8192_priv *priv = rtllib_priv(dev); - u8 attenuation = priv->cck_present_attn; - - TempVal = 0; - if (!bInCH14) { - TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] + - (dm_cck_tx_bb_gain[attenuation][1] << 8)); - - rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) + - (dm_cck_tx_bb_gain[attenuation][3] << 8) + - (dm_cck_tx_bb_gain[attenuation][4] << 16) + - (dm_cck_tx_bb_gain[attenuation][5] << 24)); - rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] + - (dm_cck_tx_bb_gain[attenuation][7] << 8)); - - rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } else { - TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) + - (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8)); - - rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) + - (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) + - (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16) + - (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24)); - rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) + - (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8)); - - rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } -} - -static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev, - bool bInCH14) -{ - u32 TempVal; - struct r8192_priv *priv = rtllib_priv(dev); - - TempVal = 0; - if (!bInCH14) { - TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][0] + - (CCKSwingTable_Ch1_Ch13[priv->cck_index][1] << 8); - rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][2] + - (CCKSwingTable_Ch1_Ch13[priv->cck_index][3] << 8) + - (CCKSwingTable_Ch1_Ch13[priv->cck_index][4] << 16) + - (CCKSwingTable_Ch1_Ch13[priv->cck_index][5] << 24); - rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][6] + - (CCKSwingTable_Ch1_Ch13[priv->cck_index][7] << 8); - - rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } else { - TempVal = CCKSwingTable_Ch14[priv->cck_index][0] + - (CCKSwingTable_Ch14[priv->cck_index][1] << 8); - - rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = CCKSwingTable_Ch14[priv->cck_index][2] + - (CCKSwingTable_Ch14[priv->cck_index][3] << 8) + - (CCKSwingTable_Ch14[priv->cck_index][4] << 16) + - (CCKSwingTable_Ch14[priv->cck_index][5] << 24); - rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = CCKSwingTable_Ch14[priv->cck_index][6] + - (CCKSwingTable_Ch14[priv->cck_index][7] << 8); - - rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } -} - -void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->ic_cut >= IC_VersionCut_D) - _rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14); - else - _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14); -} - -static void _rtl92e_dm_dig_init(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT; - dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT; - - dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; - - dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; - dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; - - dm_digtable.rssi_val = 50; - dm_digtable.backoff_val = DM_DIG_BACKOFF; - dm_digtable.rx_gain_range_max = DM_DIG_MAX; - if (priv->customer_id == RT_CID_819X_NETCORE) - dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; - else - dm_digtable.rx_gain_range_min = DM_DIG_MIN; -} - -/*----------------------------------------------------------------------------- - * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm() - * - * Overview: Driver monitor RSSI and False Alarm to change initial gain. - Only change initial gain during link in progress. - * - * Input: IN PADAPTER pAdapter - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 03/04/2009 hpfan Create Version 0. - * - ******************************************************************************/ - -static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 i; - static u8 fw_dig; - - if (fw_dig <= 3) { - for (i = 0; i < 3; i++) - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); - fw_dig++; - } - - if (priv->rtllib->link_state == MAC80211_LINKED) - dm_digtable.cur_sta_connect_state = DIG_STA_CONNECT; - else - dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT; - - dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; - _rtl92e_dm_initial_gain(dev); - _rtl92e_dm_pd_th(dev); - _rtl92e_dm_cs_ratio(dev); - dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state; -} - -static void _rtl92e_dm_initial_gain(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 initial_gain = 0; - static u8 initialized, force_write; - - if (rtllib_act_scanning(priv->rtllib, true)) { - force_write = 1; - return; - } - - if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { - if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { - long gain_range = dm_digtable.rssi_val + 10 - - dm_digtable.backoff_val; - gain_range = clamp_t(long, gain_range, - dm_digtable.rx_gain_range_min, - dm_digtable.rx_gain_range_max); - dm_digtable.cur_ig_value = gain_range; - } else { - if (dm_digtable.cur_ig_value == 0) - dm_digtable.cur_ig_value = priv->def_initial_gain[0]; - else - dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; - } - } else { - dm_digtable.cur_ig_value = priv->def_initial_gain[0]; - dm_digtable.pre_ig_value = 0; - } - - if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1)) - force_write = 1; - - if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) - || !initialized || force_write) { - initial_gain = dm_digtable.cur_ig_value; - rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain); - rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain); - dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; - initialized = 1; - force_write = 0; - } -} - -static void _rtl92e_dm_pd_th(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static u8 initialized, force_write; - - if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { - if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { - if (dm_digtable.rssi_val >= - dm_digtable.rssi_high_power_highthresh) - dm_digtable.curpd_thstate = - DIG_PD_AT_HIGH_POWER; - else if (dm_digtable.rssi_val <= - dm_digtable.rssi_low_thresh) - dm_digtable.curpd_thstate = - DIG_PD_AT_LOW_POWER; - else if ((dm_digtable.rssi_val >= - dm_digtable.rssi_high_thresh) && - (dm_digtable.rssi_val < - dm_digtable.rssi_high_power_lowthresh)) - dm_digtable.curpd_thstate = - DIG_PD_AT_NORMAL_POWER; - else - dm_digtable.curpd_thstate = - dm_digtable.prepd_thstate; - } else { - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - } else { - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - - if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || - (initialized <= 3) || force_write) { - if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x00); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42); - } else if (dm_digtable.curpd_thstate == - DIG_PD_AT_NORMAL_POWER) { - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); - } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) { - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x10); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43); - } - dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; - if (initialized <= 3) - initialized++; - force_write = 0; - } -} - -static void _rtl92e_dm_cs_ratio(struct net_device *dev) -{ - static u8 initialized, force_write; - - if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { - if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { - if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; - else - dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; - } else { - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - } - } else { - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - } - - if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || - !initialized || force_write) { - if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) - rtl92e_writeb(dev, 0xa0a, 0x08); - else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) - rtl92e_writeb(dev, 0xa0a, 0xcd); - dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; - initialized = 1; - force_write = 0; - } -} - -void rtl92e_dm_init_edca_turbo(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->bcurrent_turbo_EDCA = false; - priv->rtllib->bis_any_nonbepkts = false; - priv->bis_cur_rdlstate = false; -} - -static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; - - static unsigned long lastTxOkCnt; - static unsigned long lastRxOkCnt; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - if (priv->rtllib->link_state != MAC80211_LINKED) - goto dm_CheckEdcaTurbo_EXIT; - if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO) - goto dm_CheckEdcaTurbo_EXIT; - - if (!priv->rtllib->bis_any_nonbepkts) { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - if (ht_info->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) { - if (curTxOkCnt > 4 * curRxOkCnt) { - if (priv->bis_cur_rdlstate || - !priv->bcurrent_turbo_EDCA) { - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_UL[ht_info->iot_peer]); - priv->bis_cur_rdlstate = false; - } - } else { - if (!priv->bis_cur_rdlstate || - !priv->bcurrent_turbo_EDCA) { - if (priv->rtllib->mode == WIRELESS_MODE_G) - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL_GMode[ht_info->iot_peer]); - else - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL[ht_info->iot_peer]); - priv->bis_cur_rdlstate = true; - } - } - priv->bcurrent_turbo_EDCA = true; - } else { - if (curRxOkCnt > 4 * curTxOkCnt) { - if (!priv->bis_cur_rdlstate || - !priv->bcurrent_turbo_EDCA) { - if (priv->rtllib->mode == WIRELESS_MODE_G) - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL_GMode[ht_info->iot_peer]); - else - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_DL[ht_info->iot_peer]); - priv->bis_cur_rdlstate = true; - } - } else { - if (priv->bis_cur_rdlstate || - !priv->bcurrent_turbo_EDCA) { - rtl92e_writel(dev, EDCAPARA_BE, - edca_setting_UL[ht_info->iot_peer]); - priv->bis_cur_rdlstate = false; - } - } - - priv->bcurrent_turbo_EDCA = true; - } - } else { - if (priv->bcurrent_turbo_EDCA) { - u8 tmp = AC0_BE; - - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM, - (u8 *)(&tmp)); - priv->bcurrent_turbo_EDCA = false; - } - } - -dm_CheckEdcaTurbo_EXIT: - priv->rtllib->bis_any_nonbepkts = false; - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; -} - -static void _rtl92e_dm_init_cts_to_self(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); - - priv->rtllib->bCTSToSelfEnable = true; -} - -static void _rtl92e_dm_cts_to_self(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); - struct rt_hi_throughput *ht_info = priv->rtllib->ht_info; - static unsigned long lastTxOkCnt; - static unsigned long lastRxOkCnt; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - if (!priv->rtllib->bCTSToSelfEnable) { - ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; - return; - } - if (ht_info->iot_peer == HT_IOT_PEER_BROADCOM) { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - if (curRxOkCnt > 4 * curTxOkCnt) - ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF; - else - ht_info->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF; - - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; - } -} - -static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) -{ - struct r8192_priv *priv = container_of_dwork_rsl(data, - struct r8192_priv, gpio_change_rf_wq); - struct net_device *dev = priv->rtllib->dev; - u8 tmp1byte; - enum rt_rf_power_state rf_power_state_to_set; - bool bActuallySet = false; - - if ((priv->up_first_time == 1) || (priv->being_init_adapter)) - return; - - if (priv->bfirst_after_down) - return; - - tmp1byte = rtl92e_readb(dev, GPI); - - rf_power_state_to_set = (tmp1byte & BIT(1)) ? rf_on : rf_off; - - if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) { - netdev_info(dev, "gpiochangeRF - HW Radio ON\n"); - priv->hw_radio_off = false; - bActuallySet = true; - } else if (!priv->hw_radio_off && (rf_power_state_to_set == rf_off)) { - netdev_info(dev, "gpiochangeRF - HW Radio OFF\n"); - priv->hw_radio_off = true; - bActuallySet = true; - } - - if (bActuallySet) { - mdelay(1000); - priv->hw_rf_off_action = 1; - rtl92e_set_rf_state(dev, rf_power_state_to_set, RF_CHANGE_BY_HW); - } -} - -void rtl92e_dm_rf_pathcheck_wq(void *data) -{ - struct r8192_priv *priv = container_of_dwork_rsl(data, - struct r8192_priv, - rfpath_check_wq); - struct net_device *dev = priv->rtllib->dev; - u8 rfpath, i; - - rfpath = rtl92e_readb(dev, 0xc04); - - for (i = 0; i < RF90_PATH_MAX; i++) { - if (rfpath & (0x01 << i)) - priv->brfpath_rxenable[i] = true; - else - priv->brfpath_rxenable[i] = false; - } - if (!dm_rx_path_sel_table.enable) - return; - - _rtl92e_dm_rx_path_sel_byrssi(dev); -} - -static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev) -{ - u8 i; - struct r8192_priv *priv = rtllib_priv(dev); - - dm_rx_path_sel_table.enable = 1; - dm_rx_path_sel_table.ss_th_low = RX_PATH_SEL_SS_TH_LOW; - dm_rx_path_sel_table.diff_th = RX_PATH_SEL_DIFF_TH; - if (priv->customer_id == RT_CID_819X_NETCORE) - dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2; - else - dm_rx_path_sel_table.cck_method = CCK_Rx_Version_1; - dm_rx_path_sel_table.disabled_rf = 0; - for (i = 0; i < 4; i++) { - dm_rx_path_sel_table.rf_rssi[i] = 50; - dm_rx_path_sel_table.cck_pwdb_sta[i] = -64; - dm_rx_path_sel_table.rf_enable_rssi_th[i] = 100; - } -} - -#define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \ - (cur_cck_pwdb > tmp_cck_sec_pwdb)) - -static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 i, max_rssi_index = 0, min_rssi_index = 0; - u8 sec_rssi_index = 0, rf_num = 0; - u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0; - u8 cck_default_Rx = 0x2; - u8 cck_optional_Rx = 0x3; - long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0; - u8 cck_rx_ver2_max_index = 0; - u8 cck_rx_ver2_sec_index = 0; - u8 cur_rf_rssi; - long cur_cck_pwdb; - static u8 disabled_rf_cnt, cck_Rx_Path_initialized; - u8 update_cck_rx_path; - - if (!cck_Rx_Path_initialized) { - dm_rx_path_sel_table.cck_rx_path = (rtl92e_readb(dev, 0xa07) & 0xf); - cck_Rx_Path_initialized = 1; - } - - dm_rx_path_sel_table.disabled_rf = 0xf; - dm_rx_path_sel_table.disabled_rf &= ~(rtl92e_readb(dev, 0xc04)); - - if (priv->rtllib->mode == WIRELESS_MODE_B) - dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2; - - for (i = 0; i < RF90_PATH_MAX; i++) { - dm_rx_path_sel_table.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; - - if (!priv->brfpath_rxenable[i]) - continue; - - rf_num++; - cur_rf_rssi = dm_rx_path_sel_table.rf_rssi[i]; - - if (rf_num == 1) { - max_rssi_index = min_rssi_index = sec_rssi_index = i; - tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; - } else if (rf_num == 2) { - if (cur_rf_rssi >= tmp_max_rssi) { - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } else { - tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; - sec_rssi_index = min_rssi_index = i; - } - } else { - if (cur_rf_rssi > tmp_max_rssi) { - tmp_sec_rssi = tmp_max_rssi; - sec_rssi_index = max_rssi_index; - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } else if (cur_rf_rssi == tmp_max_rssi) { - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } else if ((cur_rf_rssi < tmp_max_rssi) && - (cur_rf_rssi > tmp_sec_rssi)) { - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } else if (cur_rf_rssi == tmp_sec_rssi) { - if (tmp_sec_rssi == tmp_min_rssi) { - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } - } else if ((cur_rf_rssi < tmp_sec_rssi) && - (cur_rf_rssi > tmp_min_rssi)) { - ; - } else if (cur_rf_rssi == tmp_min_rssi) { - if (tmp_sec_rssi == tmp_min_rssi) { - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } - } else if (cur_rf_rssi < tmp_min_rssi) { - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } - } - } - - rf_num = 0; - if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) { - for (i = 0; i < RF90_PATH_MAX; i++) { - if (!priv->brfpath_rxenable[i]) - continue; - - rf_num++; - cur_cck_pwdb = dm_rx_path_sel_table.cck_pwdb_sta[i]; - - if (rf_num == 1) { - cck_rx_ver2_max_index = i; - cck_rx_ver2_sec_index = i; - tmp_cck_max_pwdb = cur_cck_pwdb; - tmp_cck_min_pwdb = cur_cck_pwdb; - tmp_cck_sec_pwdb = cur_cck_pwdb; - } else if (rf_num == 2) { - if (cur_cck_pwdb >= tmp_cck_max_pwdb) { - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } else { - tmp_cck_sec_pwdb = cur_cck_pwdb; - tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } - } else { - if (cur_cck_pwdb > tmp_cck_max_pwdb) { - tmp_cck_sec_pwdb = tmp_cck_max_pwdb; - cck_rx_ver2_sec_index = cck_rx_ver2_max_index; - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } else if (cur_cck_pwdb == tmp_cck_max_pwdb) { - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } else if (PWDB_IN_RANGE) { - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } else if (cur_cck_pwdb == tmp_cck_sec_pwdb) { - if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } - } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && - (cur_cck_pwdb > tmp_cck_min_pwdb)) { - ; - } else if (cur_cck_pwdb == tmp_cck_min_pwdb) { - if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) - tmp_cck_min_pwdb = cur_cck_pwdb; - } else if (cur_cck_pwdb < tmp_cck_min_pwdb) { - tmp_cck_min_pwdb = cur_cck_pwdb; - } - } - } - } - - update_cck_rx_path = 0; - if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) { - cck_default_Rx = cck_rx_ver2_max_index; - cck_optional_Rx = cck_rx_ver2_sec_index; - if (tmp_cck_max_pwdb != -64) - update_cck_rx_path = 1; - } - - if (tmp_min_rssi < dm_rx_path_sel_table.ss_th_low && disabled_rf_cnt < 2) { - if ((tmp_max_rssi - tmp_min_rssi) >= - dm_rx_path_sel_table.diff_th) { - dm_rx_path_sel_table.rf_enable_rssi_th[min_rssi_index] = - tmp_max_rssi + 5; - rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, - 0x1 << min_rssi_index, 0x0); - rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, - 0x1 << min_rssi_index, 0x0); - disabled_rf_cnt++; - } - if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_1) { - cck_default_Rx = max_rssi_index; - cck_optional_Rx = sec_rssi_index; - if (tmp_max_rssi) - update_cck_rx_path = 1; - } - } - - if (update_cck_rx_path) { - dm_rx_path_sel_table.cck_rx_path = (cck_default_Rx << 2) | - (cck_optional_Rx); - rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000, - dm_rx_path_sel_table.cck_rx_path); - } - - if (dm_rx_path_sel_table.disabled_rf) { - for (i = 0; i < 4; i++) { - if ((dm_rx_path_sel_table.disabled_rf >> i) & 0x1) { - if (tmp_max_rssi >= - dm_rx_path_sel_table.rf_enable_rssi_th[i]) { - rtl92e_set_bb_reg(dev, - rOFDM0_TRxPathEnable, - 0x1 << i, 0x1); - rtl92e_set_bb_reg(dev, - rOFDM1_TRxPathEnable, - 0x1 << i, 0x1); - dm_rx_path_sel_table.rf_enable_rssi_th[i] - = 100; - disabled_rf_cnt--; - } - } - } - } -} - -static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - schedule_delayed_work(&priv->rfpath_check_wq, 0); -} - -static void _rtl92e_dm_init_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->rtllib->fsync_time_interval = 500; - priv->rtllib->fsync_rate_bitmap = 0x0f000800; - priv->rtllib->fsync_rssi_threshold = 30; - priv->rtllib->bfsync_enable = false; - priv->rtllib->fsync_multiple_timeinterval = 3; - priv->rtllib->fsync_firstdiff_ratethreshold = 100; - priv->rtllib->fsync_seconddiff_ratethreshold = 200; - priv->rtllib->fsync_state = DEFAULT_FSYNC; - - timer_setup(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback, 0); -} - -static void _rtl92e_dm_deinit_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - del_timer_sync(&priv->fsync_timer); -} - -static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t) -{ - struct r8192_priv *priv = from_timer(priv, t, fsync_timer); - struct net_device *dev = priv->rtllib->dev; - u32 rate_index, rate_count = 0, rate_count_diff = 0; - bool bSwitchFromCountDiff = false; - bool bDoubleTimeInterval = false; - - if (priv->rtllib->link_state == MAC80211_LINKED && - priv->rtllib->bfsync_enable && - (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_CDD_FSYNC)) { - u32 rate_bitmap; - - for (rate_index = 0; rate_index <= 27; rate_index++) { - rate_bitmap = 1 << rate_index; - if (priv->rtllib->fsync_rate_bitmap & rate_bitmap) - rate_count += - priv->stats.received_rate_histogram[1] - [rate_index]; - } - - if (rate_count < priv->rate_record) - rate_count_diff = 0xffffffff - rate_count + - priv->rate_record; - else - rate_count_diff = rate_count - priv->rate_record; - if (rate_count_diff < priv->rate_count_diff_rec) { - u32 DiffNum = priv->rate_count_diff_rec - - rate_count_diff; - if (DiffNum >= - priv->rtllib->fsync_seconddiff_ratethreshold) - priv->continue_diff_count++; - else - priv->continue_diff_count = 0; - - if (priv->continue_diff_count >= 2) { - bSwitchFromCountDiff = true; - priv->continue_diff_count = 0; - } - } else { - priv->continue_diff_count = 0; - } - - if (rate_count_diff <= - priv->rtllib->fsync_firstdiff_ratethreshold) { - bSwitchFromCountDiff = true; - priv->continue_diff_count = 0; - } - priv->rate_record = rate_count; - priv->rate_count_diff_rec = rate_count_diff; - if (priv->undecorated_smoothed_pwdb > - priv->rtllib->fsync_rssi_threshold && - bSwitchFromCountDiff) { - bDoubleTimeInterval = true; - priv->bswitch_fsync = !priv->bswitch_fsync; - if (priv->bswitch_fsync) { - rtl92e_writeb(dev, 0xC36, 0x1c); - rtl92e_writeb(dev, 0xC3e, 0x90); - } else { - rtl92e_writeb(dev, 0xC36, 0x5c); - rtl92e_writeb(dev, 0xC3e, 0x96); - } - } else if (priv->undecorated_smoothed_pwdb <= - priv->rtllib->fsync_rssi_threshold) { - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - rtl92e_writeb(dev, 0xC36, 0x5c); - rtl92e_writeb(dev, 0xC3e, 0x96); - } - } - if (bDoubleTimeInterval) { - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->rtllib->fsync_time_interval * - priv->rtllib->fsync_multiple_timeinterval); - add_timer(&priv->fsync_timer); - } else { - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->rtllib->fsync_time_interval); - add_timer(&priv->fsync_timer); - } - } else { - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - rtl92e_writeb(dev, 0xC36, 0x5c); - rtl92e_writeb(dev, 0xC3e, 0x96); - } - priv->continue_diff_count = 0; - rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); - } -} - -static void _rtl92e_dm_start_hw_fsync(struct net_device *dev) -{ - u8 rf_timing = 0x77; - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf); - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING, - (u8 *)(&rf_timing)); - rtl92e_writeb(dev, 0xc3b, 0x41); -} - -static void _rtl92e_dm_end_hw_fsync(struct net_device *dev) -{ - u8 rf_timing = 0xaa; - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); - priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING, (u8 *) - (&rf_timing)); - rtl92e_writeb(dev, 0xc3b, 0x49); -} - -static void _rtl92e_dm_end_sw_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - del_timer_sync(&(priv->fsync_timer)); - - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - - rtl92e_writeb(dev, 0xC36, 0x5c); - - rtl92e_writeb(dev, 0xC3e, 0x96); - } - - priv->continue_diff_count = 0; - rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); -} - -static void _rtl92e_dm_start_sw_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 rate_index; - u32 rate_bitmap; - - priv->rate_record = 0; - priv->continue_diff_count = 0; - priv->rate_count_diff_rec = 0; - priv->bswitch_fsync = false; - - if (priv->rtllib->mode == WIRELESS_MODE_N_24G) { - priv->rtllib->fsync_firstdiff_ratethreshold = 600; - priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff; - } else { - priv->rtllib->fsync_firstdiff_ratethreshold = 200; - priv->rtllib->fsync_seconddiff_ratethreshold = 200; - } - for (rate_index = 0; rate_index <= 27; rate_index++) { - rate_bitmap = 1 << rate_index; - if (priv->rtllib->fsync_rate_bitmap & rate_bitmap) - priv->rate_record += - priv->stats.received_rate_histogram[1] - [rate_index]; - } - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->rtllib->fsync_time_interval); - add_timer(&priv->fsync_timer); - - rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd); -} - -static void _rtl92e_dm_check_fsync(struct net_device *dev) -{ -#define RegC38_Default 0 -#define RegC38_NonFsync_Other_AP 1 -#define RegC38_Fsync_AP_BCM 2 - struct r8192_priv *priv = rtllib_priv(dev); - static u8 reg_c38_State = RegC38_Default; - - if (priv->rtllib->link_state == MAC80211_LINKED && - priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) { - if (priv->rtllib->bfsync_enable == 0) { - switch (priv->rtllib->fsync_state) { - case DEFAULT_FSYNC: - _rtl92e_dm_start_hw_fsync(dev); - priv->rtllib->fsync_state = HW_FSYNC; - break; - case SW_FSYNC: - _rtl92e_dm_end_sw_fsync(dev); - _rtl92e_dm_start_hw_fsync(dev); - priv->rtllib->fsync_state = HW_FSYNC; - break; - default: - break; - } - } else { - switch (priv->rtllib->fsync_state) { - case DEFAULT_FSYNC: - _rtl92e_dm_start_sw_fsync(dev); - priv->rtllib->fsync_state = SW_FSYNC; - break; - case HW_FSYNC: - _rtl92e_dm_end_hw_fsync(dev); - _rtl92e_dm_start_sw_fsync(dev); - priv->rtllib->fsync_state = SW_FSYNC; - break; - default: - break; - } - } - if (reg_c38_State != RegC38_Fsync_AP_BCM) { - rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95); - - reg_c38_State = RegC38_Fsync_AP_BCM; - } - } else { - switch (priv->rtllib->fsync_state) { - case HW_FSYNC: - _rtl92e_dm_end_hw_fsync(dev); - priv->rtllib->fsync_state = DEFAULT_FSYNC; - break; - case SW_FSYNC: - _rtl92e_dm_end_sw_fsync(dev); - priv->rtllib->fsync_state = DEFAULT_FSYNC; - break; - default: - break; - } - - if (priv->rtllib->link_state == MAC80211_LINKED) { - if (priv->undecorated_smoothed_pwdb <= - REG_C38_TH) { - if (reg_c38_State != - RegC38_NonFsync_Other_AP) { - rtl92e_writeb(dev, - rOFDM0_RxDetector3, - 0x90); - - reg_c38_State = - RegC38_NonFsync_Other_AP; - } - } else if (priv->undecorated_smoothed_pwdb >= - (REG_C38_TH + 5)) { - if (reg_c38_State) { - rtl92e_writeb(dev, - rOFDM0_RxDetector3, - priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } else { - if (reg_c38_State) { - rtl92e_writeb(dev, rOFDM0_RxDetector3, - priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } -} - -/*---------------------------Define function prototype------------------------*/ -static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->rtllib->bdynamic_txpower_enable = true; - priv->last_dtp_flag_high = false; - priv->last_dtp_flag_low = false; - priv->dynamic_tx_high_pwr = false; - priv->dynamic_tx_low_pwr = false; -} - -static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - unsigned int txhipower_threshold = 0; - unsigned int txlowpower_threshold = 0; - - if (!priv->rtllib->bdynamic_txpower_enable) { - priv->dynamic_tx_high_pwr = false; - priv->dynamic_tx_low_pwr = false; - return; - } - if ((priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_ATHEROS) && - (priv->rtllib->mode == WIRELESS_MODE_G)) { - txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH; - txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; - } else { - txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH; - txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; - } - - if (priv->rtllib->link_state == MAC80211_LINKED) { - if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) { - priv->dynamic_tx_high_pwr = true; - priv->dynamic_tx_low_pwr = false; - } else { - if (priv->undecorated_smoothed_pwdb < - txlowpower_threshold && priv->dynamic_tx_high_pwr) - priv->dynamic_tx_high_pwr = false; - if (priv->undecorated_smoothed_pwdb < 35) - priv->dynamic_tx_low_pwr = true; - else if (priv->undecorated_smoothed_pwdb >= 40) - priv->dynamic_tx_low_pwr = false; - } - } else { - priv->dynamic_tx_high_pwr = false; - priv->dynamic_tx_low_pwr = false; - } - - if ((priv->dynamic_tx_high_pwr != priv->last_dtp_flag_high) || - (priv->dynamic_tx_low_pwr != priv->last_dtp_flag_low)) { - rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel); - } - priv->last_dtp_flag_high = priv->dynamic_tx_high_pwr; - priv->last_dtp_flag_low = priv->dynamic_tx_low_pwr; -} - -static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev, CURRENT_TX_RATE_REG); - ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev, INITIAL_TX_RATE_REG); - ieee->softmac_stats.txretrycount = rtl92e_readl(dev, TX_RETRY_COUNT_REG); -} - -static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_writeb(dev, DRIVER_RSSI, priv->undecorated_smoothed_pwdb); -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h deleted file mode 100644 index 55641f17412b..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef __R8192UDM_H__ -#define __R8192UDM_H__ - -/*--------------------------Define Parameters-------------------------------*/ -#define OFDM_TABLE_LEN 19 -#define CCK_TABLE_LEN 12 - -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 -#define DM_DIG_HIGH_PWR_THRESH_LOW 70 - -#define BW_AUTO_SWITCH_HIGH_LOW 25 -#define BW_AUTO_SWITCH_LOW_HIGH 30 - -#define DM_DIG_BACKOFF 12 -#define DM_DIG_MAX 0x36 -#define DM_DIG_MIN 0x1c -#define DM_DIG_MIN_Netcore 0x12 - -#define RX_PATH_SEL_SS_TH_LOW 30 -#define RX_PATH_SEL_DIFF_TH 18 - -#define RATE_ADAPTIVE_TH_HIGH 50 -#define RATE_ADAPTIVE_TH_LOW_20M 30 -#define RATE_ADAPTIVE_TH_LOW_40M 10 -#define VERY_LOW_RSSI 15 - -#define E_FOR_TX_POWER_TRACK 300 -#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68 -#define TX_POWER_NEAR_FIELD_THRESH_LOW 62 -#define TX_POWER_ATHEROAP_THRESH_HIGH 78 -#define TX_POWER_ATHEROAP_THRESH_LOW 72 - -#define CURRENT_TX_RATE_REG 0x1e0 -#define INITIAL_TX_RATE_REG 0x1e1 -#define TX_RETRY_COUNT_REG 0x1ac -#define REG_C38_TH 20 - -/*--------------------------Define Parameters-------------------------------*/ - -/*------------------------------Define structure----------------------------*/ -struct dig_t { - long rssi_low_thresh; - long rssi_high_thresh; - - long rssi_high_power_lowthresh; - long rssi_high_power_highthresh; - - u8 cur_sta_connect_state; - u8 pre_sta_connect_state; - - u8 curpd_thstate; - u8 prepd_thstate; - u8 curcs_ratio_state; - u8 precs_ratio_state; - - u32 pre_ig_value; - u32 cur_ig_value; - - u8 backoff_val; - u8 rx_gain_range_max; - u8 rx_gain_range_min; - - long rssi_val; -}; - -enum dm_ratr_sta { - DM_RATR_STA_HIGH = 0, - DM_RATR_STA_MIDDLE = 1, - DM_RATR_STA_LOW = 2, - DM_RATR_STA_MAX -}; - -enum dm_dig_connect { - DIG_STA_DISCONNECT = 0, - DIG_STA_CONNECT = 1, -}; - -enum dm_dig_pd_th { - DIG_PD_AT_LOW_POWER = 0, - DIG_PD_AT_NORMAL_POWER = 1, - DIG_PD_AT_HIGH_POWER = 2, - DIG_PD_MAX -}; - -enum dm_dig_cs_ratio { - DIG_CS_RATIO_LOWER = 0, - DIG_CS_RATIO_HIGHER = 1, - DIG_CS_MAX -}; - -struct drx_path_sel { - u8 enable; - u8 cck_method; - u8 cck_rx_path; - - u8 ss_th_low; - u8 diff_th; - u8 disabled_rf; - u8 reserved; - - u8 rf_rssi[4]; - u8 rf_enable_rssi_th[4]; - long cck_pwdb_sta[4]; -}; - -enum dm_cck_rx_path_method { - CCK_Rx_Version_1 = 0, - CCK_Rx_Version_2 = 1, - CCK_Rx_Version_MAX -}; - -struct dcmd_txcmd { - u32 op; - u32 length; - u32 value; -}; - -/*------------------------------Define structure----------------------------*/ - -/*------------------------Export global variable----------------------------*/ -extern struct dig_t dm_digtable; - -/* Pre-calculated gain tables */ -extern const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN]; -extern const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8]; -extern const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8]; - -/*------------------------Export global variable----------------------------*/ - -/*--------------------------Exported Function prototype---------------------*/ -/*--------------------------Exported Function prototype---------------------*/ - -void rtl92e_dm_init(struct net_device *dev); -void rtl92e_dm_deinit(struct net_device *dev); - -void rtl92e_dm_watchdog(struct net_device *dev); - -void rtl92e_init_adaptive_rate(struct net_device *dev); -void rtl92e_dm_txpower_tracking_wq(void *data); - -void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14); - -void rtl92e_dm_init_edca_turbo(struct net_device *dev); -void rtl92e_dm_rf_pathcheck_wq(void *data); -void rtl92e_dm_init_txpower_tracking(struct net_device *dev); -#endif /*__R8192UDM_H__ */ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c deleted file mode 100644 index db57c655c695..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "rtl_eeprom.h" - -static void _rtl92e_gpio_write_bit(struct net_device *dev, int no, bool val) -{ - u8 reg = rtl92e_readb(dev, EPROM_CMD); - - if (val) - reg |= 1 << no; - else - reg &= ~(1 << no); - - rtl92e_writeb(dev, EPROM_CMD, reg); - udelay(EPROM_DELAY); -} - -static bool _rtl92e_gpio_get_bit(struct net_device *dev, int no) -{ - u8 reg = rtl92e_readb(dev, EPROM_CMD); - - return (reg >> no) & 0x1; -} - -static void _rtl92e_eeprom_ck_cycle(struct net_device *dev) -{ - _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 1); - _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 0); -} - -static u16 _rtl92e_eeprom_xfer(struct net_device *dev, u16 data, int tx_len) -{ - u16 ret = 0; - int rx_len = 16; - - _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 1); - _rtl92e_eeprom_ck_cycle(dev); - - while (tx_len--) { - _rtl92e_gpio_write_bit(dev, EPROM_W_BIT, - (data >> tx_len) & 0x1); - _rtl92e_eeprom_ck_cycle(dev); - } - - _rtl92e_gpio_write_bit(dev, EPROM_W_BIT, 0); - - while (rx_len--) { - _rtl92e_eeprom_ck_cycle(dev); - ret |= _rtl92e_gpio_get_bit(dev, EPROM_R_BIT) << rx_len; - } - - _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 0); - _rtl92e_eeprom_ck_cycle(dev); - - return ret; -} - -u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 ret = 0; - - rtl92e_writeb(dev, EPROM_CMD, - (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT)); - udelay(EPROM_DELAY); - - /* EEPROM is configured as x16 */ - if (priv->epromtype == EEPROM_93C56) - ret = _rtl92e_eeprom_xfer(dev, (addr & 0xFF) | (0x6 << 8), 11); - else - ret = _rtl92e_eeprom_xfer(dev, (addr & 0x3F) | (0x6 << 6), 9); - - rtl92e_writeb(dev, EPROM_CMD, - (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT)); - return ret; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h deleted file mode 100644 index 66f1979bb1d5..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#define EPROM_DELAY 10 - -u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c deleted file mode 100644 index fab8932e67da..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include -#include -#include - -#include "rtl_core.h" - -static void _rtl92e_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - strscpy(info->driver, DRV_NAME, sizeof(info->driver)); - strscpy(info->version, DRV_VERSION, sizeof(info->version)); - strscpy(info->bus_info, pci_name(priv->pdev), sizeof(info->bus_info)); -} - -static u32 _rtl92e_ethtool_get_link(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return ((priv->rtllib->link_state == MAC80211_LINKED) || - (priv->rtllib->link_state == MAC80211_LINKED_SCANNING)); -} - -const struct ethtool_ops rtl819x_ethtool_ops = { - .get_drvinfo = _rtl92e_ethtool_get_drvinfo, - .get_link = _rtl92e_ethtool_get_link, -}; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c deleted file mode 100644 index 1aa73561581b..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include "rtl_pci.h" -#include "rtl_core.h" - -static void _rtl92e_parse_pci_configuration(struct pci_dev *pdev, - struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - u8 tmp; - u16 link_ctrl_reg; - - pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg); - - pci_read_config_byte(pdev, 0x98, &tmp); - tmp |= BIT(4); - pci_write_config_byte(pdev, 0x98, tmp); - - tmp = 0x17; - pci_write_config_byte(pdev, 0x70f, tmp); -} - -bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - u16 device_id; - u8 revision_id; - u16 irq_line; - - device_id = pdev->device; - revision_id = pdev->revision; - pci_read_config_word(pdev, 0x3C, &irq_line); - - priv->card_8192 = NIC_8192E; - - if (device_id == 0x8192) { - switch (revision_id) { - case HAL_HW_PCI_REVISION_ID_8192PCIE: - dev_info(&pdev->dev, - "Adapter(8192 PCI-E) is found - DeviceID=%x\n", - device_id); - priv->card_8192 = NIC_8192E; - break; - case HAL_HW_PCI_REVISION_ID_8192SE: - dev_info(&pdev->dev, - "Adapter(8192SE) is found - DeviceID=%x\n", - device_id); - priv->card_8192 = NIC_8192SE; - break; - default: - dev_info(&pdev->dev, - "UNKNOWN nic type(%4x:%4x)\n", - pdev->vendor, pdev->device); - priv->card_8192 = NIC_UNKNOWN; - return false; - } - } - - if (priv->card_8192 != NIC_8192E) { - dev_info(&pdev->dev, - "Detect info(%x) and hardware info(%x) not match!\n", - NIC_8192E, priv->card_8192); - dev_info(&pdev->dev, - "Please select proper driver before install!!!!\n"); - return false; - } - - _rtl92e_parse_pci_configuration(pdev, dev); - - return true; -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h deleted file mode 100644 index 3e39c4835ac8..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#ifndef _RTL_PCI_H -#define _RTL_PCI_H - -#include -#include - -struct net_device; - -bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c deleted file mode 100644 index d124b5eee0cc..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtl_core.h" -#include "r8192E_hw.h" -#include "r8190P_rtl8256.h" -#include "rtl_pm.h" - -int rtl92e_suspend(struct device *dev_d) -{ - struct net_device *dev = dev_get_drvdata(dev_d); - struct r8192_priv *priv = rtllib_priv(dev); - u32 ulRegRead; - - netdev_info(dev, "============> r8192E suspend call.\n"); - del_timer_sync(&priv->gpio_polling_timer); - cancel_delayed_work_sync(&priv->gpio_change_rf_wq); - priv->polling_timer_on = 0; - - if (!netif_running(dev)) { - netdev_info(dev, - "RTL819XE:UI is open out of suspend function\n"); - goto out_pci_suspend; - } - - if (dev->netdev_ops->ndo_stop) - dev->netdev_ops->ndo_stop(dev); - netif_device_detach(dev); - - if (!priv->rtllib->bSupportRemoteWakeUp) { - rtl92e_set_rf_state(dev, rf_off, RF_CHANGE_BY_INIT); - ulRegRead = rtl92e_readl(dev, CPU_GEN); - ulRegRead |= CPU_GEN_SYSTEM_RESET; - rtl92e_writel(dev, CPU_GEN, ulRegRead); - } else { - rtl92e_writel(dev, WFCRC0, 0xffffffff); - rtl92e_writel(dev, WFCRC1, 0xffffffff); - rtl92e_writel(dev, WFCRC2, 0xffffffff); - rtl92e_writeb(dev, PMR, 0x5); - rtl92e_writeb(dev, MAC_BLK_CTRL, 0xa); - } -out_pci_suspend: - netdev_info(dev, "WOL is %s\n", priv->rtllib->bSupportRemoteWakeUp ? - "Supported" : "Not supported"); - device_set_wakeup_enable(dev_d, priv->rtllib->bSupportRemoteWakeUp); - - mdelay(20); - - return 0; -} - -int rtl92e_resume(struct device *dev_d) -{ - struct pci_dev *pdev = to_pci_dev(dev_d); - struct net_device *dev = dev_get_drvdata(dev_d); - struct r8192_priv *priv = rtllib_priv(dev); - u32 val; - - netdev_info(dev, "================>r8192E resume call.\n"); - - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - device_wakeup_disable(dev_d); - - if (priv->polling_timer_on == 0) - rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer); - - if (!netif_running(dev)) { - netdev_info(dev, - "RTL819XE:UI is open out of resume function\n"); - goto out; - } - - netif_device_attach(dev); - if (dev->netdev_ops->ndo_open) - dev->netdev_ops->ndo_open(dev); - - if (!priv->rtllib->bSupportRemoteWakeUp) - rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_INIT); - -out: - return 0; -} - diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h deleted file mode 100644 index fd8611495975..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef R8192E_PM_H -#define R8192E_PM_H - -#include -#include - -int rtl92e_suspend(struct device *dev_d); -int rtl92e_resume(struct device *dev_d); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c deleted file mode 100644 index 5aac9110bff6..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#include "rtl_ps.h" -#include "rtl_core.h" -#include "r8192E_phy.h" -#include "r8192E_phyreg.h" -#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ -#include "r8192E_cmdpkt.h" -#include - -static void _rtl92e_hw_sleep(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - unsigned long flags = 0; - - spin_lock_irqsave(&priv->rf_ps_lock, flags); - if (priv->rf_change_in_progress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - return; - } - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - rtl92e_set_rf_state(dev, rf_sleep, RF_CHANGE_BY_PS); -} - -void rtl92e_hw_sleep_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, hw_sleep_wq); - struct net_device *dev = ieee->dev; - - _rtl92e_hw_sleep(dev); -} - -void rtl92e_hw_wakeup(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - unsigned long flags = 0; - - spin_lock_irqsave(&priv->rf_ps_lock, flags); - if (priv->rf_change_in_progress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - schedule_delayed_work(&priv->rtllib->hw_wakeup_wq, - msecs_to_jiffies(10)); - return; - } - spin_unlock_irqrestore(&priv->rf_ps_lock, flags); - rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_PS); -} - -void rtl92e_hw_wakeup_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, hw_wakeup_wq); - struct net_device *dev = ieee->dev; - - rtl92e_hw_wakeup(dev); -} - -#define MIN_SLEEP_TIME 50 -#define MAX_SLEEP_TIME 10000 -void rtl92e_enter_sleep(struct net_device *dev, u64 time) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - u32 tmp; - unsigned long flags; - unsigned long timeout; - - spin_lock_irqsave(&priv->ps_lock, flags); - - time -= msecs_to_jiffies(8 + 16 + 7); - - timeout = jiffies + msecs_to_jiffies(MIN_SLEEP_TIME); - if (time_before((unsigned long)time, timeout)) { - spin_unlock_irqrestore(&priv->ps_lock, flags); - netdev_info(dev, "too short to sleep::%lld < %ld\n", - time - jiffies, msecs_to_jiffies(MIN_SLEEP_TIME)); - return; - } - timeout = jiffies + msecs_to_jiffies(MAX_SLEEP_TIME); - if (time_after((unsigned long)time, timeout)) { - netdev_info(dev, "========>too long to sleep:%lld > %ld\n", - time - jiffies, msecs_to_jiffies(MAX_SLEEP_TIME)); - spin_unlock_irqrestore(&priv->ps_lock, flags); - return; - } - tmp = time - jiffies; - schedule_delayed_work(&priv->rtllib->hw_wakeup_wq, tmp); - schedule_delayed_work(&priv->rtllib->hw_sleep_wq, 0); - spin_unlock_irqrestore(&priv->ps_lock, flags); -} - -static void _rtl92e_ps_update_rf_state(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - - psc->bSwRfProcessing = true; - rtl92e_set_rf_state(dev, psc->eInactivePowerState, RF_CHANGE_BY_IPS); - - psc->bSwRfProcessing = false; -} - -void rtl92e_ips_enter(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - enum rt_rf_power_state rt_state; - - rt_state = priv->rtllib->rf_power_state; - if (rt_state == rf_on && !psc->bSwRfProcessing && - (priv->rtllib->link_state != MAC80211_LINKED)) { - psc->eInactivePowerState = rf_off; - _rtl92e_ps_update_rf_state(dev); - } -} - -void rtl92e_ips_leave(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - enum rt_rf_power_state rt_state; - - rt_state = priv->rtllib->rf_power_state; - if (rt_state != rf_on && !psc->bSwRfProcessing && - priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { - psc->eInactivePowerState = rf_on; - _rtl92e_ps_update_rf_state(dev); - } -} - -void rtl92e_ips_leave_wq(void *data) -{ - struct rtllib_device *ieee = container_of(data, struct rtllib_device, ips_leave_wq); - struct net_device *dev = ieee->dev; - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); -} - -void rtl92e_rtllib_ips_leave_wq(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - enum rt_rf_power_state rt_state; - - rt_state = priv->rtllib->rf_power_state; - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - return; - } - netdev_info(dev, "=========>%s(): rtl92e_ips_leave\n", - __func__); - schedule_work(&priv->rtllib->ips_leave_wq); - } -} - -void rtl92e_rtllib_ips_leave(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); -} - -static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->rtllib->ps = rtPsMode; - if (priv->rtllib->sta_sleep != LPS_IS_WAKE && - rtPsMode == RTLLIB_PS_DISABLED) { - unsigned long flags; - - rtl92e_hw_wakeup(dev); - priv->rtllib->sta_sleep = LPS_IS_WAKE; - - spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags); - rtllib_sta_ps_send_null_frame(priv->rtllib, 0); - spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags); - } - - return true; -} - -void rtl92e_leisure_ps_enter(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - - if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && - (priv->rtllib->link_state == MAC80211_LINKED))) - return; - - if (psc->bLeisurePs) { - if (psc->lps_idle_count >= RT_CHECK_FOR_HANG_PERIOD) { - - if (priv->rtllib->ps == RTLLIB_PS_DISABLED) - _rtl92e_ps_set_mode(dev, RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST); - } else { - psc->lps_idle_count++; - } - } -} - -void rtl92e_leisure_ps_leave(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - - if (psc->bLeisurePs) { - if (priv->rtllib->ps != RTLLIB_PS_DISABLED) - _rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED); - } -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h deleted file mode 100644 index 70fe5d39be9a..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: wlanfae - */ -#ifndef _RTL_PS_H -#define _RTL_PS_H - -#include - -struct net_device; - -#define RT_CHECK_FOR_HANG_PERIOD 2 - -void rtl92e_hw_wakeup(struct net_device *dev); -void rtl92e_enter_sleep(struct net_device *dev, u64 time); -void rtl92e_rtllib_ips_leave_wq(struct net_device *dev); -void rtl92e_rtllib_ips_leave(struct net_device *dev); -void rtl92e_ips_leave_wq(void *data); - -void rtl92e_ips_enter(struct net_device *dev); -void rtl92e_ips_leave(struct net_device *dev); - -void rtl92e_leisure_ps_enter(struct net_device *dev); -void rtl92e_leisure_ps_leave(struct net_device *dev); - -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c deleted file mode 100644 index c21a0560410a..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ /dev/null @@ -1,866 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include -#include "rtl_core.h" -#include "rtl_wx.h" - -#define RATE_COUNT 12 -static u32 rtl8192_rates[] = { - 1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, - 18000000, 24000000, 36000000, 48000000, 54000000 -}; - -#ifndef ENETDOWN -#define ENETDOWN 1 -#endif - -static int _rtl92e_wx_get_freq(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b); -} - -static int _rtl92e_wx_get_mode(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b); -} - -static int _rtl92e_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra); -} - -static int _rtl92e_wx_set_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra); -} - -static int _rtl92e_wx_set_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) { - netdev_warn(dev, "%s(): Can't set Power: Radio is Off.\n", - __func__); - return 0; - } - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra); -} - -static int _rtl92e_wx_set_mode(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - enum rt_rf_power_state rt_state; - int ret; - - if (priv->hw_radio_off) - return 0; - rt_state = priv->rtllib->rf_power_state; - mutex_lock(&priv->wx_mutex); - if (wrqu->mode == IW_MODE_MONITOR) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > - RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return -1; - } - netdev_info(dev, - "=========>%s(): rtl92e_ips_leave\n", - __func__); - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); - } - } - ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - struct r8192_priv *priv = rtllib_priv(dev); - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - /* ~130 Mb/s real (802.11n) */ - range->throughput = 130 * 1000 * 1000; - - range->max_qual.qual = 100; - range->max_qual.level = 0; - range->max_qual.noise = 0; - range->max_qual.updated = 7; /* Updated all three */ - - range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ - range->avg_qual.level = 0; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - - range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES); - - for (i = 0; i < range->num_bitrates; i++) - range->bitrate[i] = rtl8192_rates[i]; - - range->max_rts = DEFAULT_RTS_THRESHOLD; - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->min_pmp = 0; - range->max_pmp = 5000000; - range->min_pmt = 0; - range->max_pmt = 65535 * 1000; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 18; - - for (i = 0, val = 0; i < 14; i++) { - if ((priv->rtllib->active_channel_map)[i + 1]) { - s32 freq_khz; - - range->freq[val].i = i + 1; - freq_khz = ieee80211_channel_to_freq_khz(i + 1, NL80211_BAND_2GHZ); - range->freq[val].m = freq_khz * 100; - range->freq[val].e = 1; - val++; - } - - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - range->num_channels = val; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE; - - /* Event capability (kernel + driver) */ - - return 0; -} - -static int _rtl92e_wx_set_scan(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - enum rt_rf_power_state rt_state; - int ret; - - if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) { - if ((ieee->link_state >= RTLLIB_ASSOCIATING) && - (ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED)) - return 0; - if ((priv->rtllib->link_state == MAC80211_LINKED) && - (priv->rtllib->cnt_after_link < 2)) - return 0; - } - - if (priv->hw_radio_off) { - netdev_info(dev, "================>%s(): hwradio off\n", - __func__); - return 0; - } - rt_state = priv->rtllib->rf_power_state; - if (!priv->up) - return -ENETDOWN; - if (priv->rtllib->link_detect_info.busy_traffic) - return -EAGAIN; - - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)b; - - if (req->essid_len) { - int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); - - ieee->current_network.ssid_len = len; - memcpy(ieee->current_network.ssid, req->essid, len); - } - } - - mutex_lock(&priv->wx_mutex); - - priv->rtllib->first_ie_in_scan = true; - - if (priv->rtllib->link_state != MAC80211_LINKED) { - if (rt_state == rf_off) { - if (priv->rtllib->rf_off_reason > - RF_CHANGE_BY_IPS) { - netdev_warn(dev, "%s(): RF is OFF.\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return -1; - } - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); - } - rtllib_stop_scan(priv->rtllib); - if (priv->rtllib->rf_power_state != rf_off) { - priv->rtllib->actscanning = true; - - ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); - - rtllib_start_scan_syncro(priv->rtllib); - - ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE); - } - ret = 0; - } else { - priv->rtllib->actscanning = true; - ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b); - } - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_get_scan(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (!priv->up) - return -ENETDOWN; - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - - if (priv->hw_radio_off) { - netdev_info(dev, - "=========>%s():hw radio off,or Rf state is rf_off, return\n", - __func__); - return 0; - } - mutex_lock(&priv->wx_mutex); - ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_set_nick(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (wrqu->data.length > IW_ESSID_MAX_SIZE) - return -E2BIG; - mutex_lock(&priv->wx_mutex); - wrqu->data.length = min_t(size_t, wrqu->data.length, - sizeof(priv->nick)); - memset(priv->nick, 0, sizeof(priv->nick)); - memcpy(priv->nick, extra, wrqu->data.length); - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int _rtl92e_wx_get_nick(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - mutex_lock(&priv->wx_mutex); - wrqu->data.length = strlen(priv->nick); - memcpy(extra, priv->nick, wrqu->data.length); - wrqu->data.flags = 1; /* active */ - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int _rtl92e_wx_set_freq(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra); -} - -static int _rtl92e_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - if (wrqu->frag.disabled) { - priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; - } else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - - priv->rtllib->fts = wrqu->frag.value & ~0x1; - } - - return 0; -} - -static int _rtl92e_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - wrqu->frag.value = priv->rtllib->fts; - wrqu->frag.fixed = 0; /* no auto select */ - wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); - - return 0; -} - -static int _rtl92e_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, char *extra) -{ - int ret; - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra); -} - -static int _rtl92e_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key); -} - -static int _rtl92e_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - - struct rtllib_device *ieee = priv->rtllib; - u32 hwkey[4] = {0, 0, 0, 0}; - u8 mask = 0xff; - u32 key_idx = 0; - u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; - int i; - - if (priv->hw_radio_off) - return 0; - - if (!priv->up) - return -ENETDOWN; - - priv->rtllib->wx_set_enc = 1; - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key); - mutex_unlock(&priv->wx_mutex); - - if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { - ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; - rtl92e_cam_reset(dev); - memset(priv->rtllib->swcamtable, 0, - sizeof(struct sw_cam_table) * 32); - goto end_hw_sec; - } - if (wrqu->encoding.length != 0) { - for (i = 0; i < 4; i++) { - hwkey[i] |= key[4 * i + 0] & mask; - if (i == 1 && (4 * i + 1) == wrqu->encoding.length) - mask = 0x00; - if (i == 3 && (4 * i + 1) == wrqu->encoding.length) - mask = 0x00; - hwkey[i] |= (key[4 * i + 1] & mask) << 8; - hwkey[i] |= (key[4 * i + 2] & mask) << 16; - hwkey[i] |= (key[4 * i + 3] & mask) << 24; - } - - switch (wrqu->encoding.flags & IW_ENCODE_INDEX) { - case 0: - key_idx = ieee->crypt_info.tx_keyidx; - break; - case 1: - key_idx = 0; - break; - case 2: - key_idx = 1; - break; - case 3: - key_idx = 2; - break; - case 4: - key_idx = 3; - break; - default: - break; - } - if (wrqu->encoding.length == 0x5) { - ieee->pairwise_key_type = KEY_TYPE_WEP40; - rtl92e_enable_hw_security_config(dev); - } - - else if (wrqu->encoding.length == 0xd) { - ieee->pairwise_key_type = KEY_TYPE_WEP104; - rtl92e_enable_hw_security_config(dev); - rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104, - zero_addr[key_idx], 0, hwkey); - rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104, - zero_addr[key_idx], hwkey); - } else { - netdev_info(dev, - "wrong type in WEP, not WEP40 and WEP104\n"); - } - } - -end_hw_sec: - priv->rtllib->wx_set_enc = 0; - return ret; -} - -#define R8192_MAX_RETRY 255 -static int _rtl92e_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int err = 0; - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - if (wrqu->retry.flags & IW_RETRY_LIFETIME || - wrqu->retry.disabled) { - err = -EINVAL; - goto exit; - } - if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { - err = -EINVAL; - goto exit; - } - - if (wrqu->retry.value > R8192_MAX_RETRY) { - err = -EINVAL; - goto exit; - } - if (wrqu->retry.flags & IW_RETRY_MAX) - priv->retry_rts = wrqu->retry.value; - else - priv->retry_data = wrqu->retry.value; - - rtl92e_commit(dev); -exit: - mutex_unlock(&priv->wx_mutex); - - return err; -} - -static int _rtl92e_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - wrqu->retry.disabled = 0; /* can't be disabled */ - - if ((wrqu->retry.flags & IW_RETRY_TYPE) == - IW_RETRY_LIFETIME) - return -EINVAL; - - if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - wrqu->retry.value = priv->retry_rts; - } else { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; - wrqu->retry.value = priv->retry_data; - } - return 0; -} - -static int _rtl92e_wx_set_encode_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - priv->rtllib->wx_set_enc = 1; - mutex_lock(&priv->rtllib->ips_mutex); - rtl92e_ips_leave(dev); - mutex_unlock(&priv->rtllib->ips_mutex); - - ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra); - { - const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const u8 zero[ETH_ALEN] = {0}; - u32 key[4] = {0}; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct iw_point *encoding = &wrqu->encoding; - u8 idx = 0, alg = 0, group = 0; - - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - ieee->pairwise_key_type = ieee->group_key_type - = KEY_TYPE_NA; - rtl92e_cam_reset(dev); - memset(priv->rtllib->swcamtable, 0, - sizeof(struct sw_cam_table) * 32); - goto end_hw_sec; - } - alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP : - ext->alg; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) - idx--; - group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; - - if ((!group) || (alg == KEY_TYPE_WEP40)) { - if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) - alg = KEY_TYPE_WEP104; - ieee->pairwise_key_type = alg; - rtl92e_enable_hw_security_config(dev); - } - memcpy((u8 *)key, ext->key, 16); - - if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { - if (ext->key_len == 13) - ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; - rtl92e_set_key(dev, idx, idx, alg, zero, 0, key); - rtl92e_set_swcam(dev, idx, idx, alg, zero, key); - } else if (group) { - ieee->group_key_type = alg; - rtl92e_set_key(dev, idx, idx, alg, broadcast_addr, 0, - key); - rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key); - } else { - if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && - ieee->ht_info->current_ht_support) - rtl92e_writeb(dev, 0x173, 1); - rtl92e_set_key(dev, 4, idx, alg, - (u8 *)ieee->ap_mac_addr, 0, key); - rtl92e_set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, key); - } - } - -end_hw_sec: - priv->rtllib->wx_set_enc = 0; - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret = 0; - - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - ret = rtllib_wx_set_auth(priv->rtllib, info, &data->param, extra); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret = 0; - - struct r8192_priv *priv = rtllib_priv(dev); - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int _rtl92e_wx_get_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - if (ieee->wpa_ie_len == 0 || !ieee->wpa_ie) { - data->data.length = 0; - return 0; - } - - if (data->data.length < ieee->wpa_ie_len) - return -E2BIG; - - data->data.length = ieee->wpa_ie_len; - memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); - return ret; -} - -#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT) -static iw_handler r8192_wx_handlers[] = { - [IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name, - [IW_IOCTL(SIOCSIWFREQ)] = _rtl92e_wx_set_freq, - [IW_IOCTL(SIOCGIWFREQ)] = _rtl92e_wx_get_freq, - [IW_IOCTL(SIOCSIWMODE)] = _rtl92e_wx_set_mode, - [IW_IOCTL(SIOCGIWMODE)] = _rtl92e_wx_get_mode, - [IW_IOCTL(SIOCGIWRANGE)] = _rtl92e_wx_get_range, - [IW_IOCTL(SIOCSIWAP)] = _rtl92e_wx_set_wap, - [IW_IOCTL(SIOCGIWAP)] = _rtl92e_wx_get_wap, - [IW_IOCTL(SIOCSIWSCAN)] = _rtl92e_wx_set_scan, - [IW_IOCTL(SIOCGIWSCAN)] = _rtl92e_wx_get_scan, - [IW_IOCTL(SIOCSIWESSID)] = _rtl92e_wx_set_essid, - [IW_IOCTL(SIOCGIWESSID)] = _rtl92e_wx_get_essid, - [IW_IOCTL(SIOCSIWNICKN)] = _rtl92e_wx_set_nick, - [IW_IOCTL(SIOCGIWNICKN)] = _rtl92e_wx_get_nick, - [IW_IOCTL(SIOCSIWRATE)] = _rtl92e_wx_set_rate, - [IW_IOCTL(SIOCGIWRATE)] = _rtl92e_wx_get_rate, - [IW_IOCTL(SIOCSIWRTS)] = _rtl92e_wx_set_rts, - [IW_IOCTL(SIOCGIWRTS)] = _rtl92e_wx_get_rts, - [IW_IOCTL(SIOCSIWFRAG)] = _rtl92e_wx_set_frag, - [IW_IOCTL(SIOCGIWFRAG)] = _rtl92e_wx_get_frag, - [IW_IOCTL(SIOCSIWRETRY)] = _rtl92e_wx_set_retry, - [IW_IOCTL(SIOCGIWRETRY)] = _rtl92e_wx_get_retry, - [IW_IOCTL(SIOCSIWENCODE)] = _rtl92e_wx_set_enc, - [IW_IOCTL(SIOCGIWENCODE)] = _rtl92e_wx_get_enc, - [IW_IOCTL(SIOCSIWPOWER)] = _rtl92e_wx_set_power, - [IW_IOCTL(SIOCGIWPOWER)] = _rtl92e_wx_get_power, - [IW_IOCTL(SIOCSIWGENIE)] = _rtl92e_wx_set_gen_ie, - [IW_IOCTL(SIOCGIWGENIE)] = _rtl92e_wx_get_gen_ie, - [IW_IOCTL(SIOCSIWMLME)] = _rtl92e_wx_set_mlme, - [IW_IOCTL(SIOCSIWAUTH)] = _rtl92e_wx_set_auth, - [IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext, -}; - -static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - struct iw_statistics *wstats = &priv->wstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - - if (ieee->link_state < MAC80211_LINKED) { - wstats->qual.qual = 10; - wstats->qual.level = 0; - wstats->qual.noise = 0x100 - 100; /* -100 dBm */ - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; - } - - tmp_level = (&ieee->current_network)->stats.rssi; - tmp_qual = (&ieee->current_network)->stats.signal; - tmp_noise = (&ieee->current_network)->stats.noise; - - wstats->qual.level = tmp_level; - wstats->qual.qual = tmp_qual; - wstats->qual.noise = tmp_noise; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; -} - -const struct iw_handler_def r8192_wx_handlers_def = { - .standard = r8192_wx_handlers, - .num_standard = ARRAY_SIZE(r8192_wx_handlers), - .get_wireless_stats = _rtl92e_get_wireless_stats, -}; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h deleted file mode 100644 index d70a747ac1dd..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef R819x_WX_H -#define R819x_WX_H - -struct iw_handler_def; - -extern const struct iw_handler_def r8192_wx_handlers_def; -#endif diff --git a/drivers/staging/rtl8192e/rtl8192e/table.c b/drivers/staging/rtl8192e/rtl8192e/table.c deleted file mode 100644 index 0b5cc6049232..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/table.c +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "table.h" - -u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN] = { - 0x800, 0x00000000, - 0x804, 0x00000001, - 0x808, 0x0000fc00, - 0x80c, 0x0000001c, - 0x810, 0x801010aa, - 0x814, 0x008514d0, - 0x818, 0x00000040, - 0x81c, 0x00000000, - 0x820, 0x00000004, - 0x824, 0x00690000, - 0x828, 0x00000004, - 0x82c, 0x00e90000, - 0x830, 0x00000004, - 0x834, 0x00690000, - 0x838, 0x00000004, - 0x83c, 0x00e90000, - 0x840, 0x00000000, - 0x844, 0x00000000, - 0x848, 0x00000000, - 0x84c, 0x00000000, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x65a965a9, - 0x85c, 0x65a965a9, - 0x860, 0x001f0010, - 0x864, 0x007f0010, - 0x868, 0x001f0010, - 0x86c, 0x007f0010, - 0x870, 0x0f100f70, - 0x874, 0x0f100f70, - 0x878, 0x00000000, - 0x87c, 0x00000000, - 0x880, 0x6870e36c, - 0x884, 0xe3573600, - 0x888, 0x4260c340, - 0x88c, 0x0000ff00, - 0x890, 0x00000000, - 0x894, 0xfffffffe, - 0x898, 0x4c42382f, - 0x89c, 0x00656056, - 0x8b0, 0x00000000, - 0x8e0, 0x00000000, - 0x8e4, 0x00000000, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x31121311, - 0xa00, 0x00d0c7d8, - 0xa04, 0x811f0008, - 0xa08, 0x80cd8300, - 0xa0c, 0x2e62740f, - 0xa10, 0x95009b78, - 0xa14, 0x11145008, - 0xa18, 0x00881117, - 0xa1c, 0x89140fa0, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00000000, - 0xc00, 0x00000040, - 0xc04, 0x00005433, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08000000, - 0xc1c, 0x40000100, - 0xc20, 0x08000000, - 0xc24, 0x40000100, - 0xc28, 0x08000000, - 0xc2c, 0x40000100, - 0xc30, 0x6de9ac44, - 0xc34, 0x465c52cd, - 0xc38, 0x497f5994, - 0xc3c, 0x0a969764, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020000, - 0xc4c, 0x00000300, - 0xc50, 0x69543420, - 0xc54, 0x433c0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x69543420, - 0xc64, 0x433c0094, - 0xc68, 0x69543420, - 0xc6c, 0x433c0094, - 0xc70, 0x2c7f000d, - 0xc74, 0x0186175b, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20000000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x40000100, - 0xc94, 0x00000000, - 0xc98, 0x40000100, - 0xc9c, 0x00000000, - 0xca0, 0x00492492, - 0xca4, 0x00000000, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x00492492, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xd00, 0x00000750, - 0xd04, 0x00000403, - 0xd08, 0x0000907f, - 0xd0c, 0x00000001, - 0xd10, 0xa0633333, - 0xd14, 0x33333c63, - 0xd18, 0x6a8f5b6b, - 0xd1c, 0x00000000, - 0xd20, 0x00000000, - 0xd24, 0x00000000, - 0xd28, 0x00000000, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x00000000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x024dbd02, - 0xd58, 0x00000000, - 0xd5c, 0x04032064, - 0xe00, 0x161a1a1a, - 0xe04, 0x12121416, - 0xe08, 0x00001800, - 0xe0c, 0x00000000, - 0xe10, 0x161a1a1a, - 0xe14, 0x12121416, - 0xe18, 0x161a1a1a, - 0xe1c, 0x12121416, -}; - -u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN] = { - 0x019, 0x00000003, - 0x000, 0x000000bf, - 0x001, 0x00000ee0, - 0x002, 0x0000004c, - 0x003, 0x000007f1, - 0x004, 0x00000975, - 0x005, 0x00000c58, - 0x006, 0x00000ae6, - 0x007, 0x000000ca, - 0x008, 0x00000e1c, - 0x009, 0x000007f0, - 0x00a, 0x000009d0, - 0x00b, 0x000001ba, - 0x00c, 0x00000240, - 0x00e, 0x00000020, - 0x00f, 0x00000990, - 0x012, 0x00000806, - 0x014, 0x000005ab, - 0x015, 0x00000f80, - 0x016, 0x00000020, - 0x017, 0x00000597, - 0x018, 0x0000050a, - 0x01a, 0x00000f80, - 0x01b, 0x00000f5e, - 0x01c, 0x00000008, - 0x01d, 0x00000607, - 0x01e, 0x000006cc, - 0x01f, 0x00000000, - 0x020, 0x000001a5, - 0x01f, 0x00000001, - 0x020, 0x00000165, - 0x01f, 0x00000002, - 0x020, 0x000000c6, - 0x01f, 0x00000003, - 0x020, 0x00000086, - 0x01f, 0x00000004, - 0x020, 0x00000046, - 0x01f, 0x00000005, - 0x020, 0x000001e6, - 0x01f, 0x00000006, - 0x020, 0x000001a6, - 0x01f, 0x00000007, - 0x020, 0x00000166, - 0x01f, 0x00000008, - 0x020, 0x000000c7, - 0x01f, 0x00000009, - 0x020, 0x00000087, - 0x01f, 0x0000000a, - 0x020, 0x000000f7, - 0x01f, 0x0000000b, - 0x020, 0x000000d7, - 0x01f, 0x0000000c, - 0x020, 0x000000b7, - 0x01f, 0x0000000d, - 0x020, 0x00000097, - 0x01f, 0x0000000e, - 0x020, 0x00000077, - 0x01f, 0x0000000f, - 0x020, 0x00000057, - 0x01f, 0x00000010, - 0x020, 0x00000037, - 0x01f, 0x00000011, - 0x020, 0x000000fb, - 0x01f, 0x00000012, - 0x020, 0x000000db, - 0x01f, 0x00000013, - 0x020, 0x000000bb, - 0x01f, 0x00000014, - 0x020, 0x000000ff, - 0x01f, 0x00000015, - 0x020, 0x000000e3, - 0x01f, 0x00000016, - 0x020, 0x000000c3, - 0x01f, 0x00000017, - 0x020, 0x000000a3, - 0x01f, 0x00000018, - 0x020, 0x00000083, - 0x01f, 0x00000019, - 0x020, 0x00000063, - 0x01f, 0x0000001a, - 0x020, 0x00000043, - 0x01f, 0x0000001b, - 0x020, 0x00000023, - 0x01f, 0x0000001c, - 0x020, 0x00000003, - 0x01f, 0x0000001d, - 0x020, 0x000001e3, - 0x01f, 0x0000001e, - 0x020, 0x000001c3, - 0x01f, 0x0000001f, - 0x020, 0x000001a3, - 0x01f, 0x00000020, - 0x020, 0x00000183, - 0x01f, 0x00000021, - 0x020, 0x00000163, - 0x01f, 0x00000022, - 0x020, 0x00000143, - 0x01f, 0x00000023, - 0x020, 0x00000123, - 0x01f, 0x00000024, - 0x020, 0x00000103, - 0x023, 0x00000203, - 0x024, 0x00000100, - 0x00b, 0x000001ba, - 0x02c, 0x000003d7, - 0x02d, 0x00000ff0, - 0x000, 0x00000037, - 0x004, 0x00000160, - 0x007, 0x00000080, - 0x002, 0x0000088d, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x016, 0x00000200, - 0x016, 0x00000380, - 0x016, 0x00000020, - 0x016, 0x000001a0, - 0x000, 0x000000bf, - 0x00d, 0x0000001f, - 0x00d, 0x00000c9f, - 0x002, 0x0000004d, - 0x000, 0x00000cbf, - 0x004, 0x00000975, - 0x007, 0x00000700, -}; - -u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN] = { - 0x019, 0x00000003, - 0x000, 0x000000bf, - 0x001, 0x000006e0, - 0x002, 0x0000004c, - 0x003, 0x000007f1, - 0x004, 0x00000975, - 0x005, 0x00000c58, - 0x006, 0x00000ae6, - 0x007, 0x000000ca, - 0x008, 0x00000e1c, - 0x000, 0x000000b7, - 0x00a, 0x00000850, - 0x000, 0x000000bf, - 0x00b, 0x000001ba, - 0x00c, 0x00000240, - 0x00e, 0x00000020, - 0x015, 0x00000f80, - 0x016, 0x00000020, - 0x017, 0x00000597, - 0x018, 0x0000050a, - 0x01a, 0x00000e00, - 0x01b, 0x00000f5e, - 0x01d, 0x00000607, - 0x01e, 0x000006cc, - 0x00b, 0x000001ba, - 0x023, 0x00000203, - 0x024, 0x00000100, - 0x000, 0x00000037, - 0x004, 0x00000160, - 0x016, 0x00000200, - 0x016, 0x00000380, - 0x016, 0x00000020, - 0x016, 0x000001a0, - 0x00d, 0x00000ccc, - 0x000, 0x000000bf, - 0x002, 0x0000004d, - 0x000, 0x00000cbf, - 0x004, 0x00000975, - 0x007, 0x00000700, -}; - -u32 RTL8192E_MACPHY_ARR[] = { - 0x03c, 0xffff0000, 0x00000f0f, - 0x340, 0xffffffff, 0x161a1a1a, - 0x344, 0xffffffff, 0x12121416, - 0x348, 0x0000ffff, 0x00001818, - 0x12c, 0xffffffff, 0x04000802, - 0x318, 0x00000fff, 0x00000100, -}; - -u32 RTL8192E_MACPHY_ARR_PG[] = { - 0x03c, 0xffff0000, 0x00000f0f, - 0xe00, 0xffffffff, 0x06090909, - 0xe04, 0xffffffff, 0x00030306, - 0xe08, 0x0000ff00, 0x00000000, - 0xe10, 0xffffffff, 0x0a0c0d0f, - 0xe14, 0xffffffff, 0x06070809, - 0xe18, 0xffffffff, 0x0a0c0d0f, - 0xe1c, 0xffffffff, 0x06070809, - 0x12c, 0xffffffff, 0x04000802, - 0x318, 0x00000fff, 0x00000800, -}; - -u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN] = { - 0xc78, 0x7d000001, - 0xc78, 0x7d010001, - 0xc78, 0x7d020001, - 0xc78, 0x7d030001, - 0xc78, 0x7d040001, - 0xc78, 0x7d050001, - 0xc78, 0x7c060001, - 0xc78, 0x7b070001, - 0xc78, 0x7a080001, - 0xc78, 0x79090001, - 0xc78, 0x780a0001, - 0xc78, 0x770b0001, - 0xc78, 0x760c0001, - 0xc78, 0x750d0001, - 0xc78, 0x740e0001, - 0xc78, 0x730f0001, - 0xc78, 0x72100001, - 0xc78, 0x71110001, - 0xc78, 0x70120001, - 0xc78, 0x6f130001, - 0xc78, 0x6e140001, - 0xc78, 0x6d150001, - 0xc78, 0x6c160001, - 0xc78, 0x6b170001, - 0xc78, 0x6a180001, - 0xc78, 0x69190001, - 0xc78, 0x681a0001, - 0xc78, 0x671b0001, - 0xc78, 0x661c0001, - 0xc78, 0x651d0001, - 0xc78, 0x641e0001, - 0xc78, 0x491f0001, - 0xc78, 0x48200001, - 0xc78, 0x47210001, - 0xc78, 0x46220001, - 0xc78, 0x45230001, - 0xc78, 0x44240001, - 0xc78, 0x43250001, - 0xc78, 0x28260001, - 0xc78, 0x27270001, - 0xc78, 0x26280001, - 0xc78, 0x25290001, - 0xc78, 0x242a0001, - 0xc78, 0x232b0001, - 0xc78, 0x222c0001, - 0xc78, 0x212d0001, - 0xc78, 0x202e0001, - 0xc78, 0x0a2f0001, - 0xc78, 0x08300001, - 0xc78, 0x06310001, - 0xc78, 0x05320001, - 0xc78, 0x04330001, - 0xc78, 0x03340001, - 0xc78, 0x02350001, - 0xc78, 0x01360001, - 0xc78, 0x00370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7d400001, - 0xc78, 0x7d410001, - 0xc78, 0x7d420001, - 0xc78, 0x7d430001, - 0xc78, 0x7d440001, - 0xc78, 0x7d450001, - 0xc78, 0x7c460001, - 0xc78, 0x7b470001, - 0xc78, 0x7a480001, - 0xc78, 0x79490001, - 0xc78, 0x784a0001, - 0xc78, 0x774b0001, - 0xc78, 0x764c0001, - 0xc78, 0x754d0001, - 0xc78, 0x744e0001, - 0xc78, 0x734f0001, - 0xc78, 0x72500001, - 0xc78, 0x71510001, - 0xc78, 0x70520001, - 0xc78, 0x6f530001, - 0xc78, 0x6e540001, - 0xc78, 0x6d550001, - 0xc78, 0x6c560001, - 0xc78, 0x6b570001, - 0xc78, 0x6a580001, - 0xc78, 0x69590001, - 0xc78, 0x685a0001, - 0xc78, 0x675b0001, - 0xc78, 0x665c0001, - 0xc78, 0x655d0001, - 0xc78, 0x645e0001, - 0xc78, 0x495f0001, - 0xc78, 0x48600001, - 0xc78, 0x47610001, - 0xc78, 0x46620001, - 0xc78, 0x45630001, - 0xc78, 0x44640001, - 0xc78, 0x43650001, - 0xc78, 0x28660001, - 0xc78, 0x27670001, - 0xc78, 0x26680001, - 0xc78, 0x25690001, - 0xc78, 0x246a0001, - 0xc78, 0x236b0001, - 0xc78, 0x226c0001, - 0xc78, 0x216d0001, - 0xc78, 0x206e0001, - 0xc78, 0x0a6f0001, - 0xc78, 0x08700001, - 0xc78, 0x06710001, - 0xc78, 0x05720001, - 0xc78, 0x04730001, - 0xc78, 0x03740001, - 0xc78, 0x02750001, - 0xc78, 0x01760001, - 0xc78, 0x00770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x2e00001e, - 0xc78, 0x2e01001e, - 0xc78, 0x2e02001e, - 0xc78, 0x2e03001e, - 0xc78, 0x2e04001e, - 0xc78, 0x2e05001e, - 0xc78, 0x3006001e, - 0xc78, 0x3407001e, - 0xc78, 0x3908001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3f0a001e, - 0xc78, 0x420b001e, - 0xc78, 0x440c001e, - 0xc78, 0x450d001e, - 0xc78, 0x460e001e, - 0xc78, 0x460f001e, - 0xc78, 0x4710001e, - 0xc78, 0x4811001e, - 0xc78, 0x4912001e, - 0xc78, 0x4a13001e, - 0xc78, 0x4b14001e, - 0xc78, 0x4b15001e, - 0xc78, 0x4c16001e, - 0xc78, 0x4d17001e, - 0xc78, 0x4e18001e, - 0xc78, 0x4f19001e, - 0xc78, 0x4f1a001e, - 0xc78, 0x501b001e, - 0xc78, 0x511c001e, - 0xc78, 0x521d001e, - 0xc78, 0x521e001e, - 0xc78, 0x531f001e, - 0xc78, 0x5320001e, - 0xc78, 0x5421001e, - 0xc78, 0x5522001e, - 0xc78, 0x5523001e, - 0xc78, 0x5624001e, - 0xc78, 0x5725001e, - 0xc78, 0x5726001e, - 0xc78, 0x5827001e, - 0xc78, 0x5828001e, - 0xc78, 0x5929001e, - 0xc78, 0x592a001e, - 0xc78, 0x5a2b001e, - 0xc78, 0x5b2c001e, - 0xc78, 0x5c2d001e, - 0xc78, 0x5c2e001e, - 0xc78, 0x5d2f001e, - 0xc78, 0x5e30001e, - 0xc78, 0x5f31001e, - 0xc78, 0x6032001e, - 0xc78, 0x6033001e, - 0xc78, 0x6134001e, - 0xc78, 0x6235001e, - 0xc78, 0x6336001e, - 0xc78, 0x6437001e, - 0xc78, 0x6438001e, - 0xc78, 0x6539001e, - 0xc78, 0x663a001e, - 0xc78, 0x673b001e, - 0xc78, 0x673c001e, - 0xc78, 0x683d001e, - 0xc78, 0x693e001e, - 0xc78, 0x6a3f001e, -}; diff --git a/drivers/staging/rtl8192e/rtl8192e/table.h b/drivers/staging/rtl8192e/rtl8192e/table.h deleted file mode 100644 index 82be44a9d4e8..000000000000 --- a/drivers/staging/rtl8192e/rtl8192e/table.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef __INC_HAL8192PciE_FW_IMG_H -#define __INC_HAL8192PciE_FW_IMG_H - -/*Created on 2008/11/18, 3: 7*/ - -#include - -#define RTL8192E_PHY_REG_1T2R_ARR_LEN 296 -extern u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN]; -#define RTL8192E_RADIO_A_ARR_LEN 246 -extern u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN]; -#define RTL8192E_RADIO_B_ARR_LEN 78 -extern u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN]; -#define RTL8192E_MACPHY_ARR_LEN 18 -extern u32 RTL8192E_MACPHY_ARR[RTL8192E_MACPHY_ARR_LEN]; -#define RTL8192E_MACPHY_ARR_PG_LEN 30 -extern u32 RTL8192E_MACPHY_ARR_PG[RTL8192E_MACPHY_ARR_PG_LEN]; -#define RTL8192E_AGCTAB_ARR_LEN 384 -extern u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN]; - -#endif diff --git a/drivers/staging/rtl8192e/rtl819x_BA.h b/drivers/staging/rtl8192e/rtl819x_BA.h deleted file mode 100644 index 8a35d7a3eee1..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_BA.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _BATYPE_H_ -#define _BATYPE_H_ - -#define BA_SETUP_TIMEOUT 200 - -#define BA_POLICY_DELAYED 0 -#define BA_POLICY_IMMEDIATE 1 - -#define ADDBA_STATUS_SUCCESS 0 -#define ADDBA_STATUS_REFUSED 37 -#define ADDBA_STATUS_INVALID_PARAM 38 - -#define DELBA_REASON_END_BA 37 -#define DELBA_REASON_UNKNOWN_BA 38 -#define DELBA_REASON_TIMEOUT 39 -union sequence_control { - u16 short_data; - struct { - u16 frag_num:4; - u16 seq_num:12; - } field; -}; - -union ba_param_set { - u8 char_data[2]; - u16 short_data; - struct { - u16 amsdu_support:1; - u16 ba_policy:1; - u16 tid:4; - u16 buffer_size:10; - } field; -}; - -union delba_param_set { - u8 char_data[2]; - u16 short_data; - struct { - u16 reserved:11; - u16 initiator:1; - u16 tid:4; - } field; -}; - -struct ba_record { - struct timer_list timer; - u8 b_valid; - u8 dialog_token; - union ba_param_set ba_param_set; - u16 ba_timeout_value; - union sequence_control ba_start_seq_ctrl; -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c deleted file mode 100644 index 834329886ea2..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ /dev/null @@ -1,544 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include -#include -#include -#include "rtllib.h" -#include "rtl819x_BA.h" - -static void activate_ba_entry(struct ba_record *ba, u16 time) -{ - ba->b_valid = true; - if (time != 0) - mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time)); -} - -static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba) -{ - ba->b_valid = false; - del_timer_sync(&ba->timer); -} - -static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *ts) -{ - struct ba_record *admitted_ba = &ts->tx_admitted_ba_record; - struct ba_record *pending_ba = &ts->tx_pending_ba_record; - u8 send_del_ba = false; - - if (pending_ba->b_valid) { - deactivate_ba_entry(ieee, pending_ba); - send_del_ba = true; - } - - if (admitted_ba->b_valid) { - deactivate_ba_entry(ieee, admitted_ba); - send_del_ba = true; - } - return send_del_ba; -} - -static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts) -{ - struct ba_record *ba = &ts->rx_admitted_ba_record; - u8 send_del_ba = false; - - if (ba->b_valid) { - deactivate_ba_entry(ieee, ba); - send_del_ba = true; - } - - return send_del_ba; -} - -void rtllib_reset_ba_entry(struct ba_record *ba) -{ - ba->b_valid = false; - ba->ba_param_set.short_data = 0; - ba->ba_timeout_value = 0; - ba->dialog_token = 0; - ba->ba_start_seq_ctrl.short_data = 0; -} - -static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst, - struct ba_record *ba, - u16 status_code, u8 type) -{ - struct sk_buff *skb = NULL; - struct ieee80211_hdr_3addr *ba_req = NULL; - u8 *tag = NULL; - u16 len = ieee->tx_headroom + 9; - - netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n", - __func__, type, dst, ieee->dev); - - if (!ba) { - netdev_warn(ieee->dev, "ba is NULL\n"); - return NULL; - } - skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr)); - if (!skb) - return NULL; - - memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr)); - - skb_reserve(skb, ieee->tx_headroom); - - ba_req = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); - - ether_addr_copy(ba_req->addr1, dst); - ether_addr_copy(ba_req->addr2, ieee->dev->dev_addr); - - ether_addr_copy(ba_req->addr3, ieee->current_network.bssid); - ba_req->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION); - - tag = skb_put(skb, 9); - *tag++ = ACT_CAT_BA; - *tag++ = type; - *tag++ = ba->dialog_token; - - if (type == ACT_ADDBARSP) { - put_unaligned_le16(status_code, tag); - tag += 2; - } - - put_unaligned_le16(ba->ba_param_set.short_data, tag); - tag += 2; - - put_unaligned_le16(ba->ba_timeout_value, tag); - tag += 2; - - if (type == ACT_ADDBAREQ) { - memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2); - tag += 2; - } - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, - __func__, skb->len); -#endif - return skb; -} - -static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, - struct ba_record *ba, - enum tr_select tx_rx_select, u16 reason_code) -{ - union delba_param_set del_ba_param_set; - struct sk_buff *skb = NULL; - struct ieee80211_hdr_3addr *del_ba = NULL; - u8 *tag = NULL; - u16 len = 6 + ieee->tx_headroom; - - if (net_ratelimit()) - netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n", - __func__, reason_code, dst); - - memset(&del_ba_param_set, 0, 2); - - del_ba_param_set.field.initiator = (tx_rx_select == TX_DIR) ? 1 : 0; - del_ba_param_set.field.tid = ba->ba_param_set.field.tid; - - skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr)); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - del_ba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); - - ether_addr_copy(del_ba->addr1, dst); - ether_addr_copy(del_ba->addr2, ieee->dev->dev_addr); - ether_addr_copy(del_ba->addr3, ieee->current_network.bssid); - del_ba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION); - - tag = skb_put(skb, 6); - - *tag++ = ACT_CAT_BA; - *tag++ = ACT_DELBA; - - put_unaligned_le16(del_ba_param_set.short_data, tag); - tag += 2; - - put_unaligned_le16(reason_code, tag); - tag += 2; - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, - __func__, skb->len); -#endif - return skb; -} - -static void rtllib_send_add_ba_req(struct rtllib_device *ieee, u8 *dst, - struct ba_record *ba) -{ - struct sk_buff *skb; - - skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ); - - if (skb) - softmac_mgmt_xmit(skb, ieee); - else - netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n"); -} - -static void rtllib_send_add_ba_rsp(struct rtllib_device *ieee, u8 *dst, - struct ba_record *ba, u16 status_code) -{ - struct sk_buff *skb; - - skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP); - if (skb) - softmac_mgmt_xmit(skb, ieee); - else - netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n"); -} - -static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, - struct ba_record *ba, enum tr_select tx_rx_select, - u16 reason_code) -{ - struct sk_buff *skb; - - skb = rtllib_DELBA(ieee, dst, ba, tx_rx_select, reason_code); - if (skb) - softmac_mgmt_xmit(skb, ieee); - else - netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n"); -} - -int rtllib_rx_add_ba_req(struct rtllib_device *ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr *req = NULL; - u16 rc = 0; - u8 *dst = NULL, *dialog_token = NULL, *tag = NULL; - struct ba_record *ba = NULL; - union ba_param_set *ba_param_set = NULL; - u16 *ba_timeout_value = NULL; - union sequence_control *ba_start_seq_ctrl = NULL; - struct rx_ts_record *ts = NULL; - - if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { - netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct ieee80211_hdr_3addr) + 9)); - return -1; - } - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__, - skb->data, skb->len); -#endif - - req = (struct ieee80211_hdr_3addr *)skb->data; - tag = (u8 *)req; - dst = (u8 *)(&req->addr2[0]); - tag += sizeof(struct ieee80211_hdr_3addr); - dialog_token = tag + 2; - ba_param_set = (union ba_param_set *)(tag + 3); - ba_timeout_value = (u16 *)(tag + 5); - ba_start_seq_ctrl = (union sequence_control *)(req + 7); - - if (!ieee->current_network.qos_data.active || - !ieee->ht_info->current_ht_support || - (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) { - rc = ADDBA_STATUS_REFUSED; - netdev_warn(ieee->dev, - "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", - ieee->current_network.qos_data.active, - ieee->ht_info->current_ht_support); - goto on_add_ba_req_fail; - } - if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, - (u8)(ba_param_set->field.tid), RX_DIR, true)) { - rc = ADDBA_STATUS_REFUSED; - netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); - goto on_add_ba_req_fail; - } - ba = &ts->rx_admitted_ba_record; - - if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) { - rc = ADDBA_STATUS_INVALID_PARAM; - netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n", - __func__); - goto on_add_ba_req_fail; - } - - rtllib_flush_rx_ts_pending_pkts(ieee, ts); - - deactivate_ba_entry(ieee, ba); - ba->dialog_token = *dialog_token; - ba->ba_param_set = *ba_param_set; - ba->ba_timeout_value = *ba_timeout_value; - ba->ba_start_seq_ctrl = *ba_start_seq_ctrl; - - if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev) || - (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) - ba->ba_param_set.field.buffer_size = 1; - else - ba->ba_param_set.field.buffer_size = 32; - - activate_ba_entry(ba, 0); - rtllib_send_add_ba_rsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS); - - return 0; - -on_add_ba_req_fail: - { - struct ba_record BA; - - BA.ba_param_set = *ba_param_set; - BA.ba_timeout_value = *ba_timeout_value; - BA.dialog_token = *dialog_token; - BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE; - rtllib_send_add_ba_rsp(ieee, dst, &BA, rc); - return 0; - } -} - -int rtllib_rx_add_ba_rsp(struct rtllib_device *ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr *rsp = NULL; - struct ba_record *pending_ba, *admitted_ba; - struct tx_ts_record *ts = NULL; - u8 *dst = NULL, *dialog_token = NULL, *tag = NULL; - u16 *status_code = NULL, *ba_timeout_value = NULL; - union ba_param_set *ba_param_set = NULL; - u16 reason_code; - - if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { - netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct ieee80211_hdr_3addr) + 9)); - return -1; - } - rsp = (struct ieee80211_hdr_3addr *)skb->data; - tag = (u8 *)rsp; - dst = (u8 *)(&rsp->addr2[0]); - tag += sizeof(struct ieee80211_hdr_3addr); - dialog_token = tag + 2; - status_code = (u16 *)(tag + 3); - ba_param_set = (union ba_param_set *)(tag + 5); - ba_timeout_value = (u16 *)(tag + 7); - - if (!ieee->current_network.qos_data.active || - !ieee->ht_info->current_ht_support || - !ieee->ht_info->current_ampdu_enable) { - netdev_warn(ieee->dev, - "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", - ieee->current_network.qos_data.active, - ieee->ht_info->current_ht_support, - ieee->ht_info->current_ampdu_enable); - reason_code = DELBA_REASON_UNKNOWN_BA; - goto on_add_ba_rsp_reject; - } - - if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, - (u8)(ba_param_set->field.tid), TX_DIR, false)) { - netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); - reason_code = DELBA_REASON_UNKNOWN_BA; - goto on_add_ba_rsp_reject; - } - - ts->add_ba_req_in_progress = false; - pending_ba = &ts->tx_pending_ba_record; - admitted_ba = &ts->tx_admitted_ba_record; - - if (admitted_ba->b_valid) { - netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n", - __func__); - return -1; - } else if (!pending_ba->b_valid || - (*dialog_token != pending_ba->dialog_token)) { - netdev_warn(ieee->dev, - "%s(): ADDBA Rsp. BA invalid, DELBA!\n", - __func__); - reason_code = DELBA_REASON_UNKNOWN_BA; - goto on_add_ba_rsp_reject; - } else { - netdev_dbg(ieee->dev, - "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", - __func__, *status_code); - deactivate_ba_entry(ieee, pending_ba); - } - - if (*status_code == ADDBA_STATUS_SUCCESS) { - if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) { - ts->add_ba_req_delayed = true; - deactivate_ba_entry(ieee, admitted_ba); - reason_code = DELBA_REASON_END_BA; - goto on_add_ba_rsp_reject; - } - - admitted_ba->dialog_token = *dialog_token; - admitted_ba->ba_timeout_value = *ba_timeout_value; - admitted_ba->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl; - admitted_ba->ba_param_set = *ba_param_set; - deactivate_ba_entry(ieee, admitted_ba); - activate_ba_entry(admitted_ba, *ba_timeout_value); - } else { - ts->add_ba_req_delayed = true; - ts->disable_add_ba = true; - reason_code = DELBA_REASON_END_BA; - goto on_add_ba_rsp_reject; - } - - return 0; - -on_add_ba_rsp_reject: - { - struct ba_record BA; - - BA.ba_param_set = *ba_param_set; - rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code); - return 0; - } -} - -int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr *delba = NULL; - union delba_param_set *del_ba_param_set = NULL; - u8 *dst = NULL; - - if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) { - netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n", - (int)skb->len, - (int)(sizeof(struct ieee80211_hdr_3addr) + 6)); - return -1; - } - - if (!ieee->current_network.qos_data.active || - !ieee->ht_info->current_ht_support) { - netdev_warn(ieee->dev, - "received DELBA while QOS or HT is not supported(%d, %d)\n", - ieee->current_network. qos_data.active, - ieee->ht_info->current_ht_support); - return -1; - } - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, - __func__, skb->len); -#endif - delba = (struct ieee80211_hdr_3addr *)skb->data; - dst = (u8 *)(&delba->addr2[0]); - del_ba_param_set = (union delba_param_set *)&delba->seq_ctrl + 2; - - if (del_ba_param_set->field.initiator == 1) { - struct rx_ts_record *ts; - - if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, - (u8)del_ba_param_set->field.tid, RX_DIR, false)) { - netdev_warn(ieee->dev, - "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", - __func__, dst, - (u8)del_ba_param_set->field.tid); - return -1; - } - - rx_ts_delete_ba(ieee, ts); - } else { - struct tx_ts_record *ts; - - if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, - (u8)del_ba_param_set->field.tid, TX_DIR, false)) { - netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n", - __func__); - return -1; - } - - ts->using_ba = false; - ts->add_ba_req_in_progress = false; - ts->add_ba_req_delayed = false; - del_timer_sync(&ts->ts_add_ba_timer); - tx_ts_delete_ba(ieee, ts); - } - return 0; -} - -void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts, - u8 policy, u8 overwrite_pending) -{ - struct ba_record *ba = &ts->tx_pending_ba_record; - - if (ba->b_valid && !overwrite_pending) - return; - - deactivate_ba_entry(ieee, ba); - - ba->dialog_token++; - ba->ba_param_set.field.amsdu_support = 0; - ba->ba_param_set.field.ba_policy = policy; - ba->ba_param_set.field.tid = ts->ts_common_info.tspec.ts_id; - ba->ba_param_set.field.buffer_size = 32; - ba->ba_timeout_value = 0; - ba->ba_start_seq_ctrl.field.seq_num = (ts->tx_cur_seq + 3) % 4096; - - activate_ba_entry(ba, BA_SETUP_TIMEOUT); - - rtllib_send_add_ba_req(ieee, ts->ts_common_info.addr, ba); -} - -void rtllib_ts_init_del_ba(struct rtllib_device *ieee, - struct ts_common_info *ts_common_info, - enum tr_select tx_rx_select) -{ - if (tx_rx_select == TX_DIR) { - struct tx_ts_record *ts = - (struct tx_ts_record *)ts_common_info; - - if (tx_ts_delete_ba(ieee, ts)) - rtllib_send_DELBA(ieee, ts_common_info->addr, - (ts->tx_admitted_ba_record.b_valid) ? - (&ts->tx_admitted_ba_record) : - (&ts->tx_pending_ba_record), - tx_rx_select, DELBA_REASON_END_BA); - } else if (tx_rx_select == RX_DIR) { - struct rx_ts_record *ts = - (struct rx_ts_record *)ts_common_info; - if (rx_ts_delete_ba(ieee, ts)) - rtllib_send_DELBA(ieee, ts_common_info->addr, - &ts->rx_admitted_ba_record, - tx_rx_select, DELBA_REASON_END_BA); - } -} - -void rtllib_ba_setup_timeout(struct timer_list *t) -{ - struct tx_ts_record *ts = from_timer(ts, t, - tx_pending_ba_record.timer); - - ts->add_ba_req_in_progress = false; - ts->add_ba_req_delayed = true; - ts->tx_pending_ba_record.b_valid = false; -} - -void rtllib_tx_ba_inact_timeout(struct timer_list *t) -{ - struct tx_ts_record *ts = from_timer(ts, t, - tx_admitted_ba_record.timer); - struct rtllib_device *ieee = container_of(ts, struct rtllib_device, - tx_ts_records[ts->num]); - tx_ts_delete_ba(ieee, ts); - rtllib_send_DELBA(ieee, ts->ts_common_info.addr, - &ts->tx_admitted_ba_record, TX_DIR, - DELBA_REASON_TIMEOUT); -} - -void rtllib_rx_ba_inact_timeout(struct timer_list *t) -{ - struct rx_ts_record *ts = from_timer(ts, t, - rx_admitted_ba_record.timer); - struct rtllib_device *ieee = container_of(ts, struct rtllib_device, - rx_ts_records[ts->num]); - - rx_ts_delete_ba(ieee, ts); - rtllib_send_DELBA(ieee, ts->ts_common_info.addr, - &ts->rx_admitted_ba_record, RX_DIR, - DELBA_REASON_TIMEOUT); -} diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h deleted file mode 100644 index a6e0077630c7..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_HT.h +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _RTL819XU_HTTYPE_H_ -#define _RTL819XU_HTTYPE_H_ - -#define MIMO_PS_STATIC 0 - -#define sHTCLng 4 - -enum ht_channel_width { - HT_CHANNEL_WIDTH_20 = 0, - HT_CHANNEL_WIDTH_20_40 = 1, -}; - -enum ht_extchnl_offset { - HT_EXTCHNL_OFFSET_NO_EXT = 0, - HT_EXTCHNL_OFFSET_UPPER = 1, - HT_EXTCHNL_OFFSET_NO_DEF = 2, - HT_EXTCHNL_OFFSET_LOWER = 3, -}; - -struct ht_capab_ele { - u8 adv_coding:1; - u8 chl_width:1; - u8 mimo_pwr_save:2; - u8 green_field:1; - u8 short_gi_20mhz:1; - u8 short_gi_40mhz:1; - u8 tx_stbc:1; - u8 rx_stbc:2; - u8 delay_ba:1; - u8 max_amsdu_size:1; - u8 dss_cck:1; - u8 PSMP:1; - u8 Rsvd1:1; - u8 lsig_txop_protect:1; - - u8 max_rx_ampdu_factor:2; - u8 mpdu_density:3; - u8 Rsvd2:3; - - u8 MCS[16]; - - u16 ext_ht_cap_info; - - u8 TxBFCap[4]; - - u8 ASCap; - -} __packed; - -struct ht_info_ele { - u8 ControlChl; - - u8 ExtChlOffset:2; - u8 RecommemdedTxWidth:1; - u8 RIFS:1; - u8 PSMPAccessOnly:1; - u8 SrvIntGranularity:3; - - u8 opt_mode:2; - u8 NonGFDevPresent:1; - u8 Revd1:5; - u8 Revd2:8; - - u8 Rsvd3:6; - u8 DualBeacon:1; - u8 DualCTSProtect:1; - - u8 SecondaryBeacon:1; - u8 LSigTxopProtectFull:1; - u8 PcoActive:1; - u8 PcoPhase:1; - u8 Rsvd4:4; - - u8 BasicMSC[16]; -} __packed; - -enum ht_spec_ver { - HT_SPEC_VER_IEEE = 0, - HT_SPEC_VER_EWC = 1, -}; - -enum ht_aggre_mode { - HT_AGG_AUTO = 0, - HT_AGG_FORCE_ENABLE = 1, - HT_AGG_FORCE_DISABLE = 2, -}; - -struct rt_hi_throughput { - u8 enable_ht; - u8 current_ht_support; - u8 cur_bw_40mhz; - u8 cur_short_gi_40mhz; - u8 cur_short_gi_20mhz; - enum ht_spec_ver peer_ht_spec_ver; - struct ht_capab_ele self_ht_cap; - u8 peer_ht_cap_buf[32]; - u8 peer_ht_info_buf[32]; - u8 ampdu_enable; - u8 current_ampdu_enable; - u8 ampdu_factor; - u8 current_ampdu_factor; - u8 current_mpdu_density; - u8 forced_ampdu_factor; - u8 forced_mpdu_density; - u8 current_op_mode; - enum ht_extchnl_offset cur_sta_ext_chnl_offset; - u8 cur_tx_bw40mhz; - u8 sw_bw_in_progress; - u8 current_rt2rt_aggregation; - u8 current_rt2rt_long_slot_time; - u8 sz_rt2rt_agg_buf[10]; - u8 cur_rx_reorder_enable; - u8 rx_reorder_win_size; - u8 rx_reorder_pending_time; - u16 rx_reorder_drop_counter; - u8 iot_peer; - u32 iot_action; - u8 iot_ra_func; -} __packed; - -struct bss_ht { - u8 bd_support_ht; - - u8 bd_ht_cap_buf[32]; - u16 bd_ht_cap_len; - u8 bd_ht_info_buf[32]; - u16 bd_ht_info_len; - - enum ht_spec_ver bd_ht_spec_ver; - enum ht_channel_width bd_bandwidth; - - u8 bd_rt2rt_aggregation; - u8 bd_rt2rt_long_slot_time; - u8 rt2rt_ht_mode; - u8 bd_ht_1r; -}; - -extern u8 MCS_FILTER_ALL[16]; -extern u8 MCS_FILTER_1SS[16]; - -#define RATE_ADPT_1SS_MASK 0xFF -#define RATE_ADPT_2SS_MASK 0xF0 -#define RATE_ADPT_MCS32_MASK 0x01 - -enum ht_aggre_size { - HT_AGG_SIZE_8K = 0, - HT_AGG_SIZE_16K = 1, - HT_AGG_SIZE_32K = 2, - HT_AGG_SIZE_64K = 3, -}; - -enum ht_iot_peer { - HT_IOT_PEER_UNKNOWN = 0, - HT_IOT_PEER_REALTEK = 1, - HT_IOT_PEER_REALTEK_92SE = 2, - HT_IOT_PEER_BROADCOM = 3, - HT_IOT_PEER_RALINK = 4, - HT_IOT_PEER_ATHEROS = 5, - HT_IOT_PEER_CISCO = 6, - HT_IOT_PEER_MARVELL = 7, - HT_IOT_PEER_92U_SOFTAP = 8, - HT_IOT_PEER_SELF_SOFTAP = 9, - HT_IOT_PEER_AIRGO = 10, - HT_IOT_PEER_MAX = 11, -}; - -enum ht_iot_action { - HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, - HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, - HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, - HT_IOT_ACT_DISABLE_MCS15 = 0x00000008, - HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010, - HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020, - HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040, - HT_IOT_ACT_CDD_FSYNC = 0x00000080, - HT_IOT_ACT_PURE_N_MODE = 0x00000100, - HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, - HT_IOT_ACT_FORCED_RTS = 0x00000400, - HT_IOT_ACT_AMSDU_ENABLE = 0x00000800, - HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000, - HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000, - HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000, - - HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000, - HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000, - HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000, - HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000, - HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000, - HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000, - - HT_IOT_ACT_MID_HIGHPOWER = 0x00400000, - HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000, - - HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000, - HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000, - HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000, - - HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI = 0x08000000, - -}; - -enum ht_iot_rafunc { - HT_IOT_RAFUNC_DISABLE_ALL = 0x00, - HT_IOT_RAFUNC_PEER_1R = 0x01, - HT_IOT_RAFUNC_TX_AMSDU = 0x02, -}; - -enum rt_ht_capability { - RT_HT_CAP_USE_TURBO_AGGR = 0x01, - RT_HT_CAP_USE_LONG_PREAMBLE = 0x02, - RT_HT_CAP_USE_AMPDU = 0x04, - RT_HT_CAP_USE_WOW = 0x8, - RT_HT_CAP_USE_SOFTAP = 0x10, - RT_HT_CAP_USE_92SE = 0x20, -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c deleted file mode 100644 index e38cd0c9c013..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ /dev/null @@ -1,699 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtllib.h" -#include "rtl819x_HT.h" -u8 MCS_FILTER_ALL[16] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -u8 MCS_FILTER_1SS[16] = { - 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -; - -u16 MCS_DATA_RATE[2][2][77] = { - {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, - 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, - 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, - 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156, - 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273, - 312, 351, 312, 351, 390, 390, 429}, - {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, - 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, - 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, - 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, - 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, - 433, 433, 477} }, - {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, - 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, - 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, - 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324, - 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648, - 729, 648, 729, 810, 810, 891}, - {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, - 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, - 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, - 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360, - 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720, - 810, 720, 810, 900, 900, 990} } -}; - -static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; - -static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; - -static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; - -static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; - -static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; - -static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; - -static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; - -static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; - -static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; - -static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; - -static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; - -static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; - -void ht_update_default_setting(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - ht_info->ampdu_enable = 1; - ht_info->ampdu_factor = 2; - - ieee->tx_dis_rate_fallback = 0; - ieee->tx_use_drv_assinged_rate = 0; - - ieee->tx_enable_fw_calc_dur = 1; - - ht_info->rx_reorder_win_size = 64; - ht_info->rx_reorder_pending_time = 30; -} - -static u16 ht_mcs_to_data_rate(struct rtllib_device *ieee, u8 mcs_rate) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - u8 is40MHz = (ht_info->cur_bw_40mhz) ? 1 : 0; - u8 isShortGI = (ht_info->cur_bw_40mhz) ? - ((ht_info->cur_short_gi_40mhz) ? 1 : 0) : - ((ht_info->cur_short_gi_20mhz) ? 1 : 0); - return MCS_DATA_RATE[is40MHz][isShortGI][(mcs_rate & 0x7f)]; -} - -u16 tx_count_to_data_rate(struct rtllib_device *ieee, u8 data_rate) -{ - u16 cck_of_dm_rate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, - 0x24, 0x30, 0x48, 0x60, 0x6c}; - u8 is40MHz = 0; - u8 isShortGI = 0; - - if (data_rate < 12) - return cck_of_dm_rate[data_rate]; - if (data_rate >= 0x10 && data_rate <= 0x1f) { - is40MHz = 0; - isShortGI = 0; - } else if (data_rate >= 0x20 && data_rate <= 0x2f) { - is40MHz = 1; - isShortGI = 0; - } else if (data_rate >= 0x30 && data_rate <= 0x3f) { - is40MHz = 0; - isShortGI = 1; - } else if (data_rate >= 0x40 && data_rate <= 0x4f) { - is40MHz = 1; - isShortGI = 1; - } - return MCS_DATA_RATE[is40MHz][isShortGI][data_rate & 0xf]; -} - -bool is_ht_half_nmode_aps(struct rtllib_device *ieee) -{ - bool retValue = false; - struct rtllib_network *net = &ieee->current_network; - - if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || - (memcmp(net->bssid, PCI_RALINK, 3) == 0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || - (net->ralink_cap_exist)) - retValue = true; - else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || - (net->broadcom_cap_exist)) - retValue = true; - else if (net->bssht.bd_rt2rt_aggregation) - retValue = true; - else - retValue = false; - - return retValue; -} - -static void ht_iot_peer_determine(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - struct rtllib_network *net = &ieee->current_network; - - if (net->bssht.bd_rt2rt_aggregation) { - ht_info->iot_peer = HT_IOT_PEER_REALTEK; - if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE) - ht_info->iot_peer = HT_IOT_PEER_REALTEK_92SE; - if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_SOFTAP) - ht_info->iot_peer = HT_IOT_PEER_92U_SOFTAP; - } else if (net->broadcom_cap_exist) { - ht_info->iot_peer = HT_IOT_PEER_BROADCOM; - } else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || - !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) { - ht_info->iot_peer = HT_IOT_PEER_BROADCOM; - } else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || - (memcmp(net->bssid, PCI_RALINK, 3) == 0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || - net->ralink_cap_exist) { - ht_info->iot_peer = HT_IOT_PEER_RALINK; - } else if ((net->atheros_cap_exist) || - (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) || - (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) { - ht_info->iot_peer = HT_IOT_PEER_ATHEROS; - } else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) || - net->cisco_cap_exist) { - ht_info->iot_peer = HT_IOT_PEER_CISCO; - } else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || - net->marvell_cap_exist) { - ht_info->iot_peer = HT_IOT_PEER_MARVELL; - } else if (net->airgo_cap_exist) { - ht_info->iot_peer = HT_IOT_PEER_AIRGO; - } else { - ht_info->iot_peer = HT_IOT_PEER_UNKNOWN; - } - - netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->iot_peer); -} - -static u8 ht_iot_act_is_mgnt_use_cck_6m(struct rtllib_device *ieee, - struct rtllib_network *network) -{ - u8 retValue = 0; - - if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) - retValue = 1; - - return retValue; -} - -static u8 ht_iot_act_is_ccd_fsync(struct rtllib_device *ieee) -{ - u8 retValue = 0; - - if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) - retValue = 1; - return retValue; -} - -static void ht_iot_act_determine_ra_func(struct rtllib_device *ieee, bool bPeerRx2ss) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - ht_info->iot_ra_func &= HT_IOT_RAFUNC_DISABLE_ALL; - - if (ht_info->iot_peer == HT_IOT_PEER_RALINK && !bPeerRx2ss) - ht_info->iot_ra_func |= HT_IOT_RAFUNC_PEER_1R; - - if (ht_info->iot_action & HT_IOT_ACT_AMSDU_ENABLE) - ht_info->iot_ra_func |= HT_IOT_RAFUNC_TX_AMSDU; -} - -void ht_reset_iot_setting(struct rt_hi_throughput *ht_info) -{ - ht_info->iot_action = 0; - ht_info->iot_peer = HT_IOT_PEER_UNKNOWN; - ht_info->iot_ra_func = 0; -} - -void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap, - u8 *len, u8 is_encrypt, bool assoc) -{ - struct rt_hi_throughput *ht = ieee->ht_info; - struct ht_capab_ele *cap_ele = NULL; - - if (!pos_ht_cap || !ht) { - netdev_warn(ieee->dev, - "%s(): pos_ht_cap and ht_info are null\n", __func__); - return; - } - memset(pos_ht_cap, 0, *len); - - if ((assoc) && (ht->peer_ht_spec_ver == HT_SPEC_VER_EWC)) { - static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; - - memcpy(pos_ht_cap, EWC11NHTCap, sizeof(EWC11NHTCap)); - cap_ele = (struct ht_capab_ele *)&pos_ht_cap[4]; - *len = 30 + 2; - } else { - cap_ele = (struct ht_capab_ele *)pos_ht_cap; - *len = 26 + 2; - } - - cap_ele->adv_coding = 0; - if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) - cap_ele->chl_width = 0; - else - cap_ele->chl_width = 1; - - cap_ele->mimo_pwr_save = 3; - cap_ele->green_field = 0; - cap_ele->short_gi_20mhz = 1; - cap_ele->short_gi_40mhz = 1; - - cap_ele->tx_stbc = 1; - cap_ele->rx_stbc = 0; - cap_ele->delay_ba = 0; - cap_ele->max_amsdu_size = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; - cap_ele->dss_cck = 1; - cap_ele->PSMP = 0; - cap_ele->lsig_txop_protect = 0; - - netdev_dbg(ieee->dev, - "TX HT cap/info ele BW=%d max_amsdu_size:%d dss_cck:%d\n", - cap_ele->chl_width, cap_ele->max_amsdu_size, cap_ele->dss_cck); - - if (is_encrypt) { - cap_ele->mpdu_density = 7; - cap_ele->max_rx_ampdu_factor = 2; - } else { - cap_ele->max_rx_ampdu_factor = 3; - cap_ele->mpdu_density = 0; - } - - memcpy(cap_ele->MCS, ieee->reg_dot11ht_oper_rate_set, 16); - memset(&cap_ele->ext_ht_cap_info, 0, 2); - memset(cap_ele->TxBFCap, 0, 4); - - cap_ele->ASCap = 0; - - if (assoc) { - if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS15) - cap_ele->MCS[1] &= 0x7f; - - if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS14) - cap_ele->MCS[1] &= 0xbf; - - if (ht->iot_action & HT_IOT_ACT_DISABLE_ALL_2SS) - cap_ele->MCS[1] &= 0x00; - - if (ht->iot_action & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) - cap_ele->short_gi_40mhz = 0; - - if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) { - cap_ele->chl_width = 0; - cap_ele->MCS[1] = 0; - } - } -} - -void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee, u8 *posRT2RTAgg, - u8 *len) -{ - if (!posRT2RTAgg) { - netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__); - return; - } - memset(posRT2RTAgg, 0, *len); - *posRT2RTAgg++ = 0x00; - *posRT2RTAgg++ = 0xe0; - *posRT2RTAgg++ = 0x4c; - *posRT2RTAgg++ = 0x02; - *posRT2RTAgg++ = 0x01; - - *posRT2RTAgg = 0x30; - - if (ieee->bSupportRemoteWakeUp) - *posRT2RTAgg |= RT_HT_CAP_USE_WOW; - - *len = 6 + 2; -} - -static u8 ht_pick_mcs_rate(struct rtllib_device *ieee, u8 *pOperateMCS) -{ - u8 i; - - if (!pOperateMCS) { - netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__); - return false; - } - - switch (ieee->mode) { - case WIRELESS_MODE_B: - case WIRELESS_MODE_G: - for (i = 0; i <= 15; i++) - pOperateMCS[i] = 0; - break; - case WIRELESS_MODE_N_24G: - pOperateMCS[0] &= RATE_ADPT_1SS_MASK; - pOperateMCS[1] &= RATE_ADPT_2SS_MASK; - pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; - break; - default: - break; - } - - return true; -} - -u8 ht_get_highest_mcs_rate(struct rtllib_device *ieee, u8 *pMCSRateSet, - u8 *pMCSFilter) -{ - u8 i, j; - u8 bitMap; - u8 mcsRate = 0; - u8 availableMcsRate[16]; - - if (!pMCSRateSet || !pMCSFilter) { - netdev_warn(ieee->dev, - "%s(): pMCSRateSet and pMCSFilter are null\n", - __func__); - return false; - } - for (i = 0; i < 16; i++) - availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; - - for (i = 0; i < 16; i++) { - if (availableMcsRate[i] != 0) - break; - } - if (i == 16) - return false; - - for (i = 0; i < 16; i++) { - if (availableMcsRate[i] != 0) { - bitMap = availableMcsRate[i]; - for (j = 0; j < 8; j++) { - if ((bitMap % 2) != 0) { - if (ht_mcs_to_data_rate(ieee, (8 * i + j)) > - ht_mcs_to_data_rate(ieee, mcsRate)) - mcsRate = 8 * i + j; - } - bitMap >>= 1; - } - } - } - return mcsRate | 0x80; -} - -static u8 ht_filter_mcs_rate(struct rtllib_device *ieee, u8 *pSupportMCS, - u8 *pOperateMCS) -{ - u8 i; - - for (i = 0; i <= 15; i++) - pOperateMCS[i] = ieee->reg_dot11tx_ht_oper_rate_set[i] & - pSupportMCS[i]; - - ht_pick_mcs_rate(ieee, pOperateMCS); - - if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) - pOperateMCS[1] = 0; - - for (i = 2; i <= 15; i++) - pOperateMCS[i] = 0; - - return true; -} - -void ht_set_connect_bw_mode(struct rtllib_device *ieee, - enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset); - -void ht_on_assoc_rsp(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - struct ht_capab_ele *pPeerHTCap = NULL; - struct ht_info_ele *pPeerHTInfo = NULL; - u8 *pMcsFilter = NULL; - - static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; - static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 }; - - if (!ht_info->current_ht_support) { - netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); - return; - } - netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); - - if (!memcmp(ht_info->peer_ht_cap_buf, EWC11NHTCap, sizeof(EWC11NHTCap))) - pPeerHTCap = (struct ht_capab_ele *)(&ht_info->peer_ht_cap_buf[4]); - else - pPeerHTCap = (struct ht_capab_ele *)(ht_info->peer_ht_cap_buf); - - if (!memcmp(ht_info->peer_ht_info_buf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) - pPeerHTInfo = (struct ht_info_ele *) - (&ht_info->peer_ht_info_buf[4]); - else - pPeerHTInfo = (struct ht_info_ele *)(ht_info->peer_ht_info_buf); - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, - pPeerHTCap, sizeof(struct ht_capab_ele)); -#endif - ht_set_connect_bw_mode(ieee, (enum ht_channel_width)(pPeerHTCap->chl_width), - (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); - ht_info->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? - true : false); - - ht_info->cur_short_gi_20mhz = ((pPeerHTCap->short_gi_20mhz == 1) ? true : false); - ht_info->cur_short_gi_40mhz = ((pPeerHTCap->short_gi_40mhz == 1) ? true : false); - - ht_info->current_ampdu_enable = ht_info->ampdu_enable; - if (ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) { - if ((ht_info->iot_peer == HT_IOT_PEER_ATHEROS) || - (ht_info->iot_peer == HT_IOT_PEER_UNKNOWN)) - ht_info->current_ampdu_enable = false; - } - - if (ieee->current_network.bssht.bd_rt2rt_aggregation) { - if (ieee->pairwise_key_type != KEY_TYPE_NA) - ht_info->current_ampdu_factor = - pPeerHTCap->max_rx_ampdu_factor; - else - ht_info->current_ampdu_factor = HT_AGG_SIZE_64K; - } else { - ht_info->current_ampdu_factor = min_t(u32, pPeerHTCap->max_rx_ampdu_factor, - HT_AGG_SIZE_32K); - } - - ht_info->current_mpdu_density = pPeerHTCap->mpdu_density; - if (ht_info->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K) - ht_info->current_ampdu_enable = false; - - ht_info->cur_rx_reorder_enable = 1; - - if (pPeerHTCap->MCS[0] == 0) - pPeerHTCap->MCS[0] = 0xff; - - ht_iot_act_determine_ra_func(ieee, ((pPeerHTCap->MCS[1]) != 0)); - - ht_filter_mcs_rate(ieee, pPeerHTCap->MCS, ieee->dot11ht_oper_rate_set); - - pMcsFilter = MCS_FILTER_ALL; - ieee->HTHighestOperaRate = ht_get_highest_mcs_rate(ieee, - ieee->dot11ht_oper_rate_set, - pMcsFilter); - ieee->ht_curr_op_rate = ieee->HTHighestOperaRate; - - ht_info->current_op_mode = pPeerHTInfo->opt_mode; -} - -void ht_initialize_ht_info(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - ht_info->current_ht_support = false; - - ht_info->cur_bw_40mhz = false; - ht_info->cur_tx_bw40mhz = false; - - ht_info->cur_short_gi_20mhz = false; - ht_info->cur_short_gi_40mhz = false; - - ht_info->current_mpdu_density = 0; - ht_info->current_ampdu_factor = ht_info->ampdu_factor; - - memset((void *)(&ht_info->self_ht_cap), 0, - sizeof(ht_info->self_ht_cap)); - memset((void *)(&ht_info->peer_ht_cap_buf), 0, - sizeof(ht_info->peer_ht_cap_buf)); - memset((void *)(&ht_info->peer_ht_info_buf), 0, - sizeof(ht_info->peer_ht_info_buf)); - - ht_info->sw_bw_in_progress = false; - - ht_info->peer_ht_spec_ver = HT_SPEC_VER_IEEE; - - ht_info->current_rt2rt_aggregation = false; - ht_info->current_rt2rt_long_slot_time = false; - - ht_info->iot_peer = 0; - ht_info->iot_action = 0; - ht_info->iot_ra_func = 0; - - { - u8 *RegHTSuppRateSets = &ieee->reg_ht_supp_rate_set[0]; - - RegHTSuppRateSets[0] = 0xFF; - RegHTSuppRateSets[1] = 0xFF; - RegHTSuppRateSets[4] = 0x01; - } -} - -void ht_initialize_bss_desc(struct bss_ht *bss_ht) -{ - bss_ht->bd_support_ht = false; - memset(bss_ht->bd_ht_cap_buf, 0, sizeof(bss_ht->bd_ht_cap_buf)); - bss_ht->bd_ht_cap_len = 0; - memset(bss_ht->bd_ht_info_buf, 0, sizeof(bss_ht->bd_ht_info_buf)); - bss_ht->bd_ht_info_len = 0; - - bss_ht->bd_ht_spec_ver = HT_SPEC_VER_IEEE; - - bss_ht->bd_rt2rt_aggregation = false; - bss_ht->bd_rt2rt_long_slot_time = false; - bss_ht->rt2rt_ht_mode = (enum rt_ht_capability)0; -} - -void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee, - struct rtllib_network *pNetwork) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - u8 bIOTAction = 0; - - /* unmark enable_ht flag here is the same reason why unmarked in - * function rtllib_softmac_new_net. WB 2008.09.10 - */ - if (pNetwork->bssht.bd_support_ht) { - ht_info->current_ht_support = true; - ht_info->peer_ht_spec_ver = pNetwork->bssht.bd_ht_spec_ver; - - if (pNetwork->bssht.bd_ht_cap_len > 0 && - pNetwork->bssht.bd_ht_cap_len <= sizeof(ht_info->peer_ht_cap_buf)) - memcpy(ht_info->peer_ht_cap_buf, - pNetwork->bssht.bd_ht_cap_buf, - pNetwork->bssht.bd_ht_cap_len); - - if (pNetwork->bssht.bd_ht_info_len > 0 && - pNetwork->bssht.bd_ht_info_len <= - sizeof(ht_info->peer_ht_info_buf)) - memcpy(ht_info->peer_ht_info_buf, - pNetwork->bssht.bd_ht_info_buf, - pNetwork->bssht.bd_ht_info_len); - - ht_info->current_rt2rt_aggregation = - pNetwork->bssht.bd_rt2rt_aggregation; - ht_info->current_rt2rt_long_slot_time = - pNetwork->bssht.bd_rt2rt_long_slot_time; - - ht_iot_peer_determine(ieee); - - ht_info->iot_action = 0; - bIOTAction = ht_iot_act_is_mgnt_use_cck_6m(ieee, pNetwork); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M; - bIOTAction = ht_iot_act_is_ccd_fsync(ieee); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC; - } else { - ht_info->current_ht_support = false; - ht_info->current_rt2rt_aggregation = false; - ht_info->current_rt2rt_long_slot_time = false; - - ht_info->iot_action = 0; - ht_info->iot_ra_func = 0; - } -} - -void HT_update_self_and_peer_setting(struct rtllib_device *ieee, - struct rtllib_network *pNetwork) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - struct ht_info_ele *pPeerHTInfo = - (struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf; - - if (ht_info->current_ht_support) { - if (pNetwork->bssht.bd_ht_info_len != 0) - ht_info->current_op_mode = pPeerHTInfo->opt_mode; - } -} -EXPORT_SYMBOL(HT_update_self_and_peer_setting); - -u8 ht_c_check(struct rtllib_device *ieee, u8 *pFrame) -{ - if (ieee->ht_info->current_ht_support) { - if ((is_qos_data_frame(pFrame) && frame_order(pFrame)) == 1) { - netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); - return true; - } - } - return false; -} - -static void ht_set_connect_bw_mode_callback(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - if (ht_info->cur_bw_40mhz) { - if (ht_info->cur_sta_ext_chnl_offset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, - ieee->current_network.channel + 2); - else if (ht_info->cur_sta_ext_chnl_offset == - HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, - ieee->current_network.channel - 2); - else - ieee->set_chan(ieee->dev, - ieee->current_network.channel); - - ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20_40, - ht_info->cur_sta_ext_chnl_offset); - } else { - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20, - HT_EXTCHNL_OFFSET_NO_EXT); - } - - ht_info->sw_bw_in_progress = false; -} - -void ht_set_connect_bw_mode(struct rtllib_device *ieee, - enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) - bandwidth = HT_CHANNEL_WIDTH_20; - - if (ht_info->sw_bw_in_progress) { - pr_info("%s: sw_bw_in_progress!!\n", __func__); - return; - } - if (bandwidth == HT_CHANNEL_WIDTH_20_40) { - if (ieee->current_network.channel < 2 && - Offset == HT_EXTCHNL_OFFSET_LOWER) - Offset = HT_EXTCHNL_OFFSET_NO_EXT; - if (Offset == HT_EXTCHNL_OFFSET_UPPER || - Offset == HT_EXTCHNL_OFFSET_LOWER) { - ht_info->cur_bw_40mhz = true; - ht_info->cur_sta_ext_chnl_offset = Offset; - } else { - ht_info->cur_bw_40mhz = false; - ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT; - } - } else { - ht_info->cur_bw_40mhz = false; - ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT; - } - - netdev_dbg(ieee->dev, "%s():ht_info->bCurBW40MHz:%x\n", __func__, - ht_info->cur_bw_40mhz); - - ht_info->sw_bw_in_progress = true; - - ht_set_connect_bw_mode_callback(ieee); -} diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h deleted file mode 100644 index dc991100742f..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_Qos.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef __INC_QOS_TYPE_H -#define __INC_QOS_TYPE_H - -struct qos_tsinfo { - u8 ts_id:4; - u8 ucDirection:2; -}; - -struct octet_string { - u8 *octet; - u16 Length; -}; - -#define AC0_BE 0 -#define AC1_BK 1 -#define AC2_VI 2 -#define AC3_VO 3 - -enum direction_value { - DIR_UP = 0, - DIR_DOWN = 1, - DIR_DIRECT = 2, - DIR_BI_DIR = 3, -}; - -union aci_aifsn { - u8 charData; - - struct { - u8 AIFSN:4; - u8 acm:1; - u8 ACI:2; - u8 Reserved:1; - } f; -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtl819x_TS.h b/drivers/staging/rtl8192e/rtl819x_TS.h deleted file mode 100644 index 5b0e4cb572d2..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_TS.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _TSTYPE_H_ -#define _TSTYPE_H_ -#include "rtl819x_Qos.h" -#define TS_ADDBA_DELAY 60 - -#define TOTAL_TS_NUM 16 - -enum tr_select { - TX_DIR = 0, - RX_DIR = 1, -}; - -struct ts_common_info { - struct list_head list; - u8 addr[ETH_ALEN]; - struct qos_tsinfo tspec; -}; - -struct tx_ts_record { - struct ts_common_info ts_common_info; - u16 tx_cur_seq; - struct ba_record tx_pending_ba_record; - struct ba_record tx_admitted_ba_record; - u8 add_ba_req_in_progress; - u8 add_ba_req_delayed; - u8 using_ba; - u8 disable_add_ba; - struct timer_list ts_add_ba_timer; - u8 num; -}; - -struct rx_ts_record { - struct ts_common_info ts_common_info; - u16 rx_indicate_seq; - u16 rx_timeout_indicate_seq; - struct list_head rx_pending_pkt_list; - struct timer_list rx_pkt_pending_timer; - struct ba_record rx_admitted_ba_record; - u16 rx_last_seq_num; - u8 rx_last_frag_num; - u8 num; -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c deleted file mode 100644 index ed6a488bc7ac..000000000000 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ /dev/null @@ -1,450 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#include "rtllib.h" -#include -#include "rtl819x_TS.h" - -static void RxPktPendingTimeout(struct timer_list *t) -{ - struct rx_ts_record *ts = from_timer(ts, t, rx_pkt_pending_timer); - struct rtllib_device *ieee = container_of(ts, struct rtllib_device, - rx_ts_records[ts->num]); - - struct rx_reorder_entry *pReorderEntry = NULL; - - unsigned long flags = 0; - u8 index = 0; - bool pkt_in_buf = false; - - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - if (ts->rx_timeout_indicate_seq != 0xffff) { - while (!list_empty(&ts->rx_pending_pkt_list)) { - pReorderEntry = (struct rx_reorder_entry *) - list_entry(ts->rx_pending_pkt_list.prev, - struct rx_reorder_entry, list); - if (index == 0) - ts->rx_indicate_seq = pReorderEntry->SeqNum; - - if (SN_LESS(pReorderEntry->SeqNum, - ts->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, - ts->rx_indicate_seq)) { - list_del_init(&pReorderEntry->list); - - if (SN_EQUAL(pReorderEntry->SeqNum, - ts->rx_indicate_seq)) - ts->rx_indicate_seq = - (ts->rx_indicate_seq + 1) % 4096; - - netdev_dbg(ieee->dev, - "%s(): Indicate SeqNum: %d\n", - __func__, pReorderEntry->SeqNum); - ieee->stats_IndicateArray[index] = - pReorderEntry->prxb; - index++; - - list_add_tail(&pReorderEntry->list, - &ieee->RxReorder_Unused_List); - } else { - pkt_in_buf = true; - break; - } - } - } - - if (index > 0) { - ts->rx_timeout_indicate_seq = 0xffff; - - if (index > REORDER_WIN_SIZE) { - netdev_warn(ieee->dev, - "%s(): Rx Reorder struct buffer full\n", - __func__); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), - flags); - return; - } - rtllib_indicate_packets(ieee, ieee->stats_IndicateArray, index); - pkt_in_buf = false; - } - - if (pkt_in_buf && (ts->rx_timeout_indicate_seq == 0xffff)) { - ts->rx_timeout_indicate_seq = ts->rx_indicate_seq; - mod_timer(&ts->rx_pkt_pending_timer, jiffies + - msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time) - ); - } - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); -} - -static void TsAddBaProcess(struct timer_list *t) -{ - struct tx_ts_record *ts = from_timer(ts, t, ts_add_ba_timer); - u8 num = ts->num; - struct rtllib_device *ieee = container_of(ts, struct rtllib_device, - tx_ts_records[num]); - - rtllib_ts_init_add_ba(ieee, ts, BA_POLICY_IMMEDIATE, false); - netdev_dbg(ieee->dev, "%s(): ADDBA Req is started\n", __func__); -} - -static void ResetTsCommonInfo(struct ts_common_info *ts_common_info) -{ - eth_zero_addr(ts_common_info->addr); - memset(&ts_common_info->tspec, 0, sizeof(struct qos_tsinfo)); -} - -static void ResetTxTsEntry(struct tx_ts_record *ts) -{ - ResetTsCommonInfo(&ts->ts_common_info); - ts->tx_cur_seq = 0; - ts->add_ba_req_in_progress = false; - ts->add_ba_req_delayed = false; - ts->using_ba = false; - ts->disable_add_ba = false; - rtllib_reset_ba_entry(&ts->tx_admitted_ba_record); - rtllib_reset_ba_entry(&ts->tx_pending_ba_record); -} - -static void ResetRxTsEntry(struct rx_ts_record *ts) -{ - ResetTsCommonInfo(&ts->ts_common_info); - ts->rx_indicate_seq = 0xffff; - ts->rx_timeout_indicate_seq = 0xffff; - rtllib_reset_ba_entry(&ts->rx_admitted_ba_record); -} - -void rtllib_ts_init(struct rtllib_device *ieee) -{ - struct tx_ts_record *pTxTS = ieee->tx_ts_records; - struct rx_ts_record *rxts = ieee->rx_ts_records; - struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; - u8 count = 0; - - INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); - - for (count = 0; count < TOTAL_TS_NUM; count++) { - pTxTS->num = count; - timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0); - - timer_setup(&pTxTS->tx_pending_ba_record.timer, rtllib_ba_setup_timeout, - 0); - timer_setup(&pTxTS->tx_admitted_ba_record.timer, - rtllib_tx_ba_inact_timeout, 0); - - ResetTxTsEntry(pTxTS); - list_add_tail(&pTxTS->ts_common_info.list, - &ieee->Tx_TS_Unused_List); - pTxTS++; - } - - INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); - for (count = 0; count < TOTAL_TS_NUM; count++) { - rxts->num = count; - INIT_LIST_HEAD(&rxts->rx_pending_pkt_list); - timer_setup(&rxts->rx_admitted_ba_record.timer, - rtllib_rx_ba_inact_timeout, 0); - - timer_setup(&rxts->rx_pkt_pending_timer, RxPktPendingTimeout, 0); - - ResetRxTsEntry(rxts); - list_add_tail(&rxts->ts_common_info.list, - &ieee->Rx_TS_Unused_List); - rxts++; - } - INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); - for (count = 0; count < REORDER_ENTRY_NUM; count++) { - list_add_tail(&pRxReorderEntry->list, - &ieee->RxReorder_Unused_List); - if (count == (REORDER_ENTRY_NUM - 1)) - break; - pRxReorderEntry = &ieee->RxReorderEntry[count + 1]; - } -} - -static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, - u8 *addr, u8 TID, - enum tr_select tx_rx_select) -{ - u8 dir; - bool search_dir[4] = {0}; - struct list_head *psearch_list; - struct ts_common_info *pRet = NULL; - - if (tx_rx_select == TX_DIR) { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } else { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } - - if (tx_rx_select == TX_DIR) - psearch_list = &ieee->Tx_TS_Admit_List; - else - psearch_list = &ieee->Rx_TS_Admit_List; - - for (dir = 0; dir <= DIR_BI_DIR; dir++) { - if (!search_dir[dir]) - continue; - list_for_each_entry(pRet, psearch_list, list) { - if (memcmp(pRet->addr, addr, 6) == 0 && - pRet->tspec.ts_id == TID && - pRet->tspec.ucDirection == dir) - break; - } - if (&pRet->list != psearch_list) - break; - } - - if (pRet && &pRet->list != psearch_list) - return pRet; - return NULL; -} - -static void MakeTSEntry(struct ts_common_info *ts_common_info, u8 *addr, - struct qos_tsinfo *pTSPEC) -{ - if (!ts_common_info) - return; - - memcpy(ts_common_info->addr, addr, 6); - - if (pTSPEC) - memcpy((u8 *)(&(ts_common_info->tspec)), (u8 *)pTSPEC, - sizeof(struct qos_tsinfo)); -} - -bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, - u8 *addr, u8 TID, enum tr_select tx_rx_select, bool bAddNewTs) -{ - u8 UP = 0; - struct qos_tsinfo tspec; - struct qos_tsinfo *ts_info = &tspec; - struct list_head *pUnusedList; - struct list_head *pAddmitList; - enum direction_value Dir; - - if (is_multicast_ether_addr(addr)) { - netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n"); - return false; - } - if (ieee->current_network.qos_data.supported == 0) { - UP = 0; - } else { - switch (TID) { - case 0: - case 3: - UP = 0; - break; - case 1: - case 2: - UP = 2; - break; - case 4: - case 5: - UP = 5; - break; - case 6: - case 7: - UP = 7; - break; - default: - netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n", - __func__, TID); - return false; - } - } - - *ppTS = SearchAdmitTRStream(ieee, addr, UP, tx_rx_select); - if (*ppTS) - return true; - - if (!bAddNewTs) { - netdev_dbg(ieee->dev, "add new TS failed(tid:%d)\n", UP); - return false; - } - - pUnusedList = (tx_rx_select == TX_DIR) ? - (&ieee->Tx_TS_Unused_List) : - (&ieee->Rx_TS_Unused_List); - - pAddmitList = (tx_rx_select == TX_DIR) ? - (&ieee->Tx_TS_Admit_List) : - (&ieee->Rx_TS_Admit_List); - - Dir = ((tx_rx_select == TX_DIR) ? DIR_UP : DIR_DOWN); - - if (!list_empty(pUnusedList)) { - (*ppTS) = list_entry(pUnusedList->next, - struct ts_common_info, list); - list_del_init(&(*ppTS)->list); - if (tx_rx_select == TX_DIR) { - struct tx_ts_record *tmp = - container_of(*ppTS, - struct tx_ts_record, - ts_common_info); - ResetTxTsEntry(tmp); - } else { - struct rx_ts_record *ts = - container_of(*ppTS, - struct rx_ts_record, - ts_common_info); - ResetRxTsEntry(ts); - } - - netdev_dbg(ieee->dev, - "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n", - UP, Dir, addr, *ppTS); - ts_info->ts_id = UP; - ts_info->ucDirection = Dir; - - MakeTSEntry(*ppTS, addr, &tspec); - list_add_tail(&((*ppTS)->list), pAddmitList); - - return true; - } - - netdev_warn(ieee->dev, - "There is not enough dir=%d(0=up down=1) TS record to be used!", - Dir); - return false; -} - -static void RemoveTsEntry(struct rtllib_device *ieee, - struct ts_common_info *pTs, enum tr_select tx_rx_select) -{ - rtllib_ts_init_del_ba(ieee, pTs, tx_rx_select); - - if (tx_rx_select == RX_DIR) { - struct rx_reorder_entry *pRxReorderEntry; - struct rx_ts_record *ts = (struct rx_ts_record *)pTs; - - if (timer_pending(&ts->rx_pkt_pending_timer)) - del_timer_sync(&ts->rx_pkt_pending_timer); - - while (!list_empty(&ts->rx_pending_pkt_list)) { - pRxReorderEntry = (struct rx_reorder_entry *) - list_entry(ts->rx_pending_pkt_list.prev, - struct rx_reorder_entry, list); - netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n", - __func__, pRxReorderEntry->SeqNum); - list_del_init(&pRxReorderEntry->list); - { - int i = 0; - struct rtllib_rxb *prxb = pRxReorderEntry->prxb; - - if (unlikely(!prxb)) - return; - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - kfree(prxb); - prxb = NULL; - } - list_add_tail(&pRxReorderEntry->list, - &ieee->RxReorder_Unused_List); - } - } else { - struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs; - - del_timer_sync(&pTxTS->ts_add_ba_timer); - } -} - -void remove_peer_ts(struct rtllib_device *ieee, u8 *addr) -{ - struct ts_common_info *ts, *pTmpTS; - - netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, addr); - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) { - if (memcmp(ts->addr, addr, 6) == 0) { - RemoveTsEntry(ieee, ts, TX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) { - if (memcmp(ts->addr, addr, 6) == 0) { - netdev_info(ieee->dev, - "====>remove Tx_TS_admin_list\n"); - RemoveTsEntry(ieee, ts, TX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) { - if (memcmp(ts->addr, addr, 6) == 0) { - RemoveTsEntry(ieee, ts, RX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List); - } - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) { - if (memcmp(ts->addr, addr, 6) == 0) { - RemoveTsEntry(ieee, ts, RX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List); - } - } -} -EXPORT_SYMBOL(remove_peer_ts); - -void remove_all_ts(struct rtllib_device *ieee) -{ - struct ts_common_info *ts, *pTmpTS; - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) { - RemoveTsEntry(ieee, ts, TX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) { - RemoveTsEntry(ieee, ts, TX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) { - RemoveTsEntry(ieee, ts, RX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List); - } - - list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) { - RemoveTsEntry(ieee, ts, RX_DIR); - list_del_init(&ts->list); - list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List); - } -} - -void rtllib_ts_start_add_ba_process(struct rtllib_device *ieee, struct tx_ts_record *pTxTS) -{ - if (pTxTS->add_ba_req_in_progress == false) { - pTxTS->add_ba_req_in_progress = true; - - if (pTxTS->add_ba_req_delayed) { - netdev_dbg(ieee->dev, "Start ADDBA after 60 sec!!\n"); - mod_timer(&pTxTS->ts_add_ba_timer, jiffies + - msecs_to_jiffies(TS_ADDBA_DELAY)); - } else { - netdev_dbg(ieee->dev, "Immediately Start ADDBA\n"); - mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10); - } - } else { - netdev_dbg(ieee->dev, "BA timer is already added\n"); - } -} diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h deleted file mode 100644 index 022851b7f1a9..000000000000 --- a/drivers/staging/rtl8192e/rtllib.h +++ /dev/null @@ -1,1810 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Merged with mainline rtllib.h in Aug 2004. Original ieee802_11 - * remains copyright by the original authors - * - * Portions of the merged code are based on Host AP (software wireless - * LAN access point) driver for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * Copyright (c) 2004, Intel Corporation - * - * Modified for Realtek's wi-fi cards by Andrea Merello - * - */ -#ifndef RTLLIB_H -#define RTLLIB_H -#include /* ETH_ALEN */ -#include /* ARRAY_SIZE */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "rtl819x_HT.h" -#include "rtl819x_BA.h" -#include "rtl819x_TS.h" - -#include -#include /* ARPHRD_ETHER */ -#include -#include - -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -#ifndef WIRELESS_SPY -#define WIRELESS_SPY -#endif -#include - -#ifndef IW_MODE_MONITOR -#define IW_MODE_MONITOR 6 -#endif - -#ifndef IWEVCUSTOM -#define IWEVCUSTOM 0x8c02 -#endif - -#ifndef IW_CUSTOM_MAX -/* Max number of char in custom event - use multiple of them if needed */ -#define IW_CUSTOM_MAX 256 /* In bytes */ -#endif - -#define container_of_dwork_rsl(x, y, z) \ - container_of(to_delayed_work(x), y, z) - -static inline void *netdev_priv_rsl(struct net_device *dev) -{ - return netdev_priv(dev); -} - -#define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 -#define KEY_TYPE_TKIP 0x2 -#define KEY_TYPE_CCMP 0x4 -#define KEY_TYPE_WEP104 0x5 -/* added for rtl819x tx procedure */ -#define MAX_QUEUE_SIZE 0x10 - -#define BK_QUEUE 0 -#define BE_QUEUE 1 -#define VI_QUEUE 2 -#define VO_QUEUE 3 -#define HCCA_QUEUE 4 -#define TXCMD_QUEUE 5 -#define MGNT_QUEUE 6 -#define HIGH_QUEUE 7 -#define BEACON_QUEUE 8 - -#define IE_CISCO_FLAG_POSITION 0x08 -#define SUPPORT_CKIP_MIC 0x08 -#define SUPPORT_CKIP_PK 0x10 -#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) -#define RT_IN_PS_LEVEL(psc, _PS_FLAG) \ - ((psc->CurPsLevel & _PS_FLAG) ? true : false) -#define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \ - (psc->CurPsLevel &= (~(_PS_FLAG))) - -/* defined for skb cb field */ -/* At most 28 byte */ -struct cb_desc { - /* Tx Desc Related flags (8-9) */ - u8 bLastIniPkt:1; - u8 bCmdOrInit:1; - u8 tx_dis_rate_fallback:1; - u8 tx_use_drv_assinged_rate:1; - u8 hw_sec:1; - - u8 nStuckCount; - - /* Tx Firmware Related flags (10-11)*/ - u8 cts_enable:1; - u8 rts_enable:1; - u8 use_short_gi:1; - u8 use_short_preamble:1; - u8 tx_enable_fw_calc_dur:1; - u8 ampdu_enable:1; - u8 rtsstbc:1; - u8 RTSSC:1; - - u8 rts_bw:1; - u8 packet_bw:1; - u8 rts_use_short_preamble:1; - u8 rts_use_short_gi:1; - u8 multicast:1; - u8 broadcast:1; - u8 drv_agg_enable:1; - u8 reserved2:1; - - /* Tx Desc related element(12-19) */ - u8 rata_index; - u8 queue_index; - u16 txbuf_size; - u8 ratr_index; - u8 bAMSDU:1; - u8 bFromAggrQ:1; - u8 reserved6:6; - u8 priority; - - /* Tx firmware related element(20-27) */ - u8 data_rate; - u8 rts_rate; - u8 ampdu_factor; - u8 ampdu_density; - u8 DrvAggrNum; - u8 bdhcp; - u16 pkt_size; - u8 bIsSpecialDataFrame; - - u8 bBTTxPacket; - u8 bIsBTProbRsp; -}; - -enum sw_chnl_cmd_id { - CmdID_End, - CmdID_SetTxPowerLevel, - CmdID_BBRegWrite10, - CmdID_WritePortUlong, - CmdID_WritePortUshort, - CmdID_WritePortUchar, - CmdID_RF_WriteReg, -}; - -struct sw_chnl_cmd { - enum sw_chnl_cmd_id CmdID; - u32 Para1; - u32 Para2; - u32 msDelay; -}; - -/*--------------------------Define -------------------------------------------*/ -#define MGN_1M 0x02 -#define MGN_2M 0x04 -#define MGN_5_5M 0x0b -#define MGN_11M 0x16 - -#define MGN_6M 0x0c -#define MGN_9M 0x12 -#define MGN_12M 0x18 -#define MGN_18M 0x24 -#define MGN_24M 0x30 -#define MGN_36M 0x48 -#define MGN_48M 0x60 -#define MGN_54M 0x6c - -#define MGN_MCS0 0x80 -#define MGN_MCS1 0x81 -#define MGN_MCS2 0x82 -#define MGN_MCS3 0x83 -#define MGN_MCS4 0x84 -#define MGN_MCS5 0x85 -#define MGN_MCS6 0x86 -#define MGN_MCS7 0x87 -#define MGN_MCS8 0x88 -#define MGN_MCS9 0x89 -#define MGN_MCS10 0x8a -#define MGN_MCS11 0x8b -#define MGN_MCS12 0x8c -#define MGN_MCS13 0x8d -#define MGN_MCS14 0x8e -#define MGN_MCS15 0x8f - -enum hw_variables { - HW_VAR_ETHER_ADDR, - HW_VAR_MULTICAST_REG, - HW_VAR_BASIC_RATE, - HW_VAR_BSSID, - HW_VAR_MEDIA_STATUS, - HW_VAR_SECURITY_CONF, - HW_VAR_BEACON_INTERVAL, - HW_VAR_ATIM_WINDOW, - HW_VAR_LISTEN_INTERVAL, - HW_VAR_CS_COUNTER, - HW_VAR_DEFAULTKEY0, - HW_VAR_DEFAULTKEY1, - HW_VAR_DEFAULTKEY2, - HW_VAR_DEFAULTKEY3, - HW_VAR_SIFS, - HW_VAR_DIFS, - HW_VAR_EIFS, - HW_VAR_SLOT_TIME, - HW_VAR_ACK_PREAMBLE, - HW_VAR_CW_CONFIG, - HW_VAR_CW_VALUES, - HW_VAR_RATE_FALLBACK_CONTROL, - HW_VAR_CONTENTION_WINDOW, - HW_VAR_RETRY_COUNT, - HW_VAR_TR_SWITCH, - HW_VAR_COMMAND, - HW_VAR_WPA_CONFIG, - HW_VAR_AMPDU_MIN_SPACE, - HW_VAR_SHORTGI_DENSITY, - HW_VAR_AMPDU_FACTOR, - HW_VAR_MCS_RATE_AVAILABLE, - HW_VAR_AC_PARAM, - HW_VAR_ACM_CTRL, - HW_VAR_DIS_Req_Qsize, - HW_VAR_CCX_CHNL_LOAD, - HW_VAR_CCX_NOISE_HISTOGRAM, - HW_VAR_CCX_CLM_NHM, - HW_VAR_TxOPLimit, - HW_VAR_TURBO_MODE, - HW_VAR_RF_STATE, - HW_VAR_RF_OFF_BY_HW, - HW_VAR_BUS_SPEED, - HW_VAR_SET_DEV_POWER, - - HW_VAR_RCR, - HW_VAR_RATR_0, - HW_VAR_RRSR, - HW_VAR_CPU_RST, - HW_VAR_CECHK_BSSID, - HW_VAR_LBK_MODE, - HW_VAR_AES_11N_FIX, - HW_VAR_USB_RX_AGGR, - HW_VAR_USER_CONTROL_TURBO_MODE, - HW_VAR_RETRY_LIMIT, - HW_VAR_INIT_TX_RATE, - HW_VAR_TX_RATE_REG, - HW_VAR_EFUSE_USAGE, - HW_VAR_EFUSE_BYTES, - HW_VAR_AUTOLOAD_STATUS, - HW_VAR_RF_2R_DISABLE, - HW_VAR_SET_RPWM, - HW_VAR_H2C_FW_PWRMODE, - HW_VAR_H2C_FW_JOINBSSRPT, - HW_VAR_1X1_RECV_COMBINE, - HW_VAR_STOP_SEND_BEACON, - HW_VAR_TSF_TIMER, - HW_VAR_IO_CMD, - - HW_VAR_RF_RECOVERY, - HW_VAR_H2C_FW_UPDATE_GTK, - HW_VAR_WF_MASK, - HW_VAR_WF_CRC, - HW_VAR_WF_IS_MAC_ADDR, - HW_VAR_H2C_FW_OFFLOAD, - HW_VAR_RESET_WFCRC, - - HW_VAR_HANDLE_FW_C2H, - HW_VAR_DL_FW_RSVD_PAGE, - HW_VAR_AID, - HW_VAR_HW_SEQ_ENABLE, - HW_VAR_CORRECT_TSF, - HW_VAR_BCN_VALID, - HW_VAR_FWLPS_RF_ON, - HW_VAR_DUAL_TSF_RST, - HW_VAR_SWITCH_EPHY_WoWLAN, - HW_VAR_INT_MIGRATION, - HW_VAR_INT_AC, - HW_VAR_RF_TIMING, -}; - -enum rt_op_mode { - RT_OP_MODE_AP, - RT_OP_MODE_INFRASTRUCTURE, - RT_OP_MODE_IBSS, - RT_OP_MODE_NO_LINK, -}; - -#define asifs_time \ - ((priv->rtllib->current_network.mode == WIRELESS_MODE_N_24G) ? 16 : 10) - -#define MGMT_QUEUE_NUM 5 - -#define MAX_IE_LEN 0xff - -#define msleep_interruptible_rsl msleep_interruptible - -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - * 6.2.1.1.2. - * - * The figure in section 7.1.2 suggests a body size of up to 2312 - * bytes is allowed, which is a bit confusing, I suspect this - * represents the 2304 bytes of real data, plus a possible 8 bytes of - * WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) - */ -#define RTLLIB_1ADDR_LEN 10 -#define RTLLIB_2ADDR_LEN 16 -#define RTLLIB_3ADDR_LEN 24 -#define RTLLIB_4ADDR_LEN 30 -#define RTLLIB_FCS_LEN 4 - -#define RTLLIB_SKBBUFFER_SIZE 2500 - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - -#define RTLLIB_FTYPE_MGMT 0x0000 -#define RTLLIB_FTYPE_CTL 0x0004 -#define RTLLIB_FTYPE_DATA 0x0008 - -#define RTLLIB_SCTL_FRAG 0x000F -#define RTLLIB_SCTL_SEQ 0xFFF0 - -/* QOS control */ -#define RTLLIB_QCTL_TID 0x000F - -#define FC_QOS_BIT BIT(7) -#define is_data_frame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false) -#define is_legacy_data_frame(pdu) (is_data_frame(pdu) && (!(pdu[0]&FC_QOS_BIT))) -#define is_qos_data_frame(pframe) \ - ((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \ - (IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) -#define frame_order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER) -#define SN_LESS(a, b) (((a-b)&0x800) != 0) -#define SN_EQUAL(a, b) (a == b) -#define MAX_DEV_ADDR_SIZE 8 - -enum act_category { - ACT_CAT_QOS = 1, - ACT_CAT_DLS = 2, - ACT_CAT_BA = 3, - ACT_CAT_HT = 7, - ACT_CAT_WMM = 17, -}; - -enum ba_action { - ACT_ADDBAREQ = 0, - ACT_ADDBARSP = 1, - ACT_DELBA = 2, -}; - -enum init_gain_op_type { - IG_Backup = 0, - IG_Restore, - IG_Max -}; - -enum wireless_mode { - WIRELESS_MODE_UNKNOWN = 0x00, - WIRELESS_MODE_A = 0x01, - WIRELESS_MODE_B = 0x02, - WIRELESS_MODE_G = 0x04, - WIRELESS_MODE_AUTO = 0x08, - WIRELESS_MODE_N_24G = 0x10, -}; - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ -#endif /* ETH_P_PAE */ - -#ifndef ETH_P_80211_RAW -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) -#endif - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct rtllib_snap_hdr { - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __packed; - -enum _REG_PREAMBLE_MODE { - PREAMBLE_LONG = 1, - PREAMBLE_AUTO = 2, - PREAMBLE_SHORT = 3, -}; - -#define SNAP_SIZE sizeof(struct rtllib_snap_hdr) - -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) -#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) - -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG) -#define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4) - -/* Authentication algorithms */ -#define WLAN_AUTH_OPEN 0 -#define WLAN_AUTH_SHARED_KEY 1 -#define WLAN_AUTH_LEAP 128 - -#define WLAN_CAPABILITY_ESS (1<<0) -#define WLAN_CAPABILITY_IBSS (1<<1) -#define WLAN_CAPABILITY_PRIVACY (1<<4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) -#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) - -#define RTLLIB_STATMASK_SIGNAL (1<<0) -#define RTLLIB_STATMASK_RSSI (1<<1) -#define RTLLIB_STATMASK_NOISE (1<<2) -#define RTLLIB_STATMASK_WEMASK 0x7 - -#define RTLLIB_CCK_MODULATION (1<<0) -#define RTLLIB_OFDM_MODULATION (1<<1) - -#define RTLLIB_CCK_RATE_LEN 4 -#define RTLLIB_CCK_RATE_1MB 0x02 -#define RTLLIB_CCK_RATE_2MB 0x04 -#define RTLLIB_CCK_RATE_5MB 0x0B -#define RTLLIB_CCK_RATE_11MB 0x16 -#define RTLLIB_OFDM_RATE_LEN 8 -#define RTLLIB_OFDM_RATE_6MB 0x0C -#define RTLLIB_OFDM_RATE_9MB 0x12 -#define RTLLIB_OFDM_RATE_12MB 0x18 -#define RTLLIB_OFDM_RATE_18MB 0x24 -#define RTLLIB_OFDM_RATE_24MB 0x30 -#define RTLLIB_OFDM_RATE_36MB 0x48 -#define RTLLIB_OFDM_RATE_48MB 0x60 -#define RTLLIB_OFDM_RATE_54MB 0x6C -#define RTLLIB_BASIC_RATE_MASK 0x80 - -/* this is stolen and modified from the madwifi driver*/ -#define RTLLIB_FC0_TYPE_MASK 0x0c -#define RTLLIB_FC0_TYPE_DATA 0x08 -#define RTLLIB_FC0_SUBTYPE_MASK 0xB0 -#define RTLLIB_FC0_SUBTYPE_QOS 0x80 - -#define RTLLIB_QOS_HAS_SEQ(fc) \ - (((fc) & (RTLLIB_FC0_TYPE_MASK | RTLLIB_FC0_SUBTYPE_MASK)) == \ - (RTLLIB_FC0_TYPE_DATA | RTLLIB_FC0_SUBTYPE_QOS)) - -/* this is stolen from ipw2200 driver */ -#define IEEE_IBSS_MAC_HASH_SIZE 31 - -/* NOTE: This data is for statistical purposes; not all hardware provides this - * information for frames received. Not setting these will not cause - * any adverse affects. - */ -struct rtllib_rx_stats { - s8 rssi; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ - u8 control; - u8 mask; - u16 len; - u16 Length; - u8 SignalQuality; - s32 RecvSignalPower; - u8 SignalStrength; - u16 bHwError:1; - u16 bCRC:1; - u16 bICV:1; - u16 decrypted:1; - u32 time_stamp_low; - u32 time_stamp_high; - - u8 RxDrvInfoSize; - u8 RxBufShift; - bool bIsAMPDU; - bool bFirstMPDU; - bool contain_htc; - u32 RxPWDBAll; - u8 RxMIMOSignalStrength[4]; - s8 RxMIMOSignalQuality[2]; - bool bPacketMatchBSSID; - bool bIsCCK; - bool bPacketToSelf; - bool bPacketBeacon; - bool bToSelfBA; -}; - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. - */ -#define RTLLIB_FRAG_CACHE_LEN 4 - -struct rtllib_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - -struct rtllib_device; - -#define SEC_ACTIVE_KEY (1<<4) -#define SEC_AUTH_MODE (1<<5) -#define SEC_UNICAST_GROUP (1<<6) -#define SEC_LEVEL (1<<7) -#define SEC_ENABLED (1<<8) - -#define SEC_LEVEL_0 0 /* None */ -#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ -#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ -#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ -#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ - -#define SEC_ALG_NONE 0 -#define SEC_ALG_WEP 1 -#define SEC_ALG_TKIP 2 -#define SEC_ALG_CCMP 4 - -#define WEP_KEY_LEN 13 -#define SCM_KEY_LEN 32 - -struct rtllib_security { - u16 active_key:2, - enabled:1, - auth_mode:2, - auth_algo:4, - unicast_uses_group:1, - encrypt:1; - u8 key_sizes[NUM_WEP_KEYS]; - u8 keys[NUM_WEP_KEYS][SCM_KEY_LEN]; - u8 level; - u16 flags; -} __packed; - -/* 802.11 data frame from AP - * ,-------------------------------------------------------------------. - * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - * |------|------|---------|---------|---------|------|---------|------| - * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - * | | tion | (BSSID) | | | ence | data | | - * `-------------------------------------------------------------------' - * Total: 28-2340 bytes - */ - -/* Management Frame Information Element Types */ -enum rtllib_mfie { - MFIE_TYPE_SSID = 0, - MFIE_TYPE_RATES = 1, - MFIE_TYPE_FH_SET = 2, - MFIE_TYPE_DS_SET = 3, - MFIE_TYPE_CF_SET = 4, - MFIE_TYPE_TIM = 5, - MFIE_TYPE_IBSS_SET = 6, - MFIE_TYPE_COUNTRY = 7, - MFIE_TYPE_HOP_PARAMS = 8, - MFIE_TYPE_HOP_TABLE = 9, - MFIE_TYPE_REQUEST = 10, - MFIE_TYPE_CHALLENGE = 16, - MFIE_TYPE_POWER_CONSTRAINT = 32, - MFIE_TYPE_POWER_CAPABILITY = 33, - MFIE_TYPE_TPC_REQUEST = 34, - MFIE_TYPE_TPC_REPORT = 35, - MFIE_TYPE_SUPP_CHANNELS = 36, - MFIE_TYPE_CSA = 37, - MFIE_TYPE_MEASURE_REQUEST = 38, - MFIE_TYPE_MEASURE_REPORT = 39, - MFIE_TYPE_QUIET = 40, - MFIE_TYPE_IBSS_DFS = 41, - MFIE_TYPE_ERP = 42, - MFIE_TYPE_HT_CAP = 45, - MFIE_TYPE_RSN = 48, - MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_HT_INFO = 61, - MFIE_TYPE_AIRONET = 133, - MFIE_TYPE_GENERIC = 221, - MFIE_TYPE_QOS_PARAMETER = 222, -}; - -/* Minimal header; can be used for passing 802.11 frames with sufficient - * information to determine what type of underlying data type is actually - * stored in the data. - */ -struct rtllib_info_element { - u8 id; - u8 len; - u8 data[]; -} __packed; - -struct rtllib_authentication { - struct ieee80211_hdr_3addr header; - __le16 algorithm; - __le16 transaction; - __le16 status; - /*challenge*/ - struct rtllib_info_element info_element[]; -} __packed __aligned(2); - -struct rtllib_disauth { - struct ieee80211_hdr_3addr header; - __le16 reason; -} __packed __aligned(2); - -struct rtllib_disassoc { - struct ieee80211_hdr_3addr header; - __le16 reason; -} __packed __aligned(2); - -struct rtllib_probe_request { - struct ieee80211_hdr_3addr header; - /* SSID, supported rates */ - struct rtllib_info_element info_element[]; -} __packed __aligned(2); - -struct rtllib_probe_response { - struct ieee80211_hdr_3addr header; - u32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN - */ - struct rtllib_info_element info_element[]; -} __packed __aligned(2); - -/* Alias beacon for probe_response */ -#define rtllib_beacon rtllib_probe_response - -struct rtllib_assoc_request_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - /* SSID, supported rates, RSN */ - struct rtllib_info_element info_element[]; -} __packed __aligned(2); - -struct rtllib_assoc_response_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 status; - __le16 aid; - struct rtllib_info_element info_element[]; /* supported rates */ -} __packed __aligned(2); - -struct rtllib_txb { - u8 nr_frags; - u8 encrypted; - u8 queue_index; - u8 rts_included; - u16 reserved; - __le16 frag_size; - __le16 payload_size; - struct sk_buff *fragments[] __counted_by(nr_frags); -}; - -#define MAX_SUBFRAME_COUNT 64 -struct rtllib_rxb { - u8 nr_subframes; - struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; -}; - -union frameqos { - u16 shortdata; - u8 chardata[2]; - struct { - u16 tid:4; - u16 eosp:1; - u16 ack_policy:2; - u16 reserved:1; - u16 txop:8; - } field; -}; - -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... - */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) -#define MAX_NETWORK_COUNT 96 - -#define MAX_CHANNEL_NUMBER 161 -#define RTLLIB_SOFTMAC_SCAN_TIME 100 -#define RTLLIB_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) - -#define MAX_WPA_IE_LEN 64 -#define MAX_WZC_IE_LEN 256 - -#define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) - -/* QoS structure */ -#define NETWORK_HAS_QOS_PARAMETERS (1<<3) -#define NETWORK_HAS_QOS_INFORMATION (1<<4) -#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ - NETWORK_HAS_QOS_INFORMATION) -/* 802.11h */ -#define NETWORK_HAS_ERP_VALUE (1<<10) - -#define QOS_QUEUE_NUM 4 -#define QOS_OUI_LEN 3 -#define QOS_OUI_TYPE 2 -#define QOS_ELEMENT_ID 221 -#define QOS_OUI_INFO_SUB_TYPE 0 -#define QOS_OUI_PARAM_SUB_TYPE 1 -#define QOS_VERSION_1 1 - -struct rtllib_qos_information_element { - u8 element_id; - u8 length; - u8 qui[QOS_OUI_LEN]; - u8 qui_type; - u8 qui_subtype; - u8 version; - u8 ac_info; -} __packed; - -struct rtllib_qos_ac_parameter { - u8 aci_aifsn; - u8 ecw_min_max; - __le16 tx_op_limit; -} __packed; - -struct rtllib_qos_parameter_info { - struct rtllib_qos_information_element info_element; - u8 reserved; - struct rtllib_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; -} __packed; - -struct rtllib_qos_parameters { - __le16 cw_min[QOS_QUEUE_NUM]; - __le16 cw_max[QOS_QUEUE_NUM]; - u8 aifs[QOS_QUEUE_NUM]; - u8 flag[QOS_QUEUE_NUM]; - __le16 tx_op_limit[QOS_QUEUE_NUM]; -} __packed; - -struct rtllib_qos_data { - struct rtllib_qos_parameters parameters; - unsigned int wmm_acm; - int active; - int supported; - u8 param_count; - u8 old_param_count; -}; - -struct rtllib_tim_parameters { - u8 tim_count; - u8 tim_period; -} __packed; - -struct rtllib_wmm_ac_param { - u8 ac_aci_acm_aifsn; - u8 ac_ecwmin_ecwmax; - u16 ac_txop_limit; -}; - -enum eap_type { - EAP_PACKET = 0, - EAPOL_START, - EAPOL_LOGOFF, - EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT -}; - -static const char * const eap_types[] = { - [EAP_PACKET] = "EAP-Packet", - [EAPOL_START] = "EAPOL-Start", - [EAPOL_LOGOFF] = "EAPOL-Logoff", - [EAPOL_KEY] = "EAPOL-Key", - [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" -}; - -static inline const char *eap_get_type(int type) -{ - return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : - eap_types[type]; -} - -static inline u8 frame_qos_tid(u8 *buf) -{ - struct ieee80211_hdr_3addr *hdr; - u16 fc; - - hdr = (struct ieee80211_hdr_3addr *)buf; - fc = le16_to_cpu(hdr->frame_control); - return (u8)((union frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) && - (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid; -} - -struct eapol { - u8 snap[6]; - u16 ethertype; - u8 version; - u8 type; - u16 length; -} __packed; - -struct rtllib_softmac_stats { - unsigned int rx_ass_ok; - unsigned int rx_ass_err; - unsigned int rx_probe_rq; - unsigned int tx_probe_rs; - unsigned int tx_beacons; - unsigned int rx_auth_rq; - unsigned int rx_auth_rs_ok; - unsigned int rx_auth_rs_err; - unsigned int tx_auth_rq; - unsigned int no_auth_rs; - unsigned int no_ass_rs; - unsigned int tx_ass_rq; - unsigned int rx_ass_rq; - unsigned int tx_probe_rq; - unsigned int reassoc; - unsigned int swtxstop; - unsigned int swtxawake; - unsigned char CurrentShowTxate; - unsigned char last_packet_rate; - unsigned int txretrycount; -}; - -/* These are the data types that can make up management packets - * - * u16 auth_algorithm; - * u16 auth_sequence; - * u16 beacon_interval; - * u16 capability; - * u8 current_ap[ETH_ALEN]; - * u16 listen_interval; - * struct { - * u16 association_id:14, reserved:2; - * } __packed; - * u32 time_stamp[2]; - * u16 reason; - * u16 status; - */ - -#define RTLLIB_DEFAULT_TX_ESSID "Penguin" -#define RTLLIB_DEFAULT_BASIC_RATE 2 - -enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; -#define MAX_SP_Len (WMM_all_frame << 4) -#define RTLLIB_QOS_TID 0x0f -#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) - -#define RTLLIB_DTIM_MBCAST 4 -#define RTLLIB_DTIM_UCAST 2 -#define RTLLIB_DTIM_VALID 1 -#define RTLLIB_DTIM_INVALID 0 - -#define RTLLIB_PS_DISABLED 0 -#define RTLLIB_PS_UNICAST RTLLIB_DTIM_UCAST -#define RTLLIB_PS_MBCAST RTLLIB_DTIM_MBCAST - -#define WME_AC_BK 0x00 -#define WME_AC_BE 0x01 -#define WME_AC_VI 0x02 -#define WME_AC_VO 0x03 -#define WME_AC_PRAM_LEN 16 - -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -#define UP2AC(up) ( \ - ((up) < 1) ? WME_AC_BE : \ - ((up) < 3) ? WME_AC_BK : \ - ((up) < 4) ? WME_AC_BE : \ - ((up) < 6) ? WME_AC_VI : \ - WME_AC_VO) - -#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address - * plus ether type - */ - -enum erp_t { - ERP_NonERPpresent = 0x01, - ERP_UseProtection = 0x02, - ERP_BarkerPreambleMode = 0x04, -}; - -struct rtllib_network { - /* These entries are used to identify a unique network */ - u8 bssid[ETH_ALEN]; - u8 channel; - /* Ensure null-terminated for any debug msgs */ - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - u8 hidden_ssid[IW_ESSID_MAX_SIZE + 1]; - u8 hidden_ssid_len; - struct rtllib_qos_data qos_data; - - bool with_aironet_ie; - bool ckip_supported; - bool ccx_rm_enable; - u8 ccx_rm_state[2]; - bool mb_ssid_valid; - u8 mb_ssid_mask; - u8 mb_ssid[ETH_ALEN]; - bool with_ccx_ver_num; - u8 bss_ccx_ver_number; - /* These are network statistics */ - struct rtllib_rx_stats stats; - u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; - unsigned long last_scanned; - u8 mode; - u32 flags; - u32 time_stamp[2]; - u16 beacon_interval; - u16 listen_interval; - u16 atim_window; - u8 erp_value; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - u8 wzc_ie[MAX_WZC_IE_LEN]; - size_t wzc_ie_len; - - struct rtllib_tim_parameters tim; - u8 dtim_period; - u8 dtim_data; - u64 last_dtim_sta_time; - - u8 wmm_info; - struct rtllib_wmm_ac_param wmm_param[4]; - u8 turbo_enable; - u16 country_ie_len; - u8 country_ie_buf[MAX_IE_LEN]; - struct bss_ht bssht; - bool broadcom_cap_exist; - bool realtek_cap_exit; - bool marvell_cap_exist; - bool ralink_cap_exist; - bool atheros_cap_exist; - bool cisco_cap_exist; - bool airgo_cap_exist; - bool unknown_cap_exist; - bool berp_info_valid; - bool buseprotection; - u8 SignalStrength; - u8 RSSI; - struct list_head list; -}; - -enum rtl_link_state { - /* the card is not linked at all */ - MAC80211_NOLINK = 0, - - /* RTLLIB_ASSOCIATING* are for BSS client mode - * the driver shall not perform RX filtering unless - * the state is LINKED. - * The driver shall just check for the state LINKED and - * defaults to NOLINK for ALL the other states (including - * LINKED_SCANNING) - */ - - /* the association procedure will start (wq scheduling)*/ - RTLLIB_ASSOCIATING, - RTLLIB_ASSOCIATING_RETRY, - - /* the association procedure is sending AUTH request*/ - RTLLIB_ASSOCIATING_AUTHENTICATING, - - /* the association procedure has successfully authenticated - * and is sending association request - */ - RTLLIB_ASSOCIATING_AUTHENTICATED, - - /* the link is ok. the card associated to a BSS or linked - * to a ibss cell or acting as an AP and creating the bss - */ - MAC80211_LINKED, - - /* same as LINKED, but the driver shall apply RX filter - * rules as we are in NO_LINK mode. As the card is still - * logically linked, but it is doing a syncro site survey - * then it will be back to LINKED state. - */ - MAC80211_LINKED_SCANNING, -}; - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) -#define DEFAULT_FTS 2346 - -#define CFG_RTLLIB_RESERVE_FCS (1<<0) -#define CFG_RTLLIB_COMPUTE_FCS (1<<1) - -struct tx_pending { - int frag; - struct rtllib_txb *txb; -}; - -struct bandwidth_autoswitch { - long threshold_20Mhzto40Mhz; - long threshold_40Mhzto20Mhz; - bool forced_tx_20MHz; - bool bautoswitch_enable; -}; - -#define REORDER_WIN_SIZE 128 -#define REORDER_ENTRY_NUM 128 -struct rx_reorder_entry { - struct list_head list; - u16 SeqNum; - struct rtllib_rxb *prxb; -}; - -enum fsync_state { - DEFAULT_FSYNC, - HW_FSYNC, - SW_FSYNC -}; - -enum ips_callback_function { - IPS_CALLBACK_NONE = 0, - IPS_CALLBACK_MGNT_LINK_REQUEST = 1, - IPS_CALLBACK_JOIN_REQUEST = 2, -}; - -enum rt_rf_power_state { - rf_on, - rf_sleep, - rf_off -}; - -struct rt_pwr_save_ctrl { - bool bSwRfProcessing; - enum rt_rf_power_state eInactivePowerState; - enum ips_callback_function return_point; - - bool bLeisurePs; - u8 lps_idle_count; - u8 lps_awake_intvl; - - u32 CurPsLevel; -}; - -#define RT_RF_CHANGE_SOURCE u32 - -#define RF_CHANGE_BY_SW BIT(31) -#define RF_CHANGE_BY_HW BIT(30) -#define RF_CHANGE_BY_PS BIT(29) -#define RF_CHANGE_BY_IPS BIT(28) -#define RF_CHANGE_BY_INIT 0 - -enum country_code_type { - COUNTRY_CODE_FCC = 0, - COUNTRY_CODE_IC = 1, - COUNTRY_CODE_ETSI = 2, - COUNTRY_CODE_SPAIN = 3, - COUNTRY_CODE_FRANCE = 4, - COUNTRY_CODE_MKK = 5, - COUNTRY_CODE_MKK1 = 6, - COUNTRY_CODE_ISRAEL = 7, - COUNTRY_CODE_TELEC = 8, - COUNTRY_CODE_MIC = 9, - COUNTRY_CODE_GLOBAL_DOMAIN = 10, - COUNTRY_CODE_WORLD_WIDE_13 = 11, - COUNTRY_CODE_TELEC_NETGEAR = 12, - COUNTRY_CODE_MAX -}; - -enum scan_op_backup_opt { - SCAN_OPT_BACKUP = 0, - SCAN_OPT_RESTORE, - SCAN_OPT_MAX -}; - -#define RT_MAX_LD_SLOT_NUM 10 -struct rt_link_detect { - u32 num_recv_bcn_in_period; - u32 num_recv_data_in_period; - - u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; - u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; - u16 slot_num; - u16 slot_index; - - u32 num_tx_ok_in_period; - u32 num_rx_ok_in_period; - u32 num_rx_unicast_ok_in_period; - bool busy_traffic; - bool bHigherBusyTraffic; - bool bHigherBusyRxTraffic; -}; - -struct sw_cam_table { - u8 macaddr[ETH_ALEN]; - bool bused; - u8 key_buf[16]; - u16 key_type; - u8 useDK; - u8 key_index; - -}; - -#define TOTAL_CAM_ENTRY 32 -struct rate_adaptive { - u8 ratr_state; - u16 reserve; - - u32 high_rssi_thresh_for_ra; - u32 high2low_rssi_thresh_for_ra; - u8 low2high_rssi_thresh_for_ra40M; - u32 low_rssi_thresh_for_ra40M; - u8 low2high_rssi_thresh_for_ra20M; - u32 low_rssi_thresh_for_ra20M; - u32 upper_rssi_threshold_ratr; - u32 middle_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr_40M; - u32 low_rssi_threshold_ratr_20M; - u8 ping_rssi_enable; - u32 ping_rssi_ratr; - u32 ping_rssi_thresh_for_ra; - u8 PreRATRState; - -}; - -#define NUM_PMKID_CACHE 16 -struct rt_pmkid_list { - u8 bssid[ETH_ALEN]; - u8 PMKID[16]; - u8 SsidBuf[33]; - u8 used; -}; - -/*************** DRIVER STATUS *****/ -#define STATUS_SCANNING 0 -/*************** DRIVER STATUS *****/ - -enum { - LPS_IS_WAKE = 0, - LPS_IS_SLEEP = 1, - LPS_WAIT_NULL_DATA_SEND = 2, -}; - -struct rtllib_device { - struct pci_dev *pdev; - struct net_device *dev; - struct rtllib_security sec; - - bool disable_mgnt_queue; - - unsigned long status; - u8 cnt_after_link; - - enum rt_op_mode op_mode; - - /* The last AssocReq/Resp IEs */ - u8 *assocreq_ies, *assocresp_ies; - size_t assocreq_ies_len, assocresp_ies_len; - - bool forced_bg_mode; - - u8 hwsec_active; - bool is_roaming; - bool ieee_up; - bool cannot_notify; - bool bSupportRemoteWakeUp; - bool actscanning; - bool first_ie_in_scan; - bool be_scan_inprogress; - bool beinretry; - enum rt_rf_power_state rf_power_state; - RT_RF_CHANGE_SOURCE rf_off_reason; - bool is_set_key; - bool wx_set_enc; - struct rt_hi_throughput *ht_info; - - spinlock_t reorder_spinlock; - u8 reg_dot11ht_oper_rate_set[16]; - u8 reg_dot11tx_ht_oper_rate_set[16]; - u8 dot11ht_oper_rate_set[16]; - u8 reg_ht_supp_rate_set[16]; - u8 ht_curr_op_rate; - u8 HTHighestOperaRate; - u8 tx_dis_rate_fallback; - u8 tx_use_drv_assinged_rate; - u8 tx_enable_fw_calc_dur; - atomic_t atm_swbw; - - struct list_head Tx_TS_Admit_List; - struct list_head Tx_TS_Pending_List; - struct list_head Tx_TS_Unused_List; - struct tx_ts_record tx_ts_records[TOTAL_TS_NUM]; - struct list_head Rx_TS_Admit_List; - struct list_head Rx_TS_Pending_List; - struct list_head Rx_TS_Unused_List; - struct rx_ts_record rx_ts_records[TOTAL_TS_NUM]; - struct rx_reorder_entry RxReorderEntry[128]; - struct list_head RxReorder_Unused_List; - - /* Bookkeeping structures */ - struct net_device_stats stats; - struct rtllib_softmac_stats softmac_stats; - - /* Probe / Beacon management */ - struct list_head network_free_list; - struct list_head network_list; - struct rtllib_network *networks; - int scans; - int scan_age; - - int iw_mode; /* operating mode (IW_MODE_*) */ - - spinlock_t lock; - spinlock_t wpax_suitlist_lock; - - int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs - */ - u32 config; - - /* WEP and other encryption related settings at the device level */ - int open_wep; /* Set to 1 to allow unencrypted frames */ - int auth_mode; - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes - */ - - int ieee802_1x; /* is IEEE 802.1X used */ - - /* WPA data */ - bool half_wireless_n24g_mode; - int wpa_enabled; - int drop_unencrypted; - int tkip_countermeasures; - int privacy_invoked; - size_t wpa_ie_len; - u8 *wpa_ie; - size_t wps_ie_len; - u8 *wps_ie; - u8 ap_mac_addr[ETH_ALEN]; - u16 pairwise_key_type; - u16 group_key_type; - - struct lib80211_crypt_info crypt_info; - - struct sw_cam_table swcamtable[TOTAL_CAM_ENTRY]; - - struct rt_pmkid_list pmkid_list[NUM_PMKID_CACHE]; - - /* Fragmentation structures */ - struct rtllib_frag_entry frag_cache[17][RTLLIB_FRAG_CACHE_LEN]; - unsigned int frag_next_idx[17]; - u16 fts; /* Fragmentation Threshold */ -#define DEFAULT_RTS_THRESHOLD 2346U -#define MIN_RTS_THRESHOLD 1 -#define MAX_RTS_THRESHOLD 2346U - u16 rts; /* RTS threshold */ - - /* Association info */ - u8 bssid[ETH_ALEN]; - - /* This stores infos for the current network. - * Either the network we are associated in INFRASTRUCTURE - * or the network that we are creating in MASTER mode. - * ad-hoc is a mixture ;-). - * Note that in infrastructure mode, even when not associated, - * fields bssid and essid may be valid (if wpa_set and essid_set - * are true) as thy carry the value set by the user via iwconfig - */ - struct rtllib_network current_network; - - enum rtl_link_state link_state; - - int mode; /* A, B, G */ - - /* used for forcing the ibss workqueue to terminate - * without wait for the syncro scan to terminate - */ - short sync_scan_hurryup; - u16 scan_watch_dog; - - /* map of allowed channels. 0 is dummy */ - u8 active_channel_map[MAX_CHANNEL_NUMBER+1]; - - int rate; /* current rate */ - int basic_rate; - - /* this contains flags for selectively enable softmac support */ - u16 softmac_features; - - /* if the sequence control field is not filled by HW */ - u16 seq_ctrl[5]; - - /* association procedure transaction sequence number */ - u16 associate_seq; - - /* AID for RTXed association responses */ - u16 assoc_id; - - /* power save mode related*/ - u8 ack_tx_to_ieee; - short ps; - short sta_sleep; - int ps_timeout; - int ps_period; - struct work_struct ps_task; - u64 ps_time; - bool polling; - - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - short queue_stop; - short scanning_continue; - short proto_started; - short proto_stoppping; - - struct mutex wx_mutex; - struct mutex scan_mutex; - struct mutex ips_mutex; - - spinlock_t mgmt_tx_lock; - spinlock_t beacon_lock; - - short beacon_txing; - - short wap_set; - short ssid_set; - - /* set on initialization */ - unsigned int wmm_acm; - - /* for discarding duplicated packets in IBSS */ - struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; - - /* for discarding duplicated packets in BSS */ - u16 last_rxseq_num[17]; /* rx seq previous per-tid */ - u16 last_rxfrag_num[17];/* tx frag previous per-tid */ - unsigned long last_packet_time[17]; - - /* for PS mode */ - unsigned long last_rx_ps_time; - bool awake_pkt_sent; - u8 lps_delay_cnt; - - /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ - struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; - int mgmt_queue_head; - int mgmt_queue_tail; - u8 asoc_retry_count; - struct sk_buff_head skb_waitq[MAX_QUEUE_SIZE]; - - bool bdynamic_txpower_enable; - - bool bCTSToSelfEnable; - - u32 fsync_time_interval; - u32 fsync_rate_bitmap; - u8 fsync_rssi_threshold; - bool bfsync_enable; - - u8 fsync_multiple_timeinterval; - u32 fsync_firstdiff_ratethreshold; - u32 fsync_seconddiff_ratethreshold; - enum fsync_state fsync_state; - bool bis_any_nonbepkts; - struct bandwidth_autoswitch bandwidth_auto_switch; - bool FwRWRF; - - struct rt_link_detect link_detect_info; - bool is_aggregate_frame; - struct rt_pwr_save_ctrl pwr_save_ctrl; - - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - struct tx_pending tx_pending; - - /* used if IEEE_SOFTMAC_ASSOCIATE is set */ - struct timer_list associate_timer; - - /* used if IEEE_SOFTMAC_BEACONS is set */ - u8 need_sw_enc; - struct work_struct associate_complete_wq; - struct work_struct ips_leave_wq; - struct delayed_work associate_procedure_wq; - struct delayed_work softmac_scan_wq; - struct delayed_work associate_retry_wq; - struct delayed_work hw_wakeup_wq; - struct delayed_work hw_sleep_wq; - struct delayed_work link_change_wq; - struct work_struct wx_sync_scan_wq; - - union { - struct rtllib_rxb *rfd_array[REORDER_WIN_SIZE]; - struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; - struct rtllib_rxb *prxb_indicate_array[REORDER_WIN_SIZE]; - struct { - struct sw_chnl_cmd PreCommonCmd[MAX_PRECMD_CNT]; - struct sw_chnl_cmd PostCommonCmd[MAX_POSTCMD_CNT]; - struct sw_chnl_cmd RfDependCmd[MAX_RFDEPENDCMD_CNT]; - }; - }; - - /* Callback functions */ - - /* Softmac-generated frames (management) are TXed via this - * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is - * not set. As some cards may have different HW queues that - * one might want to use for data and management frames - * the option to have two callbacks might be useful. - * This function can't sleep. - */ - int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev); - - /* used instead of hard_start_xmit (not softmac_hard_start_xmit) - * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set - * then also management frames are sent via this callback. - * This function can't sleep. - */ - void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev, int rate); - - /* ask to the driver to retune the radio. - * This function can sleep. the driver should ensure - * the radio has been switched before return. - */ - void (*set_chan)(struct net_device *dev, u8 ch); - - /* indicate the driver that the link state is changed - * for example it may indicate the card is associated now. - * Driver might be interested in this to apply RX filter - * rules or simply light the LINK led - */ - void (*link_change)(struct net_device *dev); - - /* power save mode related */ - void (*sta_wake_up)(struct net_device *dev); - void (*enter_sleep_state)(struct net_device *dev, u64 time); - short (*ps_is_queue_empty)(struct net_device *dev); - int (*handle_beacon)(struct net_device *dev, - struct rtllib_beacon *beacon, - struct rtllib_network *network); - int (*handle_assoc_response)(struct net_device *dev, - struct rtllib_assoc_response_frame *resp, - struct rtllib_network *network); - - /* check whether Tx hw resource available */ - short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); - void (*set_bw_mode_handler)(struct net_device *dev, - enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset); - bool (*get_nmode_support_by_sec_cfg)(struct net_device *dev); - void (*set_wireless_mode)(struct net_device *dev, u8 wireless_mode); - bool (*get_half_nmode_support_by_aps_handler)(struct net_device *dev); - u8 (*rtllib_ap_sec_type)(struct rtllib_device *ieee); - void (*init_gain_handler)(struct net_device *dev, u8 Operation); - void (*ScanOperationBackupHandler)(struct net_device *dev, - u8 Operation); - void (*set_hw_reg_handler)(struct net_device *dev, u8 variable, u8 *val); - - void (*allow_all_dest_addr_handler)(struct net_device *dev, - bool allow_all_da, - bool write_into_reg); - - void (*rtllib_ips_leave_wq)(struct net_device *dev); - void (*rtllib_ips_leave)(struct net_device *dev); - void (*leisure_ps_leave)(struct net_device *dev); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_rtllib - */ - u8 priv[]; -}; - -#define IEEE_MODE_MASK (WIRELESS_MODE_B | WIRELESS_MODE_G) - -/* Generate a 802.11 header */ - -/* Uses the channel change callback directly - * instead of [start/stop] scan callbacks - */ -#define IEEE_SOFTMAC_SCAN (1<<2) - -/* Perform authentication and association handshake */ -#define IEEE_SOFTMAC_ASSOCIATE (1<<3) - -/* Generate probe requests */ -#define IEEE_SOFTMAC_PROBERQ (1<<4) - -/* Generate response to probe requests */ -#define IEEE_SOFTMAC_PROBERS (1<<5) - -/* The ieee802.11 stack will manage the netif queue - * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. - */ -#define IEEE_SOFTMAC_TX_QUEUE (1<<7) - -/* Uses only the softmac_data_hard_start_xmit - * even for TX management frames. - */ -#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) - -/* Generate beacons. The stack will enqueue beacons - * to the card - */ -#define IEEE_SOFTMAC_BEACONS (1<<6) - -static inline void *rtllib_priv(struct net_device *dev) -{ - return ((struct rtllib_device *)netdev_priv(dev))->priv; -} - -static inline int rtllib_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - -static inline int rtllib_get_hdrlen(u16 fc) -{ - int hdrlen = RTLLIB_3ADDR_LEN; - - switch (WLAN_FC_GET_TYPE(fc)) { - case RTLLIB_FTYPE_DATA: - if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */ - if (RTLLIB_QOS_HAS_SEQ(fc)) - hdrlen += 2; /* QOS ctrl*/ - break; - case RTLLIB_FTYPE_CTL: - switch (WLAN_FC_GET_STYPE(fc)) { - case IEEE80211_STYPE_CTS: - case IEEE80211_STYPE_ACK: - hdrlen = RTLLIB_1ADDR_LEN; - break; - default: - hdrlen = RTLLIB_2ADDR_LEN; - break; - } - break; - } - - return hdrlen; -} - -static inline int rtllib_is_ofdm_rate(u8 rate) -{ - switch (rate & ~RTLLIB_BASIC_RATE_MASK) { - case RTLLIB_OFDM_RATE_6MB: - case RTLLIB_OFDM_RATE_9MB: - case RTLLIB_OFDM_RATE_12MB: - case RTLLIB_OFDM_RATE_18MB: - case RTLLIB_OFDM_RATE_24MB: - case RTLLIB_OFDM_RATE_36MB: - case RTLLIB_OFDM_RATE_48MB: - case RTLLIB_OFDM_RATE_54MB: - return 1; - } - return 0; -} - -static inline int rtllib_is_cck_rate(u8 rate) -{ - switch (rate & ~RTLLIB_BASIC_RATE_MASK) { - case RTLLIB_CCK_RATE_1MB: - case RTLLIB_CCK_RATE_2MB: - case RTLLIB_CCK_RATE_5MB: - case RTLLIB_CCK_RATE_11MB: - return 1; - } - return 0; -} - -/* rtllib.c */ -void free_rtllib(struct net_device *dev); -struct net_device *alloc_rtllib(int sizeof_priv); - -/* rtllib_tx.c */ - -int rtllib_encrypt_fragment(struct rtllib_device *ieee, - struct sk_buff *frag, - int hdr_len); - -netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev); -void rtllib_txb_free(struct rtllib_txb *txb); - -/* rtllib_rx.c */ -int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats); -int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel); - -/* rtllib_wx.c */ -int rtllib_wx_get_scan(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int rtllib_wx_set_encode(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int rtllib_wx_get_encode(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int rtllib_wx_set_auth(struct rtllib_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); -int rtllib_wx_set_mlme(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len); - -/* rtllib_softmac.c */ -int rtllib_rx_frame_softmac(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats, u16 type, - u16 stype); -void rtllib_softmac_new_net(struct rtllib_device *ieee, - struct rtllib_network *net); - -void send_disassociation(struct rtllib_device *ieee, bool deauth, u16 rsn); -void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee); - -int rtllib_softmac_init(struct rtllib_device *ieee); -void rtllib_softmac_free(struct rtllib_device *ieee); -void rtllib_disassociate(struct rtllib_device *ieee); -void rtllib_stop_scan(struct rtllib_device *ieee); -bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); -void rtllib_stop_scan_syncro(struct rtllib_device *ieee); -void rtllib_start_scan_syncro(struct rtllib_device *ieee); -void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); -void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee); -void rtllib_start_protocol(struct rtllib_device *ieee); -void rtllib_stop_protocol(struct rtllib_device *ieee); - -void rtllib_enable_net_monitor_mode(struct net_device *dev, bool init_state); -void rtllib_disable_net_monitor_mode(struct net_device *dev, bool init_state); - -void rtllib_softmac_stop_protocol(struct rtllib_device *ieee); -void rtllib_softmac_start_protocol(struct rtllib_device *ieee); - -void rtllib_reset_queue(struct rtllib_device *ieee); -void rtllib_wake_all_queues(struct rtllib_device *ieee); -void rtllib_stop_all_queues(struct rtllib_device *ieee); - -void notify_wx_assoc_event(struct rtllib_device *ieee); -void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success); - -void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee); -u8 rtllib_ap_sec_type(struct rtllib_device *ieee); - -/* rtllib_softmac_wx.c */ - -int rtllib_wx_get_wap(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); - -int rtllib_wx_set_wap(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *awrq, char *extra); - -int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int rtllib_wx_set_rate(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_get_rate(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int rtllib_wx_set_essid(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int rtllib_wx_get_freq(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); -void rtllib_wx_sync_scan_wq(void *data); - -int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_set_power(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_get_power(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_set_rts(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int rtllib_wx_get_rts(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -void ht_set_connect_bw_mode(struct rtllib_device *ieee, - enum ht_channel_width bandwidth, - enum ht_extchnl_offset Offset); -void ht_update_default_setting(struct rtllib_device *ieee); -void ht_construct_capability_element(struct rtllib_device *ieee, - u8 *pos_ht_cap, u8 *len, - u8 isEncrypt, bool bAssoc); -void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee, - u8 *posRT2RTAgg, u8 *len); -void ht_on_assoc_rsp(struct rtllib_device *ieee); -void ht_initialize_ht_info(struct rtllib_device *ieee); -void ht_initialize_bss_desc(struct bss_ht *bss_ht); -void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee, - struct rtllib_network *pNetwork); -void HT_update_self_and_peer_setting(struct rtllib_device *ieee, - struct rtllib_network *pNetwork); -u8 ht_get_highest_mcs_rate(struct rtllib_device *ieee, u8 *pMCSRateSet, - u8 *pMCSFilter); -extern u8 MCS_FILTER_ALL[]; -extern u16 MCS_DATA_RATE[2][2][77]; -u8 ht_c_check(struct rtllib_device *ieee, u8 *pFrame); -void ht_reset_iot_setting(struct rt_hi_throughput *ht_info); -bool is_ht_half_nmode_aps(struct rtllib_device *ieee); -u16 tx_count_to_data_rate(struct rtllib_device *ieee, u8 nDataRate); -int rtllib_rx_add_ba_req(struct rtllib_device *ieee, struct sk_buff *skb); -int rtllib_rx_add_ba_rsp(struct rtllib_device *ieee, struct sk_buff *skb); -int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb); -void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts, - u8 policy, u8 overwrite_pending); -void rtllib_ts_init_del_ba(struct rtllib_device *ieee, - struct ts_common_info *ts_common_info, - enum tr_select tx_rx_select); -void rtllib_ba_setup_timeout(struct timer_list *t); -void rtllib_tx_ba_inact_timeout(struct timer_list *t); -void rtllib_rx_ba_inact_timeout(struct timer_list *t); -void rtllib_reset_ba_entry(struct ba_record *ba); -bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *addr, - u8 TID, enum tr_select tx_rx_select, bool bAddNewTs); -void rtllib_ts_init(struct rtllib_device *ieee); -void rtllib_ts_start_add_ba_process(struct rtllib_device *ieee, - struct tx_ts_record *pTxTS); -void remove_peer_ts(struct rtllib_device *ieee, u8 *addr); -void remove_all_ts(struct rtllib_device *ieee); - -static inline const char *escape_essid(const char *essid, u8 essid_len) -{ - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - - if (rtllib_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "", sizeof("")); - return escaped; - } - - snprintf(escaped, sizeof(escaped), "%*pE", essid_len, essid); - return escaped; -} - -/* fun with the built-in rtllib stack... */ -bool rtllib_mgnt_disconnect(struct rtllib_device *rtllib, u8 rsn); - -/* For the function is more related to hardware setting, it's better to use the - * ieee handler to refer to it. - */ -void rtllib_flush_rx_ts_pending_pkts(struct rtllib_device *ieee, - struct rx_ts_record *ts); -int rtllib_parse_info_param(struct rtllib_device *ieee, - struct rtllib_info_element *info_element, - u16 length, - struct rtllib_network *network, - struct rtllib_rx_stats *stats); - -void rtllib_indicate_packets(struct rtllib_device *ieee, - struct rtllib_rxb **prxb_indicate_array, u8 index); -#define RT_ASOC_RETRY_LIMIT 5 -u8 mgnt_query_tx_rate_exclude_cck_rates(struct rtllib_device *ieee); - -#endif /* RTLLIB_H */ diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c deleted file mode 100644 index 138733cb00e2..000000000000 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ /dev/null @@ -1,411 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rtllib.h" - -#include -#include - -#include - -#define AES_BLOCK_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - -struct rtllib_ccmp_data { - u8 key[CCMP_TK_LEN]; - int key_set; - - u8 tx_pn[CCMP_PN_LEN]; - u8 rx_pn[CCMP_PN_LEN]; - - u32 dot11rsna_stats_ccmp_format_errors; - u32 dot11rsna_stats_ccmp_replays; - u32 dot11rsna_stats_ccmp_decrypt_errors; - - int key_idx; - - struct crypto_aead *tfm; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_aad[2 * AES_BLOCK_LEN]; - u8 rx_aad[2 * AES_BLOCK_LEN]; -}; - -static void *rtllib_ccmp_init(int key_idx) -{ - struct rtllib_ccmp_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (!priv) - goto fail; - priv->key_idx = key_idx; - - priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tfm)) { - pr_debug("Could not allocate crypto API aes\n"); - priv->tfm = NULL; - goto fail; - } - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_aead(priv->tfm); - kfree(priv); - } - - return NULL; -} - -static void rtllib_ccmp_deinit(void *priv) -{ - struct rtllib_ccmp_data *_priv = priv; - - if (_priv && _priv->tfm) - crypto_free_aead(_priv->tfm); - kfree(priv); -} - -static int ccmp_init_iv_and_aad(struct ieee80211_hdr *hdr, - u8 *pn, u8 *iv, u8 *aad) -{ - u8 *pos, qc = 0; - size_t aad_len; - u16 fc; - int a4_included, qc_included; - - fc = le16_to_cpu(hdr->frame_control); - a4_included = ieee80211_has_a4(hdr->frame_control); - - qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) && - (WLAN_FC_GET_STYPE(fc) & 0x80)); - aad_len = 22; - if (a4_included) - aad_len += 6; - if (qc_included) { - pos = (u8 *)&hdr->addr4; - if (a4_included) - pos += 6; - qc = *pos & 0x0f; - aad_len += 2; - } - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC - * mode authentication are not allowed to collide, yet both are derived - * from the same vector. We only set L := 1 here to indicate that the - * data size can be represented in (L+1) bytes. The CCM layer will take - * care of storing the data length in the top (L+1) bytes and setting - * and clearing the other bits as is required to derive the two IVs. - */ - iv[0] = 0x1; - - /* Nonce: QC | A2 | PN */ - iv[1] = qc; - memcpy(iv + 2, hdr->addr2, ETH_ALEN); - memcpy(iv + 8, pn, CCMP_PN_LEN); - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - pos = (u8 *)hdr; - aad[0] = pos[0] & 0x8f; - aad[1] = pos[1] & 0xc7; - memcpy(&aad[2], &hdr->addr1, ETH_ALEN); - memcpy(&aad[8], &hdr->addr2, ETH_ALEN); - memcpy(&aad[14], &hdr->addr3, ETH_ALEN); - pos = (u8 *)&hdr->seq_ctrl; - aad[20] = pos[0] & 0x0f; - aad[21] = 0; /* all bits masked */ - memset(aad + 22, 0, 8); - if (a4_included) - memcpy(aad + 22, hdr->addr4, ETH_ALEN); - if (qc_included) { - aad[a4_included ? 28 : 22] = qc; - /* rest of QC masked */ - } - - return aad_len; -} - -static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct rtllib_ccmp_data *key = priv; - int i; - u8 *pos; - struct ieee80211_hdr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - if (skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < CCMP_MIC_LEN || - skb->len < hdr_len) - return -1; - - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdr_len); - pos += hdr_len; - - i = CCMP_PN_LEN - 1; - while (i >= 0) { - key->tx_pn[i]++; - if (key->tx_pn[i] != 0) - break; - i--; - } - - *pos++ = key->tx_pn[5]; - *pos++ = key->tx_pn[4]; - *pos++ = 0; - *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = key->tx_pn[3]; - *pos++ = key->tx_pn[2]; - *pos++ = key->tx_pn[1]; - *pos++ = key->tx_pn[0]; - - hdr = (struct ieee80211_hdr *)skb->data; - if (!tcb_desc->hw_sec) { - struct aead_request *req; - struct scatterlist sg[2]; - u8 *aad = key->tx_aad; - u8 iv[AES_BLOCK_LEN]; - int aad_len, ret; - int data_len = skb->len - hdr_len - CCMP_HDR_LEN; - - req = aead_request_alloc(key->tfm, GFP_ATOMIC); - if (!req) - return -ENOMEM; - - aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); - - skb_put(skb, CCMP_MIC_LEN); - sg_init_table(sg, 2); - sg_set_buf(&sg[0], aad, aad_len); - sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, - data_len + CCMP_MIC_LEN); - - aead_request_set_callback(req, 0, NULL, NULL); - aead_request_set_ad(req, aad_len); - aead_request_set_crypt(req, sg, sg, data_len, iv); - - ret = crypto_aead_encrypt(req); - aead_request_free(req); - - return ret; - } - - return 0; -} - -static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct rtllib_ccmp_data *key = priv; - u8 keyidx, *pos; - struct ieee80211_hdr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u8 pn[6]; - - if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { - key->dot11rsna_stats_ccmp_format_errors++; - return -1; - } - - hdr = (struct ieee80211_hdr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - pr_debug("CCMP: received packet without ExtIV flag from %pM\n", - hdr->addr2); - } - key->dot11rsna_stats_ccmp_format_errors++; - return -2; - } - keyidx >>= 6; - if (key->key_idx != keyidx) { - pr_debug("CCMP: RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", - key->key_idx, keyidx, priv); - return -6; - } - if (!key->key_set) { - if (net_ratelimit()) { - pr_debug("CCMP: received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); - } - return -3; - } - - pn[0] = pos[7]; - pn[1] = pos[6]; - pn[2] = pos[5]; - pn[3] = pos[4]; - pn[4] = pos[1]; - pn[5] = pos[0]; - pos += 8; - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - key->dot11rsna_stats_ccmp_replays++; - return -4; - } - if (!tcb_desc->hw_sec) { - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; - struct aead_request *req; - struct scatterlist sg[2]; - u8 *aad = key->rx_aad; - u8 iv[AES_BLOCK_LEN]; - int aad_len, ret; - - req = aead_request_alloc(key->tfm, GFP_ATOMIC); - if (!req) - return -ENOMEM; - - aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad); - - sg_init_table(sg, 2); - sg_set_buf(&sg[0], aad, aad_len); - sg_set_buf(&sg[1], pos, data_len); - - aead_request_set_callback(req, 0, NULL, NULL); - aead_request_set_ad(req, aad_len); - aead_request_set_crypt(req, sg, sg, data_len, iv); - - ret = crypto_aead_decrypt(req); - aead_request_free(req); - - if (ret) { - if (net_ratelimit()) { - pr_debug("CCMP: decrypt failed: STA= %pM\n", - hdr->addr2); - } - key->dot11rsna_stats_ccmp_decrypt_errors++; - return -5; - } - - memcpy(key->rx_pn, pn, CCMP_PN_LEN); - } - /* Remove hdr and MIC */ - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); - skb_pull(skb, CCMP_HDR_LEN); - skb_trim(skb, skb->len - CCMP_MIC_LEN); - - return keyidx; -} - -static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct rtllib_ccmp_data *data = priv; - int keyidx; - struct crypto_aead *tfm = data->tfm; - - keyidx = data->key_idx; - memset(data, 0, sizeof(*data)); - data->key_idx = keyidx; - data->tfm = tfm; - if (len == CCMP_TK_LEN) { - memcpy(data->key, key, CCMP_TK_LEN); - data->key_set = 1; - if (seq) { - data->rx_pn[0] = seq[5]; - data->rx_pn[1] = seq[4]; - data->rx_pn[2] = seq[3]; - data->rx_pn[3] = seq[2]; - data->rx_pn[4] = seq[1]; - data->rx_pn[5] = seq[0]; - } - if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) || - crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN)) - return -1; - } else if (len == 0) { - data->key_set = 0; - } else { - return -1; - } - - return 0; -} - -static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct rtllib_ccmp_data *data = priv; - - if (len < CCMP_TK_LEN) - return -1; - - if (!data->key_set) - return 0; - memcpy(key, data->key, CCMP_TK_LEN); - - if (seq) { - seq[0] = data->tx_pn[5]; - seq[1] = data->tx_pn[4]; - seq[2] = data->tx_pn[3]; - seq[3] = data->tx_pn[2]; - seq[4] = data->tx_pn[1]; - seq[5] = data->tx_pn[0]; - } - - return CCMP_TK_LEN; -} - -static void rtllib_ccmp_print_stats(struct seq_file *m, void *priv) -{ - struct rtllib_ccmp_data *ccmp = priv; - - seq_printf(m, - "key[%d] alg=CCMP key_set=%d tx_pn=%pM rx_pn=%pM format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - ccmp->tx_pn, ccmp->rx_pn, - ccmp->dot11rsna_stats_ccmp_format_errors, - ccmp->dot11rsna_stats_ccmp_replays, - ccmp->dot11rsna_stats_ccmp_decrypt_errors); -} - -static const struct lib80211_crypto_ops rtllib_crypt_ccmp = { - .name = "R-CCMP", - .init = rtllib_ccmp_init, - .deinit = rtllib_ccmp_deinit, - .encrypt_mpdu = rtllib_ccmp_encrypt, - .decrypt_mpdu = rtllib_ccmp_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = rtllib_ccmp_set_key, - .get_key = rtllib_ccmp_get_key, - .print_stats = rtllib_ccmp_print_stats, - .extra_mpdu_prefix_len = CCMP_HDR_LEN, - .extra_mpdu_postfix_len = CCMP_MIC_LEN, - .owner = THIS_MODULE, -}; - -static int __init rtllib_crypto_ccmp_init(void) -{ - return lib80211_register_crypto_ops(&rtllib_crypt_ccmp); -} - -static void __exit rtllib_crypto_ccmp_exit(void) -{ - lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp); -} - -module_init(rtllib_crypto_ccmp_init); -module_exit(rtllib_crypto_ccmp_exit); - -MODULE_DESCRIPTION("Support module for rtllib CCMP crypto"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c deleted file mode 100644 index 74dc8326c886..000000000000 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ /dev/null @@ -1,712 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtllib.h" - -struct rtllib_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - bool initialized; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - struct arc4_ctx rx_ctx_arc4; - struct arc4_ctx tx_ctx_arc4; - struct crypto_shash *rx_tfm_michael; - struct crypto_shash *tx_tfm_michael; - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16]; - u8 tx_hdr[16]; -}; - -static void *rtllib_tkip_init(int key_idx) -{ - struct rtllib_tkip_data *priv; - - if (fips_enabled) - return NULL; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (!priv) - goto fail; - priv->key_idx = key_idx; - - priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); - if (IS_ERR(priv->tx_tfm_michael)) { - pr_debug("Could not allocate crypto API michael_mic\n"); - priv->tx_tfm_michael = NULL; - goto fail; - } - - priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); - if (IS_ERR(priv->rx_tfm_michael)) { - pr_debug("Could not allocate crypto API michael_mic\n"); - priv->rx_tfm_michael = NULL; - goto fail; - } - return priv; - -fail: - if (priv) { - crypto_free_shash(priv->tx_tfm_michael); - crypto_free_shash(priv->rx_tfm_michael); - kfree(priv); - } - - return NULL; -} - -static void rtllib_tkip_deinit(void *priv) -{ - struct rtllib_tkip_data *_priv = priv; - - if (_priv) { - crypto_free_shash(_priv->tx_tfm_michael); - crypto_free_shash(_priv->rx_tfm_michael); - } - kfree_sensitive(priv); -} - -static inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - -static inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - -static inline u8 Hi8(u16 val) -{ - return val >> 8; -} - -static inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - -static inline u16 Hi16(u32 val) -{ - return val >> 16; -} - -static inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (hi << 8); -} - -static inline u16 Mk16_le(u16 *v) -{ - return *v; -} - -static const u16 Sbox[256] = { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - -static inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - -#define PHASE1_LOOP_COUNT 8 - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. - */ - u16 *PPK = (u16 *)&WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *)&TK[0])); - PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *)&TK[2])); - PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *)&TK[4])); - PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *)&TK[6])); - PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *)&TK[8])); - PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *)&TK[10])); - - PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *)&TK[12])); - PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *)&TK[14])); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV - */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *)&TK[0])) >> 1); - -#ifdef __BIG_ENDIAN - { - int i; - - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - -static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - int len; - u8 *pos; - struct ieee80211_hdr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - int ret = 0; - u8 rc4key[16], *icv; - u32 crc; - - if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - hdr = (struct ieee80211_hdr *)skb->data; - - if (!tcb_desc->hw_sec) { - if (!tkey->tx_phase1_done) { - tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); - tkey->tx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, - tkey->tx_iv16); - } else { - tkey->tx_phase1_done = 1; - } - - len = skb->len - hdr_len; - pos = skb_push(skb, 8); - memmove(pos, pos + 8, hdr_len); - pos += hdr_len; - - if (tcb_desc->hw_sec) { - *pos++ = Hi8(tkey->tx_iv16); - *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F; - *pos++ = Lo8(tkey->tx_iv16); - } else { - *pos++ = rc4key[0]; - *pos++ = rc4key[1]; - *pos++ = rc4key[2]; - } - - *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = tkey->tx_iv32 & 0xff; - *pos++ = (tkey->tx_iv32 >> 8) & 0xff; - *pos++ = (tkey->tx_iv32 >> 16) & 0xff; - *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - - if (!tcb_desc->hw_sec) { - icv = skb_put(skb, 4); - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16); - arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4); - } - - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - - if (!tcb_desc->hw_sec) - return ret; - return 0; -} - -static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - u8 keyidx, *pos; - u32 iv32; - u16 iv16; - struct ieee80211_hdr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u8 rc4key[16]; - u8 icv[4]; - u32 crc; - int plen; - - if (skb->len < hdr_len + 8 + 4) - return -1; - - hdr = (struct ieee80211_hdr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, - "Received packet without ExtIV flag from %pM\n", - hdr->addr2); - } - return -2; - } - keyidx >>= 6; - if (tkey->key_idx != keyidx) { - netdev_dbg(skb->dev, - "RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", - tkey->key_idx, keyidx, priv); - return -6; - } - if (!tkey->key_set) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, - "Received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); - } - return -3; - } - iv16 = (pos[0] << 8) | pos[2]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; - - if (!tcb_desc->hw_sec || (skb->cb[0] == 1)) { - if ((iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) && - tkey->initialized) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, - "Replay detected: STA= %pM previous TSC %08x%04x received TSC %08x%04x\n", - hdr->addr2, tkey->rx_iv32, - tkey->rx_iv16, iv32, iv16); - } - tkey->dot11RSNAStatsTKIPReplays++; - return -4; - } - tkey->initialized = true; - - if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, - hdr->addr2, iv32); - tkey->rx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); - - plen = skb->len - hdr_len - 12; - - arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16); - arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - if (memcmp(icv, pos + plen, 4) != 0) { - if (iv32 != tkey->rx_iv32) { - /* Previously cached Phase1 result was already - * lost, so it needs to be recalculated for the - * next packet. - */ - tkey->rx_phase1_done = 0; - } - if (net_ratelimit()) { - netdev_dbg(skb->dev, - "ICV error detected: STA= %pM\n", - hdr->addr2); - } - tkey->dot11RSNAStatsTKIPICVErrors++; - return -5; - } - } - - /* Update real counters only after Michael MIC verification has - * completed - */ - tkey->rx_iv32_new = iv32; - tkey->rx_iv16_new = iv16; - - /* Remove IV and ICV */ - memmove(skb->data + 8, skb->data, hdr_len); - skb_pull(skb, 8); - skb_trim(skb, skb->len - 4); - - return keyidx; -} - -static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr, - u8 *data, size_t data_len, u8 *mic) -{ - SHASH_DESC_ON_STACK(desc, tfm_michael); - int err; - - desc->tfm = tfm_michael; - - if (crypto_shash_setkey(tfm_michael, key, 8)) - return -1; - - err = crypto_shash_init(desc); - if (err) - goto out; - err = crypto_shash_update(desc, hdr, 16); - if (err) - goto out; - err = crypto_shash_update(desc, data, data_len); - if (err) - goto out; - err = crypto_shash_final(desc, mic); - -out: - shash_desc_zero(desc); - return err; -} - -static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) -{ - struct ieee80211_hdr *hdr11; - - hdr11 = (struct ieee80211_hdr *)skb->data; - switch (le16_to_cpu(hdr11->frame_control) & - (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_TODS: - ether_addr_copy(hdr, hdr11->addr3); /* DA */ - ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */ - break; - case IEEE80211_FCTL_FROMDS: - ether_addr_copy(hdr, hdr11->addr1); /* DA */ - ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */ - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - ether_addr_copy(hdr, hdr11->addr3); /* DA */ - ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */ - break; - case 0: - ether_addr_copy(hdr, hdr11->addr1); /* DA */ - ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */ - break; - } - - /* priority */ - hdr[12] = 0; - - /* reserved */ - hdr[13] = 0; - hdr[14] = 0; - hdr[15] = 0; -} - -static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - u8 *pos; - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)skb->data; - - if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - netdev_dbg(skb->dev, - "Invalid packet for Michael MIC add (tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); - return -1; - } - - michael_mic_hdr(skb, tkey->tx_hdr); - - if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control))) - tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - pos = skb_put(skb, 8); - if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) - return -1; - - return 0; -} - -static void rtllib_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - - /* TODO: needed parameters: count, keyid, key type, TSC */ - memset(&ev, 0, sizeof(ev)); - ev.flags = keyidx & IW_MICFAILURE_KEY_ID; - if (hdr->addr1[0] & 0x01) - ev.flags |= IW_MICFAILURE_GROUP; - else - ev.flags |= IW_MICFAILURE_PAIRWISE; - ev.src_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(ev.src_addr.sa_data, hdr->addr2); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); -} - -static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - u8 mic[8]; - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)skb->data; - - if (!tkey->key_set) - return -1; - - michael_mic_hdr(skb, tkey->rx_hdr); - if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control))) - tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - - if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)skb->data; - netdev_dbg(skb->dev, - "Michael MIC verification failed for MSDU from %pM keyidx=%d\n", - hdr->addr2, keyidx); - netdev_dbg(skb->dev, "%d\n", - memcmp(mic, skb->data + skb->len - 8, 8) != 0); - if (skb->dev) { - pr_info("skb->dev != NULL\n"); - rtllib_michael_mic_failure(skb->dev, hdr, keyidx); - } - tkey->dot11RSNAStatsTKIPLocalMICFailures++; - return -1; - } - - /* Update TSC counters for RX now that the packet verification has - * completed. - */ - tkey->rx_iv32 = tkey->rx_iv32_new; - tkey->rx_iv16 = tkey->rx_iv16_new; - - skb_trim(skb, skb->len - 8); - - return 0; -} - -static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - int keyidx; - struct crypto_shash *tfm = tkey->tx_tfm_michael; - struct crypto_shash *tfm3 = tkey->rx_tfm_michael; - - keyidx = tkey->key_idx; - memset(tkey, 0, sizeof(*tkey)); - tkey->key_idx = keyidx; - tkey->tx_tfm_michael = tfm; - tkey->rx_tfm_michael = tfm3; - - if (len == TKIP_KEY_LEN) { - memcpy(tkey->key, key, TKIP_KEY_LEN); - tkey->key_set = 1; - tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ - if (seq) { - tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | - (seq[3] << 8) | seq[2]; - tkey->rx_iv16 = (seq[1] << 8) | seq[0]; - } - } else if (len == 0) { - tkey->key_set = 0; - } else { - return -1; - } - - return 0; -} - -static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct rtllib_tkip_data *tkey = priv; - - if (len < TKIP_KEY_LEN) - return -1; - - if (!tkey->key_set) - return 0; - memcpy(key, tkey->key, TKIP_KEY_LEN); - - if (seq) { - /* Return the sequence number of the last transmitted frame. */ - u16 iv16 = tkey->tx_iv16; - u32 iv32 = tkey->tx_iv32; - - if (iv16 == 0) - iv32--; - iv16--; - seq[0] = tkey->tx_iv16; - seq[1] = tkey->tx_iv16 >> 8; - seq[2] = tkey->tx_iv32; - seq[3] = tkey->tx_iv32 >> 8; - seq[4] = tkey->tx_iv32 >> 16; - seq[5] = tkey->tx_iv32 >> 24; - } - - return TKIP_KEY_LEN; -} - -static void rtllib_tkip_print_stats(struct seq_file *m, void *priv) -{ - struct rtllib_tkip_data *tkip = priv; - - seq_printf(m, - "key[%d] alg=TKIP key_set=%d tx_pn=%02x%02x%02x%02x%02x%02x rx_pn=%02x%02x%02x%02x%02x%02x replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); -} - -static const struct lib80211_crypto_ops rtllib_crypt_tkip = { - .name = "R-TKIP", - .init = rtllib_tkip_init, - .deinit = rtllib_tkip_deinit, - .encrypt_mpdu = rtllib_tkip_encrypt, - .decrypt_mpdu = rtllib_tkip_decrypt, - .encrypt_msdu = rtllib_michael_mic_add, - .decrypt_msdu = rtllib_michael_mic_verify, - .set_key = rtllib_tkip_set_key, - .get_key = rtllib_tkip_get_key, - .print_stats = rtllib_tkip_print_stats, - .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */ - .extra_mpdu_postfix_len = 4, /* ICV */ - .extra_msdu_postfix_len = 8, /* MIC */ - .owner = THIS_MODULE, -}; - -static int __init rtllib_crypto_tkip_init(void) -{ - return lib80211_register_crypto_ops(&rtllib_crypt_tkip); -} - -static void __exit rtllib_crypto_tkip_exit(void) -{ - lib80211_unregister_crypto_ops(&rtllib_crypt_tkip); -} - -module_init(rtllib_crypto_tkip_init); -module_exit(rtllib_crypto_tkip_exit); - -MODULE_DESCRIPTION("Support module for rtllib TKIP crypto"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c deleted file mode 100644 index aa18c060d727..000000000000 --- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c +++ /dev/null @@ -1,242 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypt: host-based WEP encryption implementation for Host AP driver - * - * Copyright (c) 2002-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "rtllib.h" - -#include - -struct prism2_wep_data { - u32 iv; -#define WEP_KEY_LEN 13 - u8 key[WEP_KEY_LEN + 1]; - u8 key_len; - u8 key_idx; - struct arc4_ctx rx_ctx_arc4; - struct arc4_ctx tx_ctx_arc4; -}; - -static void *prism2_wep_init(int keyidx) -{ - struct prism2_wep_data *priv; - - if (fips_enabled) - return NULL; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (!priv) - return NULL; - priv->key_idx = keyidx; - - /* start WEP IV from a random value */ - get_random_bytes(&priv->iv, 4); - - return priv; -} - -static void prism2_wep_deinit(void *priv) -{ - kfree_sensitive(priv); -} - -/* Perform WEP encryption on given skb that has at least 4 bytes of headroom - * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, - * so the payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 klen, len; - u8 key[WEP_KEY_LEN + 3]; - u8 *pos; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u32 crc; - u8 *icv; - - if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len){ - pr_err("Error!!! headroom=%d tailroom=%d skblen=%d hdr_len=%d\n", - skb_headroom(skb), skb_tailroom(skb), skb->len, hdr_len); - return -1; - } - len = skb->len - hdr_len; - pos = skb_push(skb, 4); - memmove(pos, pos + 4, hdr_len); - pos += hdr_len; - - klen = 3 + wep->key_len; - - wep->iv++; - - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key - * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. - */ - if ((wep->iv & 0xff00) == 0xff00) { - u8 B = (wep->iv >> 16) & 0xff; - - if (B >= 3 && B < klen) - wep->iv += 0x0100; - } - - /* Prepend 24-bit IV to RC4 key and TX frame */ - *pos++ = key[0] = (wep->iv >> 16) & 0xff; - *pos++ = key[1] = (wep->iv >> 8) & 0xff; - *pos++ = key[2] = wep->iv & 0xff; - *pos++ = wep->key_idx << 6; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - if (!tcb_desc->hw_sec) { - /* Append little-endian CRC32 and encrypt it to produce ICV */ - crc = ~crc32_le(~0, pos, len); - icv = skb_put(skb, 4); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - arc4_setkey(&wep->tx_ctx_arc4, key, klen); - arc4_crypt(&wep->tx_ctx_arc4, pos, pos, len + 4); - } - - return 0; -} - -/* Perform WEP decryption on given struct buffer. Buffer includes whole WEP - * part of the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). len includes both IV and ICV. - * - * 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 prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 klen, plen; - u8 key[WEP_KEY_LEN + 3]; - u8 keyidx, *pos; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + - MAX_DEV_ADDR_SIZE); - u32 crc; - u8 icv[4]; - - if (skb->len < hdr_len + 8) - return -1; - - pos = skb->data + hdr_len; - key[0] = *pos++; - key[1] = *pos++; - key[2] = *pos++; - keyidx = *pos++ >> 6; - if (keyidx != wep->key_idx) - return -1; - - klen = 3 + wep->key_len; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - plen = skb->len - hdr_len - 8; - - if (!tcb_desc->hw_sec) { - arc4_setkey(&wep->rx_ctx_arc4, key, klen); - arc4_crypt(&wep->rx_ctx_arc4, pos, pos, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - /* ICV mismatch - drop frame */ - return -2; - } - } - /* Remove IV and ICV */ - memmove(skb->data + 4, skb->data, hdr_len); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - - return 0; -} - -static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < 0 || len > WEP_KEY_LEN) - return -1; - - memcpy(wep->key, key, len); - wep->key_len = len; - - return 0; -} - -static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < wep->key_len) - return -1; - - memcpy(key, wep->key, wep->key_len); - - return wep->key_len; -} - -static void prism2_wep_print_stats(struct seq_file *m, void *priv) -{ - struct prism2_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 rtllib_crypt_wep = { - .name = "R-WEP", - .init = prism2_wep_init, - .deinit = prism2_wep_deinit, - .encrypt_mpdu = prism2_wep_encrypt, - .decrypt_mpdu = prism2_wep_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = prism2_wep_set_key, - .get_key = prism2_wep_get_key, - .print_stats = prism2_wep_print_stats, - .extra_mpdu_prefix_len = 4, /* IV */ - .extra_mpdu_postfix_len = 4, /* ICV */ - .owner = THIS_MODULE, -}; - -static int __init rtllib_crypto_wep_init(void) -{ - return lib80211_register_crypto_ops(&rtllib_crypt_wep); -} - -static void __exit rtllib_crypto_wep_exit(void) -{ - lib80211_unregister_crypto_ops(&rtllib_crypt_wep); -} - -module_init(rtllib_crypto_wep_init); -module_exit(rtllib_crypto_wep_exit); - -MODULE_DESCRIPTION("Support module for rtllib WEP crypto"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c deleted file mode 100644 index 469a69726c16..000000000000 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2004 Intel Corporation. All rights reserved. - * - * Portions of this file are based on the WEP enablement code provided by the - * Host AP project hostap-drivers v0.1.3 - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rtllib.h" - -static inline int rtllib_networks_allocate(struct rtllib_device *ieee) -{ - if (ieee->networks) - return 0; - - ieee->networks = kcalloc(MAX_NETWORK_COUNT, - sizeof(struct rtllib_network), GFP_KERNEL); - if (!ieee->networks) - return -ENOMEM; - - return 0; -} - -static inline void rtllib_networks_free(struct rtllib_device *ieee) -{ - if (!ieee->networks) - return; - kfree(ieee->networks); - ieee->networks = NULL; -} - -static inline void rtllib_networks_initialize(struct rtllib_device *ieee) -{ - int i; - - INIT_LIST_HEAD(&ieee->network_free_list); - INIT_LIST_HEAD(&ieee->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, - &ieee->network_free_list); -} - -struct net_device *alloc_rtllib(int sizeof_priv) -{ - struct rtllib_device *ieee = NULL; - struct net_device *dev; - int i, err; - - pr_debug("rtllib: Initializing...\n"); - - dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv); - if (!dev) { - pr_err("Unable to allocate net_device.\n"); - return NULL; - } - ieee = (struct rtllib_device *)netdev_priv_rsl(dev); - ieee->dev = dev; - - err = rtllib_networks_allocate(ieee); - if (err) { - pr_err("Unable to allocate beacon storage: %d\n", err); - goto free_netdev; - } - rtllib_networks_initialize(ieee); - - /* Default fragmentation threshold is maximum payload size */ - ieee->fts = DEFAULT_FTS; - ieee->scan_age = DEFAULT_MAX_SCAN_AGE; - ieee->open_wep = 1; - - ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ - - ieee->rtllib_ap_sec_type = rtllib_ap_sec_type; - - spin_lock_init(&ieee->lock); - spin_lock_init(&ieee->wpax_suitlist_lock); - spin_lock_init(&ieee->reorder_spinlock); - atomic_set(&ieee->atm_swbw, 0); - - /* SAM FIXME */ - lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock); - - ieee->wpa_enabled = 0; - ieee->tkip_countermeasures = 0; - ieee->drop_unencrypted = 0; - ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; - ieee->hwsec_active = 0; - - memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32); - err = rtllib_softmac_init(ieee); - if (err) - goto free_crypt_info; - - ieee->ht_info = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); - if (!ieee->ht_info) - goto free_softmac; - - ht_update_default_setting(ieee); - ht_initialize_ht_info(ieee); - rtllib_ts_init(ieee); - for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) - INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - return dev; - -free_softmac: - rtllib_softmac_free(ieee); -free_crypt_info: - lib80211_crypt_info_free(&ieee->crypt_info); - rtllib_networks_free(ieee); -free_netdev: - free_netdev(dev); - - return NULL; -} -EXPORT_SYMBOL(alloc_rtllib); - -void free_rtllib(struct net_device *dev) -{ - struct rtllib_device *ieee = (struct rtllib_device *) - netdev_priv_rsl(dev); - - kfree(ieee->ht_info); - rtllib_softmac_free(ieee); - - lib80211_crypt_info_free(&ieee->crypt_info); - - rtllib_networks_free(ieee); - free_netdev(dev); -} -EXPORT_SYMBOL(free_rtllib); - -static int __init rtllib_init(void) -{ - return 0; -} - -static void __exit rtllib_exit(void) -{ -} - -module_init(rtllib_init); -module_exit(rtllib_exit); - -MODULE_DESCRIPTION("Support module for rtllib wireless devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c deleted file mode 100644 index 84ca5d769b7e..000000000000 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ /dev/null @@ -1,2564 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Original code based Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3 - hostap.o module, common routines - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * Copyright (c) 2004, Intel Corporation - * - * Few modifications for Realtek's Wi-Fi drivers by - * Andrea Merello - * - * A special thanks goes to Realtek for their support ! - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtllib.h" - -static void rtllib_rx_mgt(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *stats); - -static inline void rtllib_monitor_rx(struct rtllib_device *ieee, - struct sk_buff *skb, - struct rtllib_rx_stats *rx_status, - size_t hdr_length) -{ - skb->dev = ieee->dev; - skb_reset_mac_header(skb); - skb_pull(skb, hdr_length); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_80211_RAW); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - -/* Called only as a tasklet (software IRQ) */ -static struct rtllib_frag_entry * -rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, - unsigned int frag, u8 tid, u8 *src, u8 *dst) -{ - struct rtllib_frag_entry *entry; - int i; - - for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) { - entry = &ieee->frag_cache[tid][i]; - if (entry->skb && - time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - netdev_dbg(ieee->dev, - "expiring fragment cache entry seq=%u last_frag=%u\n", - entry->seq, entry->last_frag); - dev_kfree_skb_any(entry->skb); - entry->skb = NULL; - } - - if (entry->skb && entry->seq == seq && - (entry->last_frag + 1 == frag || frag == -1) && - memcmp(entry->src_addr, src, ETH_ALEN) == 0 && - memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) - return entry; - } - - return NULL; -} - -/* Called only as a tasklet (software IRQ) */ -static struct sk_buff * -rtllib_frag_cache_get(struct rtllib_device *ieee, - struct ieee80211_hdr *hdr) -{ - struct sk_buff *skb = NULL; - u16 fc = le16_to_cpu(hdr->frame_control); - u16 sc = le16_to_cpu(hdr->seq_ctrl); - unsigned int frag = WLAN_GET_SEQ_FRAG(sc); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct rtllib_frag_entry *entry; - struct ieee80211_qos_hdr *hdr_3addrqos; - struct ieee80211_qos_hdr_4addr *hdr_4addrqos; - u8 tid; - - if (ieee80211_has_a4(hdr->frame_control) && - RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - if (frag == 0) { - /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct ieee80211_hdr) + - 8 /* LLC */ + - 2 /* alignment */ + - 8 /* WEP */ + - ETH_ALEN /* WDS */ + - /* QOS Control */ - (RTLLIB_QOS_HAS_SEQ(fc) ? 2 : 0)); - if (!skb) - return NULL; - - entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; - ieee->frag_next_idx[tid]++; - if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN) - ieee->frag_next_idx[tid] = 0; - - if (entry->skb) - dev_kfree_skb_any(entry->skb); - - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->last_frag = frag; - entry->skb = skb; - ether_addr_copy(entry->src_addr, hdr->addr2); - ether_addr_copy(entry->dst_addr, hdr->addr1); - } else { - /* received a fragment of a frame for which the head fragment - * should have already been received - */ - entry = rtllib_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, - hdr->addr1); - if (entry) { - entry->last_frag = frag; - skb = entry->skb; - } - } - - return skb; -} - -/* Called only as a tasklet (software IRQ) */ -static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, - struct ieee80211_hdr *hdr) -{ - u16 fc = le16_to_cpu(hdr->frame_control); - u16 sc = le16_to_cpu(hdr->seq_ctrl); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct rtllib_frag_entry *entry; - struct ieee80211_qos_hdr *hdr_3addrqos; - struct ieee80211_qos_hdr_4addr *hdr_4addrqos; - u8 tid; - - if (ieee80211_has_a4(hdr->frame_control) && - RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - entry = rtllib_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, - hdr->addr1); - - if (!entry) { - netdev_dbg(ieee->dev, - "Couldn't invalidate fragment cache entry (seq=%u)\n", - seq); - return -1; - } - - entry->skb = NULL; - return 0; -} - -/* rtllib_rx_frame_mgtmt - * - * Responsible for handling management control frames - * - * Called by rtllib_rx - */ -static inline int -rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats, u16 type, u16 stype) -{ - /* On the struct stats definition there is written that - * this is not mandatory.... but seems that the probe - * response parser uses it - */ - struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data; - - rx_stats->len = skb->len; - rtllib_rx_mgt(ieee, skb, rx_stats); - if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) { - dev_kfree_skb_any(skb); - return 0; - } - rtllib_rx_frame_softmac(ieee, skb, rx_stats, type, stype); - - dev_kfree_skb_any(skb); - - return 0; -} - -/* No encapsulation header if EtherType < 0x600 (=length) */ - -/* Called by rtllib_rx_frame_decrypt */ -static int rtllib_is_eapol_frame(struct rtllib_device *ieee, - struct sk_buff *skb, size_t hdrlen) -{ - struct net_device *dev = ieee->dev; - u16 fc, ethertype; - struct ieee80211_hdr *hdr; - u8 *pos; - - if (skb->len < 24) - return 0; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = le16_to_cpu(hdr->frame_control); - - /* check that the frame is unicast frame to us */ - if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_TODS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - /* FromDS frame with own addr as DA */ - } else { - return 0; - } - - if (skb->len < 24 + 8) - return 0; - - /* check for port access entity Ethernet type */ - pos = skb->data + hdrlen; - ethertype = (pos[6] << 8) | pos[7]; - if (ethertype == ETH_P_PAE) - return 1; - - return 0; -} - -/* Called only as a tasklet (software IRQ), by rtllib_rx */ -static inline int -rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, - struct lib80211_crypt_data *crypt) -{ - struct ieee80211_hdr *hdr; - int res, hdrlen; - - if (!crypt || !crypt->ops->decrypt_mpdu) - return 0; - - if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *) - (skb->cb + MAX_DEV_ADDR_SIZE); - - tcb_desc->hw_sec = 1; - - if (ieee->need_sw_enc) - tcb_desc->hw_sec = 0; - } - - hdr = (struct ieee80211_hdr *)skb->data; - hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_dbg(ieee->dev, "decryption failed (SA= %pM) res=%d\n", - hdr->addr2, res); - if (res == -2) - netdev_dbg(ieee->dev, - "Decryption failed ICV mismatch (key %d)\n", - skb->data[hdrlen + 3] >> 6); - return -1; - } - - return res; -} - -/* Called only as a tasklet (software IRQ), by rtllib_rx */ -static inline int -rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, - int keyidx, struct lib80211_crypt_data *crypt) -{ - struct ieee80211_hdr *hdr; - int res, hdrlen; - - if (!crypt || !crypt->ops->decrypt_msdu) - return 0; - if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *) - (skb->cb + MAX_DEV_ADDR_SIZE); - - tcb_desc->hw_sec = 1; - - if (ieee->need_sw_enc) - tcb_desc->hw_sec = 0; - } - - hdr = (struct ieee80211_hdr *)skb->data; - hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_dbg(ieee->dev, - "MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n", - hdr->addr2, keyidx); - return -1; - } - - return 0; -} - -/* this function is stolen from ipw2200 driver*/ -#define IEEE_PACKET_RETRY_TIME (5 * HZ) -static int is_duplicate_packet(struct rtllib_device *ieee, - struct ieee80211_hdr *header) -{ - u16 fc = le16_to_cpu(header->frame_control); - u16 sc = le16_to_cpu(header->seq_ctrl); - u16 seq = WLAN_GET_SEQ_SEQ(sc); - u16 frag = WLAN_GET_SEQ_FRAG(sc); - u16 *last_seq, *last_frag; - unsigned long *last_time; - struct ieee80211_qos_hdr *hdr_3addrqos; - struct ieee80211_qos_hdr_4addr *hdr_4addrqos; - u8 tid; - - if (ieee80211_has_a4(header->frame_control) && - RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_qos_hdr *)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - switch (ieee->iw_mode) { - case IW_MODE_INFRA: - last_seq = &ieee->last_rxseq_num[tid]; - last_frag = &ieee->last_rxfrag_num[tid]; - last_time = &ieee->last_packet_time[tid]; - break; - default: - return 0; - } - - if ((*last_seq == seq) && - time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { - if (*last_frag == frag) - goto drop; - if (*last_frag + 1 != frag) - /* out-of-order fragment */ - goto drop; - } else { - *last_seq = seq; - } - - *last_frag = frag; - *last_time = jiffies; - return 0; - -drop: - - return 1; -} - -static bool add_reorder_entry(struct rx_ts_record *ts, - struct rx_reorder_entry *pReorderEntry) -{ - struct list_head *list = &ts->rx_pending_pkt_list; - - while (list->next != &ts->rx_pending_pkt_list) { - if (SN_LESS(pReorderEntry->SeqNum, ((struct rx_reorder_entry *) - list_entry(list->next, struct rx_reorder_entry, - list))->SeqNum)) - list = list->next; - else if (SN_EQUAL(pReorderEntry->SeqNum, - ((struct rx_reorder_entry *)list_entry(list->next, - struct rx_reorder_entry, list))->SeqNum)) - return false; - else - break; - } - pReorderEntry->list.next = list->next; - pReorderEntry->list.next->prev = &pReorderEntry->list; - pReorderEntry->list.prev = list; - list->next = &pReorderEntry->list; - - return true; -} - -void rtllib_indicate_packets(struct rtllib_device *ieee, - struct rtllib_rxb **prxb_indicate_array, u8 index) -{ - struct net_device_stats *stats = &ieee->stats; - u8 i = 0, j = 0; - u16 ethertype; - - for (j = 0; j < index; j++) { - struct rtllib_rxb *prxb = prxb_indicate_array[j]; - - for (i = 0; i < prxb->nr_subframes; i++) { - struct sk_buff *sub_skb = prxb->subframes[i]; - - /* convert hdr + possible LLC headers into Ethernet header */ - ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((memcmp(sub_skb->data, rfc1042_header, - SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && - ethertype != ETH_P_IPX) || - memcmp(sub_skb->data, bridge_tunnel_header, - SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation - * and replace EtherType - */ - skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); - } else { - u16 len; - /* Leave Ethernet header part of hdr and full payload */ - len = sub_skb->len; - memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); - } - - /* Indicate the packets to upper layer */ - if (sub_skb) { - stats->rx_packets++; - stats->rx_bytes += sub_skb->len; - - memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->protocol = eth_type_trans(sub_skb, - ieee->dev); - sub_skb->dev = ieee->dev; - sub_skb->dev->stats.rx_packets++; - sub_skb->dev->stats.rx_bytes += sub_skb->len; - /* 802.11 crc not sufficient */ - sub_skb->ip_summed = CHECKSUM_NONE; - ieee->last_rx_ps_time = jiffies; - netif_rx(sub_skb); - } - } - kfree(prxb); - prxb = NULL; - } -} - -void rtllib_flush_rx_ts_pending_pkts(struct rtllib_device *ieee, - struct rx_ts_record *ts) -{ - struct rx_reorder_entry *pRxReorderEntry; - u8 rfd_cnt = 0; - - del_timer_sync(&ts->rx_pkt_pending_timer); - while (!list_empty(&ts->rx_pending_pkt_list)) { - if (rfd_cnt >= REORDER_WIN_SIZE) { - netdev_info(ieee->dev, - "-------------->%s() error! rfd_cnt >= REORDER_WIN_SIZE\n", - __func__); - break; - } - - pRxReorderEntry = (struct rx_reorder_entry *) - list_entry(ts->rx_pending_pkt_list.prev, - struct rx_reorder_entry, list); - netdev_dbg(ieee->dev, "%s(): Indicate SeqNum %d!\n", __func__, - pRxReorderEntry->SeqNum); - list_del_init(&pRxReorderEntry->list); - - ieee->rfd_array[rfd_cnt] = pRxReorderEntry->prxb; - - rfd_cnt = rfd_cnt + 1; - list_add_tail(&pRxReorderEntry->list, - &ieee->RxReorder_Unused_List); - } - rtllib_indicate_packets(ieee, ieee->rfd_array, rfd_cnt); - - ts->rx_indicate_seq = 0xffff; -} - -static void rx_reorder_indicate_packet(struct rtllib_device *ieee, - struct rtllib_rxb *prxb, - struct rx_ts_record *ts, u16 SeqNum) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - struct rx_reorder_entry *pReorderEntry = NULL; - u8 win_size = ht_info->rx_reorder_win_size; - u16 win_end = 0; - u8 index = 0; - bool match_win_start = false, pkt_in_buf = false; - unsigned long flags; - - netdev_dbg(ieee->dev, - "%s(): Seq is %d, ts->rx_indicate_seq is %d, win_size is %d\n", - __func__, SeqNum, ts->rx_indicate_seq, win_size); - - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - - win_end = (ts->rx_indicate_seq + win_size - 1) % 4096; - /* Rx Reorder initialize condition.*/ - if (ts->rx_indicate_seq == 0xffff) - ts->rx_indicate_seq = SeqNum; - - /* Drop out the packet which SeqNum is smaller than WinStart */ - if (SN_LESS(SeqNum, ts->rx_indicate_seq)) { - netdev_dbg(ieee->dev, - "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", - ts->rx_indicate_seq, SeqNum); - ht_info->rx_reorder_drop_counter++; - { - int i; - - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - kfree(prxb); - prxb = NULL; - } - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - return; - } - - /* Sliding window manipulation. Conditions includes: - * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 - * 2. Incoming SeqNum is larger than the win_end => Window shift N - */ - if (SN_EQUAL(SeqNum, ts->rx_indicate_seq)) { - ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) % 4096; - match_win_start = true; - } else if (SN_LESS(win_end, SeqNum)) { - if (SeqNum >= (win_size - 1)) - ts->rx_indicate_seq = SeqNum + 1 - win_size; - else - ts->rx_indicate_seq = 4095 - - (win_size - (SeqNum + 1)) + 1; - netdev_dbg(ieee->dev, - "Window Shift! IndicateSeq: %d, NewSeq: %d\n", - ts->rx_indicate_seq, SeqNum); - } - - /* Indication process. - * After Packet dropping and Sliding Window shifting as above, we can - * now just indicate the packets with the SeqNum smaller than latest - * WinStart and struct buffer other packets. - * - * For Rx Reorder condition: - * 1. All packets with SeqNum smaller than WinStart => Indicate - * 2. All packets with SeqNum larger than or equal to - * WinStart => Buffer it. - */ - if (match_win_start) { - /* Current packet is going to be indicated.*/ - netdev_dbg(ieee->dev, - "Packets indication! IndicateSeq: %d, NewSeq: %d\n", - ts->rx_indicate_seq, SeqNum); - ieee->prxb_indicate_array[0] = prxb; - index = 1; - } else { - /* Current packet is going to be inserted into pending list.*/ - if (!list_empty(&ieee->RxReorder_Unused_List)) { - pReorderEntry = (struct rx_reorder_entry *) - list_entry(ieee->RxReorder_Unused_List.next, - struct rx_reorder_entry, list); - list_del_init(&pReorderEntry->list); - - /* Make a reorder entry and insert - * into a the packet list. - */ - pReorderEntry->SeqNum = SeqNum; - pReorderEntry->prxb = prxb; - - if (!add_reorder_entry(ts, pReorderEntry)) { - int i; - - netdev_dbg(ieee->dev, - "%s(): Duplicate packet is dropped. IndicateSeq: %d, NewSeq: %d\n", - __func__, ts->rx_indicate_seq, - SeqNum); - list_add_tail(&pReorderEntry->list, - &ieee->RxReorder_Unused_List); - - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - kfree(prxb); - prxb = NULL; - } else { - netdev_dbg(ieee->dev, - "Pkt insert into struct buffer. IndicateSeq: %d, NewSeq: %d\n", - ts->rx_indicate_seq, SeqNum); - } - } else { - /* Packets are dropped if there are not enough reorder - * entries. This part should be modified!! We can just - * indicate all the packets in struct buffer and get - * reorder entries. - */ - netdev_err(ieee->dev, - "%s(): There is no reorder entry! Packet is dropped!\n", - __func__); - { - int i; - - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - kfree(prxb); - prxb = NULL; - } - } - } - - /* Check if there is any packet need indicate.*/ - while (!list_empty(&ts->rx_pending_pkt_list)) { - netdev_dbg(ieee->dev, "%s(): start RREORDER indicate\n", - __func__); - - pReorderEntry = (struct rx_reorder_entry *) - list_entry(ts->rx_pending_pkt_list.prev, - struct rx_reorder_entry, - list); - if (SN_LESS(pReorderEntry->SeqNum, ts->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, ts->rx_indicate_seq)) { - /* This protect struct buffer from overflow. */ - if (index >= REORDER_WIN_SIZE) { - netdev_err(ieee->dev, - "%s(): Buffer overflow!\n", - __func__); - pkt_in_buf = true; - break; - } - - list_del_init(&pReorderEntry->list); - - if (SN_EQUAL(pReorderEntry->SeqNum, ts->rx_indicate_seq)) - ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) % - 4096; - - ieee->prxb_indicate_array[index] = pReorderEntry->prxb; - netdev_dbg(ieee->dev, "%s(): Indicate SeqNum %d!\n", - __func__, pReorderEntry->SeqNum); - index++; - - list_add_tail(&pReorderEntry->list, - &ieee->RxReorder_Unused_List); - } else { - pkt_in_buf = true; - break; - } - } - - /* Handling pending timer. Set this timer to prevent from long time - * Rx buffering. - */ - if (index > 0) { - spin_unlock_irqrestore(&ieee->reorder_spinlock, flags); - if (timer_pending(&ts->rx_pkt_pending_timer)) - del_timer_sync(&ts->rx_pkt_pending_timer); - spin_lock_irqsave(&ieee->reorder_spinlock, flags); - ts->rx_timeout_indicate_seq = 0xffff; - - if (index > REORDER_WIN_SIZE) { - netdev_err(ieee->dev, - "%s(): Rx Reorder struct buffer full!\n", - __func__); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), - flags); - return; - } - rtllib_indicate_packets(ieee, ieee->prxb_indicate_array, index); - pkt_in_buf = false; - } - - if (pkt_in_buf && ts->rx_timeout_indicate_seq == 0xffff) { - netdev_dbg(ieee->dev, "%s(): SET rx timeout timer\n", __func__); - ts->rx_timeout_indicate_seq = ts->rx_indicate_seq; - spin_unlock_irqrestore(&ieee->reorder_spinlock, flags); - mod_timer(&ts->rx_pkt_pending_timer, jiffies + - msecs_to_jiffies(ht_info->rx_reorder_pending_time)); - spin_lock_irqsave(&ieee->reorder_spinlock, flags); - } - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); -} - -static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats, - struct rtllib_rxb *rxb, u8 *src, u8 *dst) -{ - struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_control); - - u16 llc_offset = sizeof(struct ieee80211_hdr_3addr); - bool is_aggregate_frame = false; - u16 nSubframe_Length; - u8 pad_len = 0; - u16 SeqNum = 0; - struct sk_buff *sub_skb; - /* just for debug purpose */ - SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctrl)); - if ((RTLLIB_QOS_HAS_SEQ(fc)) && - (((union frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved)) - is_aggregate_frame = true; - - if (RTLLIB_QOS_HAS_SEQ(fc)) - llc_offset += 2; - if (rx_stats->contain_htc) - llc_offset += sHTCLng; - - if (skb->len <= llc_offset) - return 0; - - skb_pull(skb, llc_offset); - ieee->is_aggregate_frame = is_aggregate_frame; - if (!is_aggregate_frame) { - rxb->nr_subframes = 1; - - /* altered by clark 3/30/2010 - * The struct buffer size of the skb indicated to upper layer - * must be less than 5000, or the defraged IP datagram - * in the IP layer will exceed "ipfrag_high_tresh" and be - * discarded. so there must not use the function - * "skb_copy" and "skb_clone" for "skb". - */ - - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(RTLLIB_SKBBUFFER_SIZE); - if (!sub_skb) - return 0; - skb_reserve(sub_skb, 12); - skb_put_data(sub_skb, skb->data, skb->len); - sub_skb->dev = ieee->dev; - - rxb->subframes[0] = sub_skb; - - memcpy(rxb->src, src, ETH_ALEN); - memcpy(rxb->dst, dst, ETH_ALEN); - rxb->subframes[0]->dev = ieee->dev; - return 1; - } - - rxb->nr_subframes = 0; - memcpy(rxb->src, src, ETH_ALEN); - memcpy(rxb->dst, dst, ETH_ALEN); - while (skb->len > ETHERNET_HEADER_SIZE) { - /* Offset 12 denote 2 mac address */ - nSubframe_Length = *((u16 *)(skb->data + 12)); - nSubframe_Length = (nSubframe_Length >> 8) + - (nSubframe_Length << 8); - - if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { - netdev_info(ieee->dev, - "%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n", - __func__, rxb->nr_subframes); - netdev_info(ieee->dev, - "%s: A-MSDU parse error!! Subframe Length: %d\n", - __func__, nSubframe_Length); - netdev_info(ieee->dev, - "nRemain_Length is %d and nSubframe_Length is : %d\n", - skb->len, nSubframe_Length); - netdev_info(ieee->dev, - "The Packet SeqNum is %d\n", - SeqNum); - return 0; - } - - /* move the data point to data content */ - skb_pull(skb, ETHERNET_HEADER_SIZE); - - /* altered by clark 3/30/2010 - * The struct buffer size of the skb indicated to upper layer - * must be less than 5000, or the defraged IP datagram - * in the IP layer will exceed "ipfrag_high_tresh" and be - * discarded. so there must not use the function - * "skb_copy" and "skb_clone" for "skb". - */ - - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(nSubframe_Length + 12); - if (!sub_skb) - return 0; - skb_reserve(sub_skb, 12); - skb_put_data(sub_skb, skb->data, nSubframe_Length); - - sub_skb->dev = ieee->dev; - rxb->subframes[rxb->nr_subframes++] = sub_skb; - if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { - netdev_dbg(ieee->dev, - "ParseSubframe(): Too many Subframes! Packets dropped!\n"); - break; - } - skb_pull(skb, nSubframe_Length); - - if (skb->len != 0) { - pad_len = 4 - ((nSubframe_Length + - ETHERNET_HEADER_SIZE) % 4); - if (pad_len == 4) - pad_len = 0; - - if (skb->len < pad_len) - return 0; - - skb_pull(skb, pad_len); - } - } - - return rxb->nr_subframes; -} - -static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, - struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_control); - size_t hdrlen; - - hdrlen = rtllib_get_hdrlen(fc); - if (ht_c_check(ieee, skb->data)) { - if (net_ratelimit()) - netdev_info(ieee->dev, "%s: find HTCControl!\n", - __func__); - hdrlen += 4; - rx_stats->contain_htc = true; - } - - return hdrlen; -} - -static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, - struct sk_buff *skb, u8 multicast) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc, sc; - u8 frag; - - fc = le16_to_cpu(hdr->frame_control); - sc = le16_to_cpu(hdr->seq_ctrl); - frag = WLAN_GET_SEQ_FRAG(sc); - - if (!ieee->ht_info->cur_rx_reorder_enable || - !ieee->current_network.qos_data.active || - !is_data_frame(skb->data) || - is_legacy_data_frame(skb->data)) { - if (!ieee80211_is_beacon(hdr->frame_control)) { - if (is_duplicate_packet(ieee, hdr)) - return -1; - } - } else { - struct rx_ts_record *ts = NULL; - - if (rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2, - (u8)frame_qos_tid((u8 *)(skb->data)), RX_DIR, true)) { - if ((fc & (1 << 11)) && (frag == ts->rx_last_frag_num) && - (WLAN_GET_SEQ_SEQ(sc) == ts->rx_last_seq_num)) - return -1; - ts->rx_last_frag_num = frag; - ts->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc); - } else { - netdev_warn(ieee->dev, "%s(): No TS! Skip the check!\n", - __func__); - return -1; - } - } - - return 0; -} - -static void rtllib_rx_extract_addr(struct rtllib_device *ieee, - struct ieee80211_hdr *hdr, u8 *dst, - u8 *src, u8 *bssid) -{ - u16 fc = le16_to_cpu(hdr->frame_control); - - switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_FROMDS: - ether_addr_copy(dst, hdr->addr1); - ether_addr_copy(src, hdr->addr3); - ether_addr_copy(bssid, hdr->addr2); - break; - case IEEE80211_FCTL_TODS: - ether_addr_copy(dst, hdr->addr3); - ether_addr_copy(src, hdr->addr2); - ether_addr_copy(bssid, hdr->addr1); - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - ether_addr_copy(dst, hdr->addr3); - ether_addr_copy(src, hdr->addr4); - ether_addr_copy(bssid, ieee->current_network.bssid); - break; - default: - ether_addr_copy(dst, hdr->addr1); - ether_addr_copy(src, hdr->addr2); - ether_addr_copy(bssid, hdr->addr3); - break; - } -} - -static int rtllib_rx_data_filter(struct rtllib_device *ieee, struct ieee80211_hdr *hdr, - u8 *dst, u8 *src, u8 *bssid, u8 *addr2) -{ - u16 fc = le16_to_cpu(hdr->frame_control); - u8 type = WLAN_FC_GET_TYPE(fc); - u8 stype = WLAN_FC_GET_STYPE(fc); - - /* Filter frames from different BSS */ - if (ieee80211_has_a4(hdr->frame_control) && - !ether_addr_equal(ieee->current_network.bssid, bssid) && - !is_zero_ether_addr(ieee->current_network.bssid)) { - return -1; - } - - /* Nullfunc frames may have PS-bit set, so they must be passed to - * hostap_handle_sta_rx() before being dropped here. - */ - if (stype != IEEE80211_STYPE_DATA && - stype != IEEE80211_STYPE_DATA_CFACK && - stype != IEEE80211_STYPE_DATA_CFPOLL && - stype != IEEE80211_STYPE_DATA_CFACKPOLL && - stype != IEEE80211_STYPE_QOS_DATA) { - if (stype != IEEE80211_STYPE_NULLFUNC) - netdev_dbg(ieee->dev, - "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n", - type, stype); - return -1; - } - - /* packets from our adapter are dropped (echo) */ - if (!memcmp(src, ieee->dev->dev_addr, ETH_ALEN)) - return -1; - - /* {broad,multi}cast packets to our BSS go through */ - if (is_multicast_ether_addr(dst)) { - if (memcmp(bssid, ieee->current_network.bssid, - ETH_ALEN)) - return -1; - } - return 0; -} - -static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb, - struct lib80211_crypt_data **crypt, size_t hdrlen) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_control); - int idx = 0; - - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - - *crypt = ieee->crypt_info.crypt[idx]; - /* allow NULL decrypt to indicate an station specific override - * for default encryption - */ - if (*crypt && (!(*crypt)->ops || !(*crypt)->ops->decrypt_mpdu)) - *crypt = NULL; - - if (!*crypt && (fc & IEEE80211_FCTL_PROTECTED)) { - /* This seems to be triggered by some (multicast?) - * frames from other than current BSS, so just drop the - * frames silently instead of filling system log with - * these reports. - */ - netdev_dbg(ieee->dev, - "Decryption failed (not set) (SA= %pM)\n", - hdr->addr2); - return -1; - } - - return 0; -} - -static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats, - struct lib80211_crypt_data *crypt, size_t hdrlen) -{ - struct ieee80211_hdr *hdr; - int keyidx = 0; - u16 fc, sc; - u8 frag; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = le16_to_cpu(hdr->frame_control); - sc = le16_to_cpu(hdr->seq_ctrl); - frag = WLAN_GET_SEQ_FRAG(sc); - - if ((!rx_stats->decrypted)) - ieee->need_sw_enc = 1; - else - ieee->need_sw_enc = 0; - - keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt); - if ((fc & IEEE80211_FCTL_PROTECTED) && (keyidx < 0)) { - netdev_info(ieee->dev, "%s: decrypt frame error\n", __func__); - return -1; - } - - hdr = (struct ieee80211_hdr *)skb->data; - if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { - int flen; - struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr); - - netdev_dbg(ieee->dev, "Rx Fragment received (%u)\n", frag); - - if (!frag_skb) { - netdev_dbg(ieee->dev, - "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n", - (fc & IEEE80211_FCTL_MOREFRAGS) != 0, - WLAN_GET_SEQ_SEQ(sc), frag); - return -1; - } - flen = skb->len; - if (frag != 0) - flen -= hdrlen; - - if (frag_skb->tail + flen > frag_skb->end) { - netdev_warn(ieee->dev, - "%s: host decrypted and reassembled frame did not fit skb\n", - __func__); - rtllib_frag_cache_invalidate(ieee, hdr); - return -1; - } - - if (frag == 0) { - /* copy first fragment (including full headers) into - * beginning of the fragment cache skb - */ - skb_put_data(frag_skb, skb->data, flen); - } else { - /* append frame payload to the end of the fragment - * cache skb - */ - skb_put_data(frag_skb, skb->data + hdrlen, flen); - } - dev_kfree_skb_any(skb); - skb = NULL; - - if (fc & IEEE80211_FCTL_MOREFRAGS) { - /* more fragments expected - leave the skb in fragment - * cache for now; it will be delivered to upper layers - * after all fragments have been received - */ - return -2; - } - - /* this was the last fragment and the frame will be - * delivered, so remove skb from fragment cache - */ - skb = frag_skb; - hdr = (struct ieee80211_hdr *)skb->data; - rtllib_frag_cache_invalidate(ieee, hdr); - } - - /* skb: hdr + (possible reassembled) full MSDU payload; possibly still - * encrypted/authenticated - */ - if ((fc & IEEE80211_FCTL_PROTECTED) && - rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) { - netdev_info(ieee->dev, "%s: ==>decrypt msdu error\n", __func__); - return -1; - } - - hdr = (struct ieee80211_hdr *)skb->data; - if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) { - if (/*ieee->ieee802_1x &&*/ - rtllib_is_eapol_frame(ieee, skb, hdrlen)) { - /* pass unencrypted EAPOL frames even if encryption is - * configured - */ - struct eapol *eap = (struct eapol *)(skb->data + - 24); - netdev_dbg(ieee->dev, - "RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); - } else { - netdev_dbg(ieee->dev, - "encryption configured, but RX frame not encrypted (SA= %pM)\n", - hdr->addr2); - return -1; - } - } - - if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && - rtllib_is_eapol_frame(ieee, skb, hdrlen)) { - struct eapol *eap = (struct eapol *)(skb->data + 24); - - netdev_dbg(ieee->dev, "RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - - if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep && - !rtllib_is_eapol_frame(ieee, skb, hdrlen)) { - netdev_dbg(ieee->dev, - "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n", - hdr->addr2); - return -1; - } - - return 0; -} - -static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, - u8 nr_subframes) -{ - if (unicast) { - if (ieee->link_state == MAC80211_LINKED) { - if (((ieee->link_detect_info.num_rx_unicast_ok_in_period + - ieee->link_detect_info.num_tx_ok_in_period) > 8) || - (ieee->link_detect_info.num_rx_unicast_ok_in_period > 2)) { - ieee->leisure_ps_leave(ieee->dev); - } - } - } - ieee->last_rx_ps_time = jiffies; -} - -static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, - struct rtllib_rx_stats *rx_stats, - struct rtllib_rxb *rxb, - u8 *dst, - u8 *src) -{ - struct net_device *dev = ieee->dev; - u16 ethertype; - int i = 0; - - if (!rxb) { - netdev_info(dev, "%s: rxb is NULL!!\n", __func__); - return; - } - - for (i = 0; i < rxb->nr_subframes; i++) { - struct sk_buff *sub_skb = rxb->subframes[i]; - - if (sub_skb) { - /* convert hdr + possible LLC headers - * into Ethernet header - */ - ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation - * and replace EtherType - */ - skb_pull(sub_skb, SNAP_SIZE); - ether_addr_copy(skb_push(sub_skb, ETH_ALEN), - src); - ether_addr_copy(skb_push(sub_skb, ETH_ALEN), - dst); - } else { - u16 len; - /* Leave Ethernet header part of hdr - * and full payload - */ - len = sub_skb->len; - memcpy(skb_push(sub_skb, 2), &len, 2); - ether_addr_copy(skb_push(sub_skb, ETH_ALEN), - src); - ether_addr_copy(skb_push(sub_skb, ETH_ALEN), - dst); - } - - ieee->stats.rx_packets++; - ieee->stats.rx_bytes += sub_skb->len; - - if (is_multicast_ether_addr(dst)) - ieee->stats.multicast++; - - /* Indicate the packets to upper layer */ - memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->protocol = eth_type_trans(sub_skb, dev); - sub_skb->dev = dev; - sub_skb->dev->stats.rx_packets++; - sub_skb->dev->stats.rx_bytes += sub_skb->len; - /* 802.11 crc not sufficient */ - sub_skb->ip_summed = CHECKSUM_NONE; - netif_rx(sub_skb); - } - } - kfree(rxb); -} - -static int rtllib_rx_infra_adhoc(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - struct net_device *dev = ieee->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct lib80211_crypt_data *crypt = NULL; - struct rtllib_rxb *rxb = NULL; - struct rx_ts_record *ts = NULL; - u16 fc, sc, SeqNum = 0; - u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 bssid[ETH_ALEN] = {0}; - - size_t hdrlen = 0; - int ret = 0, i = 0; - - fc = le16_to_cpu(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctrl); - - /*Filter pkt not to me*/ - multicast = is_multicast_ether_addr(hdr->addr1); - unicast = !multicast; - if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) - goto rx_dropped; - - /*Filter pkt has too small length */ - hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats); - if (skb->len < hdrlen) { - netdev_info(dev, - "%s():ERR!!! skb->len is smaller than hdrlen\n", - __func__); - goto rx_dropped; - } - - /* Filter Duplicate pkt */ - ret = rtllib_rx_check_duplicate(ieee, skb, multicast); - if (ret < 0) - goto rx_dropped; - - /* Filter CTRL Frame */ - if (type == RTLLIB_FTYPE_CTL) - goto rx_dropped; - - /* Filter MGNT Frame */ - if (type == RTLLIB_FTYPE_MGMT) { - if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) - goto rx_dropped; - else - goto rx_exit; - } - - /* Filter WAPI DATA Frame */ - - /* Update statstics for AP roaming */ - ieee->link_detect_info.num_recv_data_in_period++; - ieee->link_detect_info.num_rx_ok_in_period++; - - /* Data frame - extract src/dst addresses */ - rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid); - - /* Filter Data frames */ - ret = rtllib_rx_data_filter(ieee, hdr, dst, src, bssid, hdr->addr2); - if (ret < 0) - goto rx_dropped; - - if (skb->len == hdrlen) - goto rx_dropped; - - /* Send pspoll based on moredata */ - if ((ieee->iw_mode == IW_MODE_INFRA) && - (ieee->sta_sleep == LPS_IS_SLEEP) && - (ieee->polling)) { - if (WLAN_FC_MORE_DATA(fc)) { - /* more data bit is set, let's request a new frame - * from the AP - */ - rtllib_sta_ps_send_pspoll_frame(ieee); - } else { - ieee->polling = false; - } - } - - /* Get crypt if encrypted */ - ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen); - if (ret == -1) - goto rx_dropped; - - /* Decrypt data frame (including reassemble) */ - ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen); - if (ret == -1) - goto rx_dropped; - else if (ret == -2) - goto rx_exit; - - /* Get TS for Rx Reorder */ - hdr = (struct ieee80211_hdr *)skb->data; - if (ieee->current_network.qos_data.active && is_qos_data_frame(skb->data) - && !is_multicast_ether_addr(hdr->addr1)) { - TID = frame_qos_tid(skb->data); - SeqNum = WLAN_GET_SEQ_SEQ(sc); - rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2, TID, - RX_DIR, true); - if (TID != 0 && TID != 3) - ieee->bis_any_nonbepkts = true; - } - - /* Parse rx data frame (For AMSDU) */ - /* skb: hdr + (possible reassembled) full plaintext payload */ - rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC); - if (!rxb) - goto rx_dropped; - - /* to parse amsdu packets */ - /* qos data packets & reserved bit is 1 */ - if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) { - /* only to free rxb, and not submit the packets - * to upper layer - */ - for (i = 0; i < rxb->nr_subframes; i++) - dev_kfree_skb(rxb->subframes[i]); - kfree(rxb); - rxb = NULL; - goto rx_dropped; - } - - /* Update WAPI PN */ - - /* Check if leave LPS */ - if (ieee->is_aggregate_frame) - nr_subframes = rxb->nr_subframes; - else - nr_subframes = 1; - if (unicast) - ieee->link_detect_info.num_rx_unicast_ok_in_period += nr_subframes; - rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes); - - /* Indicate packets to upper layer or Rx Reorder */ - if (!ieee->ht_info->cur_rx_reorder_enable || !ts) - rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src); - else - rx_reorder_indicate_packet(ieee, rxb, ts, SeqNum); - - dev_kfree_skb(skb); - - rx_exit: - return 1; - - rx_dropped: - ieee->stats.rx_dropped++; - - /* Returning 0 indicates to caller that we have not handled the SKB-- - * so it is still allocated and can be used again by underlying - * hardware as a DMA target - */ - return 0; -} - -static int rtllib_rx_monitor(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_control); - size_t hdrlen = rtllib_get_hdrlen(fc); - - if (skb->len < hdrlen) { - netdev_info(ieee->dev, - "%s():ERR!!! skb->len is smaller than hdrlen\n", - __func__); - return 0; - } - - if (ht_c_check(ieee, skb->data)) { - if (net_ratelimit()) - netdev_info(ieee->dev, "%s: Find HTCControl!\n", - __func__); - hdrlen += 4; - } - - ieee->stats.rx_packets++; - ieee->stats.rx_bytes += skb->len; - rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen); - - return 1; -} - -/* All received frames are sent to this function. @skb contains the frame in - * IEEE 802.11 format, i.e., in the format it was sent over air. - * This function is called only as a tasklet (software IRQ). - */ -int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - int ret = 0; - - if (!ieee || !skb || !rx_stats) { - pr_info("%s: Input parameters NULL!\n", __func__); - goto rx_dropped; - } - if (skb->len < 10) { - netdev_info(ieee->dev, "%s: SKB length < 10\n", __func__); - goto rx_dropped; - } - - switch (ieee->iw_mode) { - case IW_MODE_INFRA: - ret = rtllib_rx_infra_adhoc(ieee, skb, rx_stats); - break; - case IW_MODE_MONITOR: - ret = rtllib_rx_monitor(ieee, skb, rx_stats); - break; - default: - netdev_info(ieee->dev, "%s: ERR iw mode!!!\n", __func__); - break; - } - - return ret; - - rx_dropped: - if (ieee) - ieee->stats.rx_dropped++; - return 0; -} -EXPORT_SYMBOL(rtllib_rx); - -static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; - -/* Make ther structure we read from the beacon packet has the right values */ -static int rtllib_verify_qos_info(struct rtllib_qos_information_element - *info_element, int sub_type) -{ - if (info_element->element_id != QOS_ELEMENT_ID) - return -1; - if (info_element->qui_subtype != sub_type) - return -1; - if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) - return -1; - if (info_element->qui_type != QOS_OUI_TYPE) - return -1; - if (info_element->version != QOS_VERSION_1) - return -1; - - return 0; -} - -/* Parse a QoS parameter element */ -static int rtllib_read_qos_param_element( - struct rtllib_qos_parameter_info *element_param, - struct rtllib_info_element *info_element) -{ - size_t size = sizeof(*element_param); - - if (!element_param || !info_element || info_element->len != size - 2) - return -1; - - memcpy(element_param, info_element, size); - return rtllib_verify_qos_info(&element_param->info_element, - QOS_OUI_PARAM_SUB_TYPE); -} - -/* Parse a QoS information element */ -static int rtllib_read_qos_info_element( - struct rtllib_qos_information_element *element_info, - struct rtllib_info_element *info_element) -{ - size_t size = sizeof(*element_info); - - if (!element_info || !info_element || info_element->len != size - 2) - return -1; - - memcpy(element_info, info_element, size); - return rtllib_verify_qos_info(element_info, QOS_OUI_INFO_SUB_TYPE); -} - -/* Write QoS parameters from the ac parameters. */ -static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm, - struct rtllib_qos_data *qos_data) -{ - struct rtllib_qos_ac_parameter *ac_params; - struct rtllib_qos_parameters *qos_param = &(qos_data->parameters); - int i; - u8 aci; - u8 acm; - - qos_data->wmm_acm = 0; - for (i = 0; i < QOS_QUEUE_NUM; i++) { - ac_params = &(param_elm->ac_params_record[i]); - - aci = (ac_params->aci_aifsn & 0x60) >> 5; - acm = (ac_params->aci_aifsn & 0x10) >> 4; - - if (aci >= QOS_QUEUE_NUM) - continue; - switch (aci) { - case 1: - /* BIT(0) | BIT(3) */ - if (acm) - qos_data->wmm_acm |= (0x01 << 0) | (0x01 << 3); - break; - case 2: - /* BIT(4) | BIT(5) */ - if (acm) - qos_data->wmm_acm |= (0x01 << 4) | (0x01 << 5); - break; - case 3: - /* BIT(6) | BIT(7) */ - if (acm) - qos_data->wmm_acm |= (0x01 << 6) | (0x01 << 7); - break; - case 0: - default: - /* BIT(1) | BIT(2) */ - if (acm) - qos_data->wmm_acm |= (0x01 << 1) | (0x01 << 2); - break; - } - - qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; - - /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ - qos_param->aifs[aci] = max_t(u8, qos_param->aifs[aci], 2); - - qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & - 0x0F); - - qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max & - 0xF0) >> 4); - - qos_param->flag[aci] = - (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; - qos_param->tx_op_limit[aci] = ac_params->tx_op_limit; - } - return 0; -} - -/* we have a generic data element which it may contain QoS information or - * parameters element. check the information element length to decide - * which type to read - */ -static int rtllib_parse_qos_info_param_IE(struct rtllib_device *ieee, - struct rtllib_info_element - *info_element, - struct rtllib_network *network) -{ - int rc = 0; - struct rtllib_qos_information_element qos_info_element; - - rc = rtllib_read_qos_info_element(&qos_info_element, info_element); - - if (rc == 0) { - network->qos_data.param_count = qos_info_element.ac_info & 0x0F; - network->flags |= NETWORK_HAS_QOS_INFORMATION; - } else { - struct rtllib_qos_parameter_info param_element; - - rc = rtllib_read_qos_param_element(¶m_element, - info_element); - if (rc == 0) { - rtllib_qos_convert_ac_to_parameters(¶m_element, - &(network->qos_data)); - network->flags |= NETWORK_HAS_QOS_PARAMETERS; - network->qos_data.param_count = - param_element.info_element.ac_info & 0x0F; - } - } - - if (rc == 0) { - netdev_dbg(ieee->dev, "QoS is supported\n"); - network->qos_data.supported = 1; - } - return rc; -} - -static const char *get_info_element_string(u16 id) -{ - switch (id) { - case MFIE_TYPE_SSID: - return "SSID"; - case MFIE_TYPE_RATES: - return "RATES"; - case MFIE_TYPE_FH_SET: - return "FH_SET"; - case MFIE_TYPE_DS_SET: - return "DS_SET"; - case MFIE_TYPE_CF_SET: - return "CF_SET"; - case MFIE_TYPE_TIM: - return "TIM"; - case MFIE_TYPE_IBSS_SET: - return "IBSS_SET"; - case MFIE_TYPE_COUNTRY: - return "COUNTRY"; - case MFIE_TYPE_HOP_PARAMS: - return "HOP_PARAMS"; - case MFIE_TYPE_HOP_TABLE: - return "HOP_TABLE"; - case MFIE_TYPE_REQUEST: - return "REQUEST"; - case MFIE_TYPE_CHALLENGE: - return "CHALLENGE"; - case MFIE_TYPE_POWER_CONSTRAINT: - return "POWER_CONSTRAINT"; - case MFIE_TYPE_POWER_CAPABILITY: - return "POWER_CAPABILITY"; - case MFIE_TYPE_TPC_REQUEST: - return "TPC_REQUEST"; - case MFIE_TYPE_TPC_REPORT: - return "TPC_REPORT"; - case MFIE_TYPE_SUPP_CHANNELS: - return "SUPP_CHANNELS"; - case MFIE_TYPE_CSA: - return "CSA"; - case MFIE_TYPE_MEASURE_REQUEST: - return "MEASURE_REQUEST"; - case MFIE_TYPE_MEASURE_REPORT: - return "MEASURE_REPORT"; - case MFIE_TYPE_QUIET: - return "QUIET"; - case MFIE_TYPE_IBSS_DFS: - return "IBSS_DFS"; - case MFIE_TYPE_RSN: - return "RSN"; - case MFIE_TYPE_RATES_EX: - return "RATES_EX"; - case MFIE_TYPE_GENERIC: - return "GENERIC"; - case MFIE_TYPE_QOS_PARAMETER: - return "QOS_PARAMETER"; - default: - return "UNKNOWN"; - } -} - -static void rtllib_parse_mife_generic(struct rtllib_device *ieee, - struct rtllib_info_element *info_element, - struct rtllib_network *network, - u16 *tmp_htcap_len, - u16 *tmp_htinfo_len) -{ - u16 ht_realtek_agg_len = 0; - u8 ht_realtek_agg_buf[MAX_IE_LEN]; - - if (!rtllib_parse_qos_info_param_IE(ieee, info_element, network)) - return; - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - network->wpa_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->wpa_ie, info_element, network->wpa_ie_len); - return; - } - if (info_element->len == 7 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x01 && - info_element->data[4] == 0x02) - network->turbo_enable = 1; - - if (*tmp_htcap_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x033) { - *tmp_htcap_len = min_t(u8, info_element->len, - MAX_IE_LEN); - if (*tmp_htcap_len != 0) { - network->bssht.bd_ht_spec_ver = HT_SPEC_VER_EWC; - network->bssht.bd_ht_cap_len = min_t(u16, *tmp_htcap_len, - sizeof(network->bssht.bd_ht_cap_buf)); - memcpy(network->bssht.bd_ht_cap_buf, - info_element->data, - network->bssht.bd_ht_cap_len); - } - } - if (*tmp_htcap_len != 0) { - network->bssht.bd_support_ht = true; - network->bssht.bd_ht_1r = ((((struct ht_capab_ele *)(network->bssht.bd_ht_cap_buf))->MCS[1]) == 0); - } else { - network->bssht.bd_support_ht = false; - network->bssht.bd_ht_1r = false; - } - } - - if (*tmp_htinfo_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x034) { - *tmp_htinfo_len = min_t(u8, info_element->len, - MAX_IE_LEN); - if (*tmp_htinfo_len != 0) { - network->bssht.bd_ht_spec_ver = HT_SPEC_VER_EWC; - network->bssht.bd_ht_info_len = min_t(u16, *tmp_htinfo_len, - sizeof(network->bssht.bd_ht_info_buf)); - memcpy(network->bssht.bd_ht_info_buf, - info_element->data, - network->bssht.bd_ht_info_len); - } - } - } - - if (network->bssht.bd_support_ht) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x02) { - ht_realtek_agg_len = min_t(u8, info_element->len, - MAX_IE_LEN); - memcpy(ht_realtek_agg_buf, info_element->data, - info_element->len); - } - if (ht_realtek_agg_len >= 5) { - network->realtek_cap_exit = true; - network->bssht.bd_rt2rt_aggregation = true; - - if ((ht_realtek_agg_buf[4] == 1) && - (ht_realtek_agg_buf[5] & 0x02)) - network->bssht.bd_rt2rt_long_slot_time = true; - - if ((ht_realtek_agg_buf[4] == 1) && - (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE)) - network->bssht.rt2rt_ht_mode |= RT_HT_CAP_USE_92SE; - } - } - if (ht_realtek_agg_len >= 5) { - if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP)) - network->bssht.rt2rt_ht_mode |= RT_HT_CAP_USE_SOFTAP; - } - - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x05 && - info_element->data[2] == 0xb5) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf7) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x10 && - info_element->data[2] == 0x18)) { - network->broadcom_cap_exist = true; - } - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0c && - info_element->data[2] == 0x43) - network->ralink_cap_exist = true; - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x03 && - info_element->data[2] == 0x7f) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x13 && - info_element->data[2] == 0x74)) - network->atheros_cap_exist = true; - - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0x43)) - network->marvell_cap_exist = true; - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96) - network->cisco_cap_exist = true; - - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf5) - network->airgo_cap_exist = true; - - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x01) { - if (info_element->len == 6) { - memcpy(network->ccx_rm_state, &info_element->data[4], 2); - if (network->ccx_rm_state[0] != 0) - network->ccx_rm_enable = true; - else - network->ccx_rm_enable = false; - network->mb_ssid_mask = network->ccx_rm_state[1] & 0x07; - if (network->mb_ssid_mask != 0) { - network->mb_ssid_valid = true; - network->mb_ssid_mask = 0xff << - (network->mb_ssid_mask); - ether_addr_copy(network->mb_ssid, - network->bssid); - network->mb_ssid[5] &= network->mb_ssid_mask; - } else { - network->mb_ssid_valid = false; - } - } else { - network->ccx_rm_enable = false; - } - } - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x03) { - if (info_element->len == 5) { - network->with_ccx_ver_num = true; - network->bss_ccx_ver_number = info_element->data[4]; - } else { - network->with_ccx_ver_num = false; - network->bss_ccx_ver_number = 0; - } - } - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x04) { - netdev_dbg(ieee->dev, "MFIE_TYPE_WZC: %d bytes\n", - info_element->len); - network->wzc_ie_len = min(info_element->len + 2, MAX_WZC_IE_LEN); - memcpy(network->wzc_ie, info_element, network->wzc_ie_len); - } -} - -static void rtllib_parse_mfie_ht_cap(struct rtllib_info_element *info_element, - struct rtllib_network *network, - u16 *tmp_htcap_len) -{ - struct bss_ht *ht = &network->bssht; - - *tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); - if (*tmp_htcap_len != 0) { - ht->bd_ht_spec_ver = HT_SPEC_VER_EWC; - ht->bd_ht_cap_len = min_t(u16, *tmp_htcap_len, - sizeof(ht->bd_ht_cap_buf)); - memcpy(ht->bd_ht_cap_buf, info_element->data, ht->bd_ht_cap_len); - - ht->bd_support_ht = true; - ht->bd_ht_1r = ((((struct ht_capab_ele *) - ht->bd_ht_cap_buf))->MCS[1]) == 0; - - ht->bd_bandwidth = (enum ht_channel_width) - (((struct ht_capab_ele *) - (ht->bd_ht_cap_buf))->chl_width); - } else { - ht->bd_support_ht = false; - ht->bd_ht_1r = false; - ht->bd_bandwidth = HT_CHANNEL_WIDTH_20; - } -} - -int rtllib_parse_info_param(struct rtllib_device *ieee, - struct rtllib_info_element *info_element, - u16 length, - struct rtllib_network *network, - struct rtllib_rx_stats *stats) -{ - u8 i; - short offset; - u16 tmp_htcap_len = 0; - u16 tmp_htinfo_len = 0; - char rates_str[64]; - char *p; - - while (length >= sizeof(*info_element)) { - if (sizeof(*info_element) + info_element->len > length) { - netdev_dbg(ieee->dev, - "Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + sizeof(*info_element), - length, info_element->id); - /* We stop processing but don't return an error here - * because some misbehaviour APs break this rule. ie. - * Orinoco AP1000. - */ - break; - } - - switch (info_element->id) { - case MFIE_TYPE_SSID: - if (rtllib_is_empty_essid(info_element->data, - info_element->len)) { - network->flags |= NETWORK_EMPTY_ESSID; - break; - } - - network->ssid_len = min(info_element->len, - (u8)IW_ESSID_MAX_SIZE); - memcpy(network->ssid, info_element->data, - network->ssid_len); - if (network->ssid_len < IW_ESSID_MAX_SIZE) - memset(network->ssid + network->ssid_len, 0, - IW_ESSID_MAX_SIZE - network->ssid_len); - - netdev_dbg(ieee->dev, "MFIE_TYPE_SSID: '%s' len=%d.\n", - network->ssid, network->ssid_len); - break; - - case MFIE_TYPE_RATES: - p = rates_str; - network->rates_len = min(info_element->len, - MAX_RATES_LENGTH); - for (i = 0; i < network->rates_len; i++) { - network->rates[i] = info_element->data[i]; - p += scnprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates[i]); - if (rtllib_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - RTLLIB_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - - if (rtllib_is_cck_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_CCK; - } - } - - netdev_dbg(ieee->dev, "MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); - break; - - case MFIE_TYPE_RATES_EX: - p = rates_str; - network->rates_ex_len = min(info_element->len, - MAX_RATES_EX_LENGTH); - for (i = 0; i < network->rates_ex_len; i++) { - network->rates_ex[i] = info_element->data[i]; - p += scnprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates_ex[i]); - if (rtllib_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - RTLLIB_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - netdev_dbg(ieee->dev, "MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); - break; - - case MFIE_TYPE_DS_SET: - netdev_dbg(ieee->dev, "MFIE_TYPE_DS_SET: %d\n", - info_element->data[0]); - network->channel = info_element->data[0]; - break; - - case MFIE_TYPE_FH_SET: - netdev_dbg(ieee->dev, "MFIE_TYPE_FH_SET: ignored\n"); - break; - - case MFIE_TYPE_CF_SET: - netdev_dbg(ieee->dev, "MFIE_TYPE_CF_SET: ignored\n"); - break; - - case MFIE_TYPE_TIM: - if (info_element->len < 4) - break; - - network->tim.tim_count = info_element->data[0]; - network->tim.tim_period = info_element->data[1]; - - network->dtim_period = info_element->data[1]; - if (ieee->link_state != MAC80211_LINKED) - break; - network->last_dtim_sta_time = jiffies; - - network->dtim_data = RTLLIB_DTIM_VALID; - - if (info_element->data[2] & 1) - network->dtim_data |= RTLLIB_DTIM_MBCAST; - - offset = (info_element->data[2] >> 1) * 2; - - if (ieee->assoc_id < 8 * offset || - ieee->assoc_id > 8 * (offset + info_element->len - 3)) - break; - - offset = (ieee->assoc_id / 8) - offset; - if (info_element->data[3 + offset] & - (1 << (ieee->assoc_id % 8))) - network->dtim_data |= RTLLIB_DTIM_UCAST; - - network->listen_interval = network->dtim_period; - break; - - case MFIE_TYPE_ERP: - network->erp_value = info_element->data[0]; - network->flags |= NETWORK_HAS_ERP_VALUE; - netdev_dbg(ieee->dev, "MFIE_TYPE_ERP_SET: %d\n", - network->erp_value); - break; - case MFIE_TYPE_IBSS_SET: - network->atim_window = info_element->data[0]; - netdev_dbg(ieee->dev, "MFIE_TYPE_IBSS_SET: %d\n", - network->atim_window); - break; - - case MFIE_TYPE_CHALLENGE: - netdev_dbg(ieee->dev, "MFIE_TYPE_CHALLENGE: ignored\n"); - break; - - case MFIE_TYPE_GENERIC: - netdev_dbg(ieee->dev, "MFIE_TYPE_GENERIC: %d bytes\n", - info_element->len); - - rtllib_parse_mife_generic(ieee, info_element, network, - &tmp_htcap_len, - &tmp_htinfo_len); - break; - - case MFIE_TYPE_RSN: - netdev_dbg(ieee->dev, "MFIE_TYPE_RSN: %d bytes\n", - info_element->len); - network->rsn_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->rsn_ie, info_element, - network->rsn_ie_len); - break; - - case MFIE_TYPE_HT_CAP: - netdev_dbg(ieee->dev, "MFIE_TYPE_HT_CAP: %d bytes\n", - info_element->len); - - rtllib_parse_mfie_ht_cap(info_element, network, - &tmp_htcap_len); - break; - - case MFIE_TYPE_HT_INFO: - netdev_dbg(ieee->dev, "MFIE_TYPE_HT_INFO: %d bytes\n", - info_element->len); - tmp_htinfo_len = min_t(u8, info_element->len, - MAX_IE_LEN); - if (tmp_htinfo_len) { - network->bssht.bd_ht_spec_ver = HT_SPEC_VER_IEEE; - network->bssht.bd_ht_info_len = tmp_htinfo_len > - sizeof(network->bssht.bd_ht_info_buf) ? - sizeof(network->bssht.bd_ht_info_buf) : - tmp_htinfo_len; - memcpy(network->bssht.bd_ht_info_buf, - info_element->data, - network->bssht.bd_ht_info_len); - } - break; - - case MFIE_TYPE_AIRONET: - netdev_dbg(ieee->dev, "MFIE_TYPE_AIRONET: %d bytes\n", - info_element->len); - if (info_element->len > IE_CISCO_FLAG_POSITION) { - network->with_aironet_ie = true; - - if ((info_element->data[IE_CISCO_FLAG_POSITION] - & SUPPORT_CKIP_MIC) || - (info_element->data[IE_CISCO_FLAG_POSITION] - & SUPPORT_CKIP_PK)) - network->ckip_supported = true; - else - network->ckip_supported = false; - } else { - network->with_aironet_ie = false; - network->ckip_supported = false; - } - break; - case MFIE_TYPE_QOS_PARAMETER: - netdev_err(ieee->dev, - "QoS Error need to parse QOS_PARAMETER IE\n"); - break; - - case MFIE_TYPE_COUNTRY: - netdev_dbg(ieee->dev, "MFIE_TYPE_COUNTRY: %d bytes\n", - info_element->len); - break; -/* TODO */ - default: - netdev_dbg(ieee->dev, - "Unsupported info element: %s (%d)\n", - get_info_element_string(info_element->id), - info_element->id); - break; - } - - length -= sizeof(*info_element) + info_element->len; - info_element = - (struct rtllib_info_element *)&info_element->data[info_element->len]; - } - - if (!network->atheros_cap_exist && !network->broadcom_cap_exist && - !network->cisco_cap_exist && !network->ralink_cap_exist && - !network->bssht.bd_rt2rt_aggregation) - network->unknown_cap_exist = true; - else - network->unknown_cap_exist = false; - return 0; -} - -static long rtllib_translate_todbm(u8 signal_strength_index) -{ - long signal_power; - - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -static inline int rtllib_network_init( - struct rtllib_device *ieee, - struct rtllib_probe_response *beacon, - struct rtllib_network *network, - struct rtllib_rx_stats *stats) -{ - memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data)); - - /* Pull out fixed field data */ - ether_addr_copy(network->bssid, beacon->header.addr3); - network->capability = le16_to_cpu(beacon->capability); - network->last_scanned = jiffies; - network->time_stamp[0] = beacon->time_stamp[0]; - network->time_stamp[1] = beacon->time_stamp[1]; - network->beacon_interval = le16_to_cpu(beacon->beacon_interval); - /* Where to pull this? beacon->listen_interval;*/ - network->listen_interval = 0x0A; - network->rates_len = network->rates_ex_len = 0; - network->ssid_len = 0; - network->hidden_ssid_len = 0; - memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid)); - network->flags = 0; - network->atim_window = 0; - network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? - 0x3 : 0x0; - network->berp_info_valid = false; - network->broadcom_cap_exist = false; - network->ralink_cap_exist = false; - network->atheros_cap_exist = false; - network->cisco_cap_exist = false; - network->unknown_cap_exist = false; - network->realtek_cap_exit = false; - network->marvell_cap_exist = false; - network->airgo_cap_exist = false; - network->turbo_enable = 0; - network->SignalStrength = stats->SignalStrength; - network->RSSI = stats->SignalStrength; - network->country_ie_len = 0; - memset(network->country_ie_buf, 0, MAX_IE_LEN); - ht_initialize_bss_desc(&network->bssht); - network->flags |= NETWORK_HAS_CCK; - - network->wpa_ie_len = 0; - network->rsn_ie_len = 0; - network->wzc_ie_len = 0; - - if (rtllib_parse_info_param(ieee, - beacon->info_element, - (stats->len - sizeof(*beacon)), - network, - stats)) - return 1; - - network->mode = 0; - - if (network->flags & NETWORK_HAS_OFDM) - network->mode |= WIRELESS_MODE_G; - if (network->flags & NETWORK_HAS_CCK) - network->mode |= WIRELESS_MODE_B; - - if (network->mode == 0) { - netdev_dbg(ieee->dev, "Filtered out '%s (%pM)' network.\n", - escape_essid(network->ssid, network->ssid_len), - network->bssid); - return 1; - } - - if (network->bssht.bd_support_ht) { - if (network->mode & (WIRELESS_MODE_G | WIRELESS_MODE_B)) - network->mode = WIRELESS_MODE_N_24G; - } - if (rtllib_is_empty_essid(network->ssid, network->ssid_len)) - network->flags |= NETWORK_EMPTY_ESSID; - stats->signal = 30 + (stats->SignalStrength * 70) / 100; - stats->noise = rtllib_translate_todbm((u8)(100 - stats->signal)) - 25; - - memcpy(&network->stats, stats, sizeof(network->stats)); - - return 0; -} - -static inline int is_same_network(struct rtllib_network *src, - struct rtllib_network *dst, u8 ssidbroad) -{ - /* A network is only a duplicate if the channel, BSSID, ESSID - * and the capability field (in particular IBSS and BSS) all match. - * We treat all with the same BSSID and channel - * as one network - */ - return (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) && - (src->channel == dst->channel) && - !memcmp(src->bssid, dst->bssid, ETH_ALEN) && - (!memcmp(src->ssid, dst->ssid, src->ssid_len) || - (!ssidbroad)) && - ((src->capability & WLAN_CAPABILITY_IBSS) == - (dst->capability & WLAN_CAPABILITY_IBSS)) && - ((src->capability & WLAN_CAPABILITY_ESS) == - (dst->capability & WLAN_CAPABILITY_ESS))); -} - -static inline void update_network(struct rtllib_device *ieee, - struct rtllib_network *dst, - struct rtllib_network *src) -{ - int qos_active; - u8 old_param; - - memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats)); - dst->capability = src->capability; - memcpy(dst->rates, src->rates, src->rates_len); - dst->rates_len = src->rates_len; - memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); - dst->rates_ex_len = src->rates_ex_len; - if (src->ssid_len > 0) { - if (dst->ssid_len == 0) { - memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid)); - dst->hidden_ssid_len = src->ssid_len; - memcpy(dst->hidden_ssid, src->ssid, src->ssid_len); - } else { - memset(dst->ssid, 0, dst->ssid_len); - dst->ssid_len = src->ssid_len; - memcpy(dst->ssid, src->ssid, src->ssid_len); - } - } - dst->mode = src->mode; - dst->flags = src->flags; - dst->time_stamp[0] = src->time_stamp[0]; - dst->time_stamp[1] = src->time_stamp[1]; - if (src->flags & NETWORK_HAS_ERP_VALUE) { - dst->erp_value = src->erp_value; - dst->berp_info_valid = src->berp_info_valid = true; - } - dst->beacon_interval = src->beacon_interval; - dst->listen_interval = src->listen_interval; - dst->atim_window = src->atim_window; - dst->dtim_period = src->dtim_period; - dst->dtim_data = src->dtim_data; - dst->last_dtim_sta_time = src->last_dtim_sta_time; - memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters)); - - dst->bssht.bd_support_ht = src->bssht.bd_support_ht; - dst->bssht.bd_rt2rt_aggregation = src->bssht.bd_rt2rt_aggregation; - dst->bssht.bd_ht_cap_len = src->bssht.bd_ht_cap_len; - memcpy(dst->bssht.bd_ht_cap_buf, src->bssht.bd_ht_cap_buf, - src->bssht.bd_ht_cap_len); - dst->bssht.bd_ht_info_len = src->bssht.bd_ht_info_len; - memcpy(dst->bssht.bd_ht_info_buf, src->bssht.bd_ht_info_buf, - src->bssht.bd_ht_info_len); - dst->bssht.bd_ht_spec_ver = src->bssht.bd_ht_spec_ver; - dst->bssht.bd_rt2rt_long_slot_time = src->bssht.bd_rt2rt_long_slot_time; - dst->broadcom_cap_exist = src->broadcom_cap_exist; - dst->ralink_cap_exist = src->ralink_cap_exist; - dst->atheros_cap_exist = src->atheros_cap_exist; - dst->realtek_cap_exit = src->realtek_cap_exit; - dst->marvell_cap_exist = src->marvell_cap_exist; - dst->cisco_cap_exist = src->cisco_cap_exist; - dst->airgo_cap_exist = src->airgo_cap_exist; - dst->unknown_cap_exist = src->unknown_cap_exist; - memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); - dst->wpa_ie_len = src->wpa_ie_len; - memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); - dst->rsn_ie_len = src->rsn_ie_len; - memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len); - dst->wzc_ie_len = src->wzc_ie_len; - - dst->last_scanned = jiffies; - /* qos related parameters */ - qos_active = dst->qos_data.active; - old_param = dst->qos_data.param_count; - dst->qos_data.supported = src->qos_data.supported; - if (dst->flags & NETWORK_HAS_QOS_PARAMETERS) - memcpy(&dst->qos_data, &src->qos_data, - sizeof(struct rtllib_qos_data)); - if (dst->qos_data.supported == 1) { - if (dst->ssid_len) - netdev_dbg(ieee->dev, - "QoS the network %s is QoS supported\n", - dst->ssid); - else - netdev_dbg(ieee->dev, - "QoS the network is QoS supported\n"); - } - dst->qos_data.active = qos_active; - dst->qos_data.old_param_count = old_param; - - dst->wmm_info = src->wmm_info; - if (src->wmm_param[0].ac_aci_acm_aifsn || - src->wmm_param[1].ac_aci_acm_aifsn || - src->wmm_param[2].ac_aci_acm_aifsn || - src->wmm_param[3].ac_aci_acm_aifsn) - memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); - - dst->SignalStrength = src->SignalStrength; - dst->RSSI = src->RSSI; - dst->turbo_enable = src->turbo_enable; - - dst->country_ie_len = src->country_ie_len; - memcpy(dst->country_ie_buf, src->country_ie_buf, src->country_ie_len); - - dst->with_aironet_ie = src->with_aironet_ie; - dst->ckip_supported = src->ckip_supported; - memcpy(dst->ccx_rm_state, src->ccx_rm_state, 2); - dst->ccx_rm_enable = src->ccx_rm_enable; - dst->mb_ssid_mask = src->mb_ssid_mask; - dst->mb_ssid_valid = src->mb_ssid_valid; - memcpy(dst->mb_ssid, src->mb_ssid, 6); - dst->with_ccx_ver_num = src->with_ccx_ver_num; - dst->bss_ccx_ver_number = src->bss_ccx_ver_number; -} - -static int is_passive_channel(struct rtllib_device *rtllib, u8 channel) -{ - if (channel > MAX_CHANNEL_NUMBER) { - netdev_info(rtllib->dev, "%s(): Invalid Channel\n", __func__); - return 0; - } - - if (rtllib->active_channel_map[channel] == 2) - return 1; - - return 0; -} - -int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel) -{ - if (channel > MAX_CHANNEL_NUMBER) { - netdev_info(rtllib->dev, "%s(): Invalid Channel\n", __func__); - return 0; - } - if (rtllib->active_channel_map[channel] > 0) - return 1; - - return 0; -} -EXPORT_SYMBOL(rtllib_legal_channel); - -static inline void rtllib_process_probe_response( - struct rtllib_device *ieee, - struct rtllib_probe_response *beacon, - struct rtllib_rx_stats *stats) -{ - struct rtllib_network *target; - struct rtllib_network *oldest = NULL; - struct rtllib_info_element *info_element = &beacon->info_element[0]; - unsigned long flags; - short renew; - struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), - GFP_ATOMIC); - __le16 frame_ctl = beacon->header.frame_control; - - if (!network) - return; - - netdev_dbg(ieee->dev, - "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - (le16_to_cpu(beacon->capability) & (1 << 0xf)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0xe)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0xd)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0xc)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0xb)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0xa)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x9)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x8)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x7)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x6)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x5)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x4)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x3)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x2)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x1)) ? '1' : '0', - (le16_to_cpu(beacon->capability) & (1 << 0x0)) ? '1' : '0'); - - if (rtllib_network_init(ieee, beacon, network, stats)) { - netdev_dbg(ieee->dev, "Dropped '%s' ( %pM) via %s.\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); - goto free_network; - } - - if (!rtllib_legal_channel(ieee, network->channel)) - goto free_network; - - if (ieee80211_is_probe_resp(frame_ctl)) { - if (is_passive_channel(ieee, network->channel)) { - netdev_info(ieee->dev, - "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", - network->channel); - goto free_network; - } - } - - /* The network parsed correctly -- so now we scan our known networks - * to see if we can find it in our list. - * - * NOTE: This search is definitely not optimized. Once its doing - * the "right thing" we'll optimize it for efficiency if - * necessary - */ - - /* Search for this entry in the list and update it if it is - * already there. - */ - - spin_lock_irqsave(&ieee->lock, flags); - if (is_same_network(&ieee->current_network, network, - (network->ssid_len ? 1 : 0))) { - update_network(ieee, &ieee->current_network, network); - if ((ieee->current_network.mode == WIRELESS_MODE_N_24G || - ieee->current_network.mode == WIRELESS_MODE_G) && - ieee->current_network.berp_info_valid) { - if (ieee->current_network.erp_value & ERP_UseProtection) - ieee->current_network.buseprotection = true; - else - ieee->current_network.buseprotection = false; - } - if (ieee80211_is_beacon(frame_ctl)) { - if (ieee->link_state >= MAC80211_LINKED) - ieee->link_detect_info.num_recv_bcn_in_period++; - } - } - list_for_each_entry(target, &ieee->network_list, list) { - if (is_same_network(target, network, - (target->ssid_len ? 1 : 0))) - break; - if (!oldest || (target->last_scanned < oldest->last_scanned)) - oldest = target; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information - */ - if (&target->list == &ieee->network_list) { - if (list_empty(&ieee->network_free_list)) { - /* If there are no more slots, expire the oldest */ - list_del(&oldest->list); - target = oldest; - netdev_dbg(ieee->dev, - "Expired '%s' ( %pM) from network list.\n", - escape_essid(target->ssid, target->ssid_len), - target->bssid); - } else { - /* Otherwise just pull from the free list */ - target = list_entry(ieee->network_free_list.next, - struct rtllib_network, list); - list_del(ieee->network_free_list.next); - } - - netdev_dbg(ieee->dev, "Adding '%s' ( %pM) via %s.\n", - escape_essid(network->ssid, network->ssid_len), - network->bssid, - ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); - - memcpy(target, network, sizeof(*target)); - list_add_tail(&target->list, &ieee->network_list); - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) - rtllib_softmac_new_net(ieee, network); - } else { - netdev_dbg(ieee->dev, "Updating '%s' ( %pM) via %s.\n", - escape_essid(target->ssid, target->ssid_len), - target->bssid, - ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); - - /* we have an entry and we are going to update it. But this - * entry may be already expired. In this case we do the same - * as we found a new net and call the new_net handler - */ - renew = !time_after(target->last_scanned + ieee->scan_age, - jiffies); - if ((!target->ssid_len) && - (((network->ssid_len > 0) && (target->hidden_ssid_len == 0)) - || ((ieee->current_network.ssid_len == network->ssid_len) && - (strncmp(ieee->current_network.ssid, network->ssid, - network->ssid_len) == 0) && - (ieee->link_state == MAC80211_NOLINK)))) - renew = 1; - update_network(ieee, target, network); - if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) - rtllib_softmac_new_net(ieee, network); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - if (ieee80211_is_beacon(frame_ctl) && - is_same_network(&ieee->current_network, network, - (network->ssid_len ? 1 : 0)) && - (ieee->link_state == MAC80211_LINKED)) { - ieee->handle_beacon(ieee->dev, beacon, &ieee->current_network); - } -free_network: - kfree(network); -} - -static void rtllib_rx_mgt(struct rtllib_device *ieee, - struct sk_buff *skb, - struct rtllib_rx_stats *stats) -{ - struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data; - - if (!ieee80211_is_probe_resp(header->frame_control) && - (!ieee80211_is_beacon(header->frame_control))) - ieee->last_rx_ps_time = jiffies; - - if (ieee80211_is_beacon(header->frame_control)) { - netdev_dbg(ieee->dev, "received BEACON\n"); - rtllib_process_probe_response( - ieee, (struct rtllib_probe_response *)header, - stats); - - if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->link_state == MAC80211_LINKED)) - schedule_work(&ieee->ps_task); - } else if (ieee80211_is_probe_resp(header->frame_control)) { - netdev_dbg(ieee->dev, "received PROBE RESPONSE\n"); - rtllib_process_probe_response(ieee, (struct rtllib_probe_response *)header, - stats); - } -} diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c deleted file mode 100644 index 0fc97c868f81..000000000000 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ /dev/null @@ -1,2309 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Few lines might be stolen from other part of the rtllib - * stack. Copyright who own it's copyright - * - * WPA code stolen from the ipw2200 driver. - * Copyright who own it's copyright. - */ -#include "rtllib.h" - -#include -#include -#include -#include -#include - -static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl); - -static short rtllib_is_54g(struct rtllib_network *net) -{ - return (net->rates_ex_len > 0) || (net->rates_len > 4); -} - -/* returns the total length needed for placing the RATE MFIE - * tag and the EXTENDED RATE MFIE tag if needed. - * It encludes two bytes per tag for the tag itself and its len - */ -static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee) -{ - unsigned int rate_len = 0; - - rate_len = RTLLIB_CCK_RATE_LEN + 2; - rate_len += RTLLIB_OFDM_RATE_LEN + 2; - - return rate_len; -} - -/* place the MFIE rate, tag to the memory (double) pointed. - * Then it updates the pointer so that - * it points after the new MFIE tag added. - */ -static void rtllib_mfie_brate(struct rtllib_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_RATES; - *tag++ = 4; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB; - - /* We may add an option for custom rates that specific HW - * might support - */ - *tag_p = tag; -} - -static void rtllib_mfie_grate(struct rtllib_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_RATES_EX; - *tag++ = 8; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB; - *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB; - - /* We may add an option for custom rates that specific HW might - * support - */ - *tag_p = tag; -} - -static void rtllib_wmm_info(struct rtllib_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0x50; - *tag++ = 0xf2; - *tag++ = 0x02; - *tag++ = 0x00; - *tag++ = 0x01; - *tag++ = MAX_SP_Len; - *tag_p = tag; -} - -static void rtllib_turbo_info(struct rtllib_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0xe0; - *tag++ = 0x4c; - *tag++ = 0x01; - *tag++ = 0x02; - *tag++ = 0x11; - *tag++ = 0x00; - - *tag_p = tag; - netdev_alert(ieee->dev, "This is enable turbo mode IE process\n"); -} - -static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb) -{ - int nh; - - nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM; - -/* if the queue is full but we have newer frames then - * just overwrites the oldest. - * - * if (nh == ieee->mgmt_queue_tail) - * return -1; - */ - ieee->mgmt_queue_head = nh; - ieee->mgmt_queue_ring[nh] = skb; -} - -static void init_mgmt_queue(struct rtllib_device *ieee) -{ - ieee->mgmt_queue_tail = 0; - ieee->mgmt_queue_head = 0; -} - -u8 mgnt_query_tx_rate_exclude_cck_rates(struct rtllib_device *ieee) -{ - u16 i; - u8 query_rate = 0; - u8 basic_rate; - - for (i = 0; i < ieee->current_network.rates_len; i++) { - basic_rate = ieee->current_network.rates[i] & 0x7F; - if (!rtllib_is_cck_rate(basic_rate)) { - if (query_rate == 0) { - query_rate = basic_rate; - } else { - if (basic_rate < query_rate) - query_rate = basic_rate; - } - } - } - - if (query_rate == 0) { - query_rate = 12; - netdev_info(ieee->dev, "No basic_rate found!!\n"); - } - return query_rate; -} - -static u8 mgnt_query_mgnt_frame_tx_rate(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - u8 rate; - - if (ht_info->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M) - rate = 0x0c; - else - rate = ieee->basic_rate & 0x7f; - - if (rate == 0) - rate = 0x02; - - return rate; -} - -inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) -{ - unsigned long flags; - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *)skb->data; - - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd param 0, no mgmt lock required */ - rtllib_sta_wakeup(ieee, 0); - - if (ieee80211_is_beacon(header->frame_control)) - tcb_desc->queue_index = BEACON_QUEUE; - else - tcb_desc->queue_index = MGNT_QUEUE; - - if (ieee->disable_mgnt_queue) - tcb_desc->queue_index = HIGH_QUEUE; - - tcb_desc->data_rate = mgnt_query_mgnt_frame_tx_rate(ieee); - tcb_desc->ratr_index = 7; - tcb_desc->tx_dis_rate_fallback = 1; - tcb_desc->tx_use_drv_assinged_rate = 1; - if (single) { - if (ieee->queue_stop) { - enqueue_mgmt(ieee, skb); - } else { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, - ieee->basic_rate); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - } else { - spin_unlock_irqrestore(&ieee->lock, flags); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); - - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* check whether the managed packet queued greater than 5 */ - if (!ieee->check_nic_enough_desc(ieee->dev, - tcb_desc->queue_index) || - skb_queue_len(&ieee->skb_waitq[tcb_desc->queue_index]) || - ieee->queue_stop) { - /* insert the skb packet to the management queue - * - * as for the completion function, it does not need - * to check it any more. - */ - netdev_info(ieee->dev, - "%s():insert to waitqueue, queue_index:%d!\n", - __func__, tcb_desc->queue_index); - skb_queue_tail(&ieee->skb_waitq[tcb_desc->queue_index], - skb); - } else { - ieee->softmac_hard_start_xmit(skb, ieee->dev); - } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); - } -} - -static inline void -softmac_ps_mgmt_xmit(struct sk_buff *skb, - struct rtllib_device *ieee) -{ - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *)skb->data; - u16 fc, type, stype; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); - - fc = le16_to_cpu(header->frame_control); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - - if (stype != IEEE80211_STYPE_PSPOLL) - tcb_desc->queue_index = MGNT_QUEUE; - else - tcb_desc->queue_index = HIGH_QUEUE; - - if (ieee->disable_mgnt_queue) - tcb_desc->queue_index = HIGH_QUEUE; - - tcb_desc->data_rate = mgnt_query_mgnt_frame_tx_rate(ieee); - tcb_desc->ratr_index = 7; - tcb_desc->tx_dis_rate_fallback = 1; - tcb_desc->tx_use_drv_assinged_rate = 1; - if (single) { - if (type != RTLLIB_FTYPE_CTL) { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, - ieee->basic_rate); - - } else { - if (type != RTLLIB_FTYPE_CTL) { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - ieee->softmac_hard_start_xmit(skb, ieee->dev); - } -} - -static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) -{ - unsigned int len, rate_len; - u8 *tag; - struct sk_buff *skb; - struct rtllib_probe_request *req; - - len = ieee->current_network.ssid_len; - - rate_len = rtllib_MFIE_rate_len(ieee); - - skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) + - 2 + len + rate_len + ieee->tx_headroom); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - req = skb_put(skb, sizeof(struct rtllib_probe_request)); - req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - req->header.duration_id = 0; - - eth_broadcast_addr(req->header.addr1); - ether_addr_copy(req->header.addr2, ieee->dev->dev_addr); - eth_broadcast_addr(req->header.addr3); - - tag = skb_put(skb, len + 2 + rate_len); - - *tag++ = MFIE_TYPE_SSID; - *tag++ = len; - memcpy(tag, ieee->current_network.ssid, len); - tag += len; - - rtllib_mfie_brate(ieee, &tag); - rtllib_mfie_grate(ieee, &tag); - - return skb; -} - -/* Enables network monitor mode, all rx packets will be received. */ -void rtllib_enable_net_monitor_mode(struct net_device *dev, - bool init_state) -{ - struct rtllib_device *ieee = netdev_priv_rsl(dev); - - netdev_info(dev, "========>Enter Monitor Mode\n"); - - ieee->allow_all_dest_addr_handler(dev, true, !init_state); -} - -/* Disables network monitor mode. Only packets destinated to - * us will be received. - */ -void rtllib_disable_net_monitor_mode(struct net_device *dev, bool init_state) -{ - struct rtllib_device *ieee = netdev_priv_rsl(dev); - - netdev_info(dev, "========>Exit Monitor Mode\n"); - - ieee->allow_all_dest_addr_handler(dev, false, !init_state); -} - -static void rtllib_send_probe(struct rtllib_device *ieee) -{ - struct sk_buff *skb; - - skb = rtllib_probe_req(ieee); - if (skb) { - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_probe_rq++; - } -} - -static void rtllib_send_probe_requests(struct rtllib_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ) { - rtllib_send_probe(ieee); - rtllib_send_probe(ieee); - } -} - -/* this performs syncro scan blocking the caller until all channels - * in the allowed channel map has been checked. - */ -static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee) -{ - union iwreq_data wrqu; - short ch = 0; - - ieee->be_scan_inprogress = true; - - mutex_lock(&ieee->scan_mutex); - - while (1) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - goto out; /* scan completed */ - } while (!ieee->active_channel_map[ch]); - - /* this function can be called in two situations - * 1- We have switched to ad-hoc mode and we are - * performing a complete syncro scan before conclude - * there are no interesting cell and to create a - * new one. In this case the link state is - * MAC80211_NOLINK until we found an interesting cell. - * If so the ieee8021_new_net, called by the RX path - * will set the state to MAC80211_LINKED, so we stop - * scanning - * 2- We are linked and the root uses run iwlist scan. - * So we switch to MAC80211_LINKED_SCANNING to remember - * that we are still logically linked (not interested in - * new network events, despite for updating the net list, - * but we are temporarily 'unlinked' as the driver shall - * not filter RX frames and the channel is changing. - * So the only situation in which are interested is to check - * if the state become LINKED because of the #1 situation - */ - - if (ieee->link_state == MAC80211_LINKED) - goto out; - if (ieee->sync_scan_hurryup) { - netdev_info(ieee->dev, - "============>sync_scan_hurryup out\n"); - goto out; - } - - ieee->set_chan(ieee->dev, ch); - if (ieee->active_channel_map[ch] == 1) - rtllib_send_probe_requests(ieee); - - /* this prevent excessive time wait when we - * need to wait for a syncro scan to end.. - */ - msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME); - } -out: - ieee->actscanning = false; - ieee->sync_scan_hurryup = 0; - - mutex_unlock(&ieee->scan_mutex); - - ieee->be_scan_inprogress = false; - - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL); -} - -static void rtllib_softmac_scan_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, softmac_scan_wq); - u8 last_channel = ieee->current_network.channel; - - if (!ieee->ieee_up) - return; - if (rtllib_act_scanning(ieee, true)) - return; - - mutex_lock(&ieee->scan_mutex); - - if (ieee->rf_power_state == rf_off) { - netdev_info(ieee->dev, - "======>%s():rf state is rf_off, return\n", - __func__); - goto out1; - } - - do { - ieee->current_network.channel = - (ieee->current_network.channel + 1) % - MAX_CHANNEL_NUMBER; - if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) { - if (!ieee->active_channel_map[ieee->current_network.channel]) - ieee->current_network.channel = 6; - goto out; /* no good chans */ - } - } while (!ieee->active_channel_map[ieee->current_network.channel]); - - if (ieee->scanning_continue == 0) - goto out; - - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - if (ieee->active_channel_map[ieee->current_network.channel] == 1) - rtllib_send_probe_requests(ieee); - - schedule_delayed_work(&ieee->softmac_scan_wq, - msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME)); - - mutex_unlock(&ieee->scan_mutex); - return; - -out: - ieee->current_network.channel = last_channel; - -out1: - ieee->actscanning = false; - ieee->scan_watch_dog = 0; - ieee->scanning_continue = 0; - mutex_unlock(&ieee->scan_mutex); -} - -static void rtllib_softmac_stop_scan(struct rtllib_device *ieee) -{ - mutex_lock(&ieee->scan_mutex); - ieee->scan_watch_dog = 0; - if (ieee->scanning_continue == 1) { - ieee->scanning_continue = 0; - ieee->actscanning = false; - mutex_unlock(&ieee->scan_mutex); - cancel_delayed_work_sync(&ieee->softmac_scan_wq); - } else { - mutex_unlock(&ieee->scan_mutex); - } -} - -void rtllib_stop_scan(struct rtllib_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - rtllib_softmac_stop_scan(ieee); -} -EXPORT_SYMBOL(rtllib_stop_scan); - -void rtllib_stop_scan_syncro(struct rtllib_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee->sync_scan_hurryup = 1; -} -EXPORT_SYMBOL(rtllib_stop_scan_syncro); - -bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { - if (sync_scan) - return ieee->be_scan_inprogress; - else - return ieee->actscanning || ieee->be_scan_inprogress; - } else { - return test_bit(STATUS_SCANNING, &ieee->status); - } -} -EXPORT_SYMBOL(rtllib_act_scanning); - -/* called with ieee->lock held */ -static void rtllib_start_scan(struct rtllib_device *ieee) -{ - ieee->rtllib_ips_leave_wq(ieee->dev); - - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { - if (ieee->scanning_continue == 0) { - ieee->actscanning = true; - ieee->scanning_continue = 1; - schedule_delayed_work(&ieee->softmac_scan_wq, 0); - } - } -} - -/* called with wx_mutex held */ -void rtllib_start_scan_syncro(struct rtllib_device *ieee) -{ - ieee->sync_scan_hurryup = 0; - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - rtllib_softmac_scan_syncro(ieee); -} -EXPORT_SYMBOL(rtllib_start_scan_syncro); - -static inline struct sk_buff * -rtllib_authentication_req(struct rtllib_network *beacon, - struct rtllib_device *ieee, - int challengelen, u8 *daddr) -{ - struct sk_buff *skb; - struct rtllib_authentication *auth; - int len; - - len = sizeof(struct rtllib_authentication) + challengelen + - ieee->tx_headroom + 4; - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - auth = skb_put(skb, sizeof(struct rtllib_authentication)); - - auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH); - if (challengelen) - auth->header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); - - auth->header.duration_id = cpu_to_le16(0x013a); - ether_addr_copy(auth->header.addr1, beacon->bssid); - ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr); - ether_addr_copy(auth->header.addr3, beacon->bssid); - if (ieee->auth_mode == 0) - auth->algorithm = WLAN_AUTH_OPEN; - else if (ieee->auth_mode == 1) - auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY); - else if (ieee->auth_mode == 2) - auth->algorithm = WLAN_AUTH_OPEN; - auth->transaction = cpu_to_le16(ieee->associate_seq); - ieee->associate_seq++; - - auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); - - return skb; -} - -static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr) -{ - struct sk_buff *skb; - struct ieee80211_hdr_3addr *hdr; - - skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr) + ieee->tx_headroom); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - hdr = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); - - ether_addr_copy(hdr->addr1, ieee->current_network.bssid); - ether_addr_copy(hdr->addr2, ieee->dev->dev_addr); - ether_addr_copy(hdr->addr3, ieee->current_network.bssid); - - hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_DATA | - IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | - (pwr ? IEEE80211_FCTL_PM : 0)); - - return skb; -} - -static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_pspoll *hdr; - - skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll) + ieee->tx_headroom); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - hdr = skb_put(skb, sizeof(struct ieee80211_pspoll)); - - ether_addr_copy(hdr->bssid, ieee->current_network.bssid); - ether_addr_copy(hdr->ta, ieee->dev->dev_addr); - - hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); - hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | - IEEE80211_FCTL_PM); - - return skb; -} - -static inline int sec_is_in_pmkid_list(struct rtllib_device *ieee, u8 *bssid) -{ - int i = 0; - - do { - if ((ieee->pmkid_list[i].used) && - (memcmp(ieee->pmkid_list[i].bssid, bssid, ETH_ALEN) == 0)) - break; - i++; - } while (i < NUM_PMKID_CACHE); - - if (i == NUM_PMKID_CACHE) - i = -1; - return i; -} - -static inline struct sk_buff * -rtllib_association_req(struct rtllib_network *beacon, - struct rtllib_device *ieee) -{ - struct sk_buff *skb; - struct rtllib_assoc_request_frame *hdr; - u8 *tag, *ies; - int i; - u8 *ht_cap_buf = NULL; - u8 ht_cap_len = 0; - u8 *realtek_ie_buf = NULL; - u8 realtek_ie_len = 0; - int wpa_ie_len = ieee->wpa_ie_len; - int wps_ie_len = ieee->wps_ie_len; - unsigned int ckip_ie_len = 0; - unsigned int ccxrm_ie_len = 0; - unsigned int cxvernum_ie_len = 0; - struct lib80211_crypt_data *crypt; - int encrypt; - int pmk_cache_idx; - - unsigned int rate_len = (beacon->rates_len ? - (beacon->rates_len + 2) : 0) + - (beacon->rates_ex_len ? (beacon->rates_ex_len) + - 2 : 0); - - unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0; - unsigned int turbo_info_len = beacon->turbo_enable ? 9 : 0; - - int len = 0; - - crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - if (crypt) - encrypt = crypt && crypt->ops && - ((strcmp(crypt->ops->name, "R-WEP") == 0 || - wpa_ie_len)); - else - encrypt = 0; - - if ((ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) || - ieee->forced_bg_mode) { - ieee->ht_info->enable_ht = 0; - ieee->mode = WIRELESS_MODE_G; - } - - if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { - ht_cap_buf = (u8 *)&ieee->ht_info->self_ht_cap; - ht_cap_len = sizeof(ieee->ht_info->self_ht_cap); - ht_construct_capability_element(ieee, ht_cap_buf, &ht_cap_len, - encrypt, true); - if (ieee->ht_info->current_rt2rt_aggregation) { - realtek_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf; - realtek_ie_len = - sizeof(ieee->ht_info->sz_rt2rt_agg_buf); - ht_construct_rt2rt_agg_element(ieee, realtek_ie_buf, - &realtek_ie_len); - } - } - - if (beacon->ckip_supported) - ckip_ie_len = 30 + 2; - if (beacon->ccx_rm_enable) - ccxrm_ie_len = 6 + 2; - if (beacon->bss_ccx_ver_number >= 2) - cxvernum_ie_len = 5 + 2; - - pmk_cache_idx = sec_is_in_pmkid_list(ieee, ieee->current_network.bssid); - if (pmk_cache_idx >= 0) { - wpa_ie_len += 18; - netdev_info(ieee->dev, "[PMK cache]: WPA2 IE length: %x\n", - wpa_ie_len); - } - len = sizeof(struct rtllib_assoc_request_frame) + 2 - + beacon->ssid_len - + rate_len - + wpa_ie_len - + wps_ie_len - + wmm_info_len - + turbo_info_len - + ht_cap_len - + realtek_ie_len - + ckip_ie_len - + ccxrm_ie_len - + cxvernum_ie_len - + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2); - - hdr->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ); - hdr->header.duration_id = cpu_to_le16(37); - ether_addr_copy(hdr->header.addr1, beacon->bssid); - ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr); - ether_addr_copy(hdr->header.addr3, beacon->bssid); - - ether_addr_copy(ieee->ap_mac_addr, beacon->bssid); - - hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS); - if (beacon->capability & WLAN_CAPABILITY_PRIVACY) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); - - if (beacon->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); - - hdr->listen_interval = cpu_to_le16(beacon->listen_interval); - - hdr->info_element[0].id = MFIE_TYPE_SSID; - - hdr->info_element[0].len = beacon->ssid_len; - skb_put_data(skb, beacon->ssid, beacon->ssid_len); - - tag = skb_put(skb, rate_len); - - if (beacon->rates_len) { - *tag++ = MFIE_TYPE_RATES; - *tag++ = beacon->rates_len; - for (i = 0; i < beacon->rates_len; i++) - *tag++ = beacon->rates[i]; - } - - if (beacon->rates_ex_len) { - *tag++ = MFIE_TYPE_RATES_EX; - *tag++ = beacon->rates_ex_len; - for (i = 0; i < beacon->rates_ex_len; i++) - *tag++ = beacon->rates_ex[i]; - } - - if (beacon->ckip_supported) { - static const u8 aironet_ie_oui[] = {0x00, 0x01, 0x66}; - u8 ccx_aironet_buf[30]; - struct octet_string os_ccx_aironet_ie; - - memset(ccx_aironet_buf, 0, 30); - os_ccx_aironet_ie.octet = ccx_aironet_buf; - os_ccx_aironet_ie.Length = sizeof(ccx_aironet_buf); - memcpy(os_ccx_aironet_ie.octet, aironet_ie_oui, - sizeof(aironet_ie_oui)); - - os_ccx_aironet_ie.octet[IE_CISCO_FLAG_POSITION] |= - (SUPPORT_CKIP_PK | SUPPORT_CKIP_MIC); - tag = skb_put(skb, ckip_ie_len); - *tag++ = MFIE_TYPE_AIRONET; - *tag++ = os_ccx_aironet_ie.Length; - memcpy(tag, os_ccx_aironet_ie.octet, os_ccx_aironet_ie.Length); - tag += os_ccx_aironet_ie.Length; - } - - if (beacon->ccx_rm_enable) { - static const u8 ccx_rm_cap_buf[] = {0x00, 0x40, 0x96, 0x01, 0x01, - 0x00}; - struct octet_string os_ccx_rm_cap; - - os_ccx_rm_cap.octet = (u8 *)ccx_rm_cap_buf; - os_ccx_rm_cap.Length = sizeof(ccx_rm_cap_buf); - tag = skb_put(skb, ccxrm_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = os_ccx_rm_cap.Length; - memcpy(tag, os_ccx_rm_cap.octet, os_ccx_rm_cap.Length); - tag += os_ccx_rm_cap.Length; - } - - if (beacon->bss_ccx_ver_number >= 2) { - u8 ccx_ver_num_buf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; - struct octet_string os_ccx_ver_num; - - ccx_ver_num_buf[4] = beacon->bss_ccx_ver_number; - os_ccx_ver_num.octet = ccx_ver_num_buf; - os_ccx_ver_num.Length = sizeof(ccx_ver_num_buf); - tag = skb_put(skb, cxvernum_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = os_ccx_ver_num.Length; - memcpy(tag, os_ccx_ver_num.octet, os_ccx_ver_num.Length); - tag += os_ccx_ver_num.Length; - } - if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { - if (ieee->ht_info->peer_ht_spec_ver != HT_SPEC_VER_EWC) { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_HT_CAP; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf, ht_cap_len - 2); - tag += ht_cap_len - 2; - } - } - - if (wpa_ie_len) { - skb_put_data(skb, ieee->wpa_ie, ieee->wpa_ie_len); - - if (pmk_cache_idx >= 0) { - tag = skb_put(skb, 18); - *tag = 1; - *(tag + 1) = 0; - memcpy((tag + 2), &ieee->pmkid_list[pmk_cache_idx].PMKID, - 16); - } - } - if (wmm_info_len) { - tag = skb_put(skb, wmm_info_len); - rtllib_wmm_info(ieee, &tag); - } - - if (wps_ie_len && ieee->wps_ie) - skb_put_data(skb, ieee->wps_ie, wps_ie_len); - - if (turbo_info_len) { - tag = skb_put(skb, turbo_info_len); - rtllib_turbo_info(ieee, &tag); - } - - if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { - if (ieee->ht_info->peer_ht_spec_ver == HT_SPEC_VER_EWC) { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf, ht_cap_len - 2); - tag += ht_cap_len - 2; - } - - if (ieee->ht_info->current_rt2rt_aggregation) { - tag = skb_put(skb, realtek_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = realtek_ie_len - 2; - memcpy(tag, realtek_ie_buf, realtek_ie_len - 2); - } - } - - kfree(ieee->assocreq_ies); - ieee->assocreq_ies = NULL; - ies = &hdr->info_element[0].id; - ieee->assocreq_ies_len = (skb->data + skb->len) - ies; - ieee->assocreq_ies = kmemdup(ies, ieee->assocreq_ies_len, GFP_ATOMIC); - if (!ieee->assocreq_ies) - ieee->assocreq_ies_len = 0; - - return skb; -} - -static void rtllib_associate_abort(struct rtllib_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - - ieee->associate_seq++; - - /* don't scan, and avoid to have the RX path possibly - * try again to associate. Even do not react to AUTH or - * ASSOC response. Just wait for the retry wq to be scheduled. - * Here we will check if there are good nets to associate - * with, so we retry or just get back to NO_LINK and scanning - */ - if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING) { - netdev_dbg(ieee->dev, "Authentication failed\n"); - ieee->softmac_stats.no_auth_rs++; - } else { - netdev_dbg(ieee->dev, "Association failed\n"); - ieee->softmac_stats.no_ass_rs++; - } - - ieee->link_state = RTLLIB_ASSOCIATING_RETRY; - - schedule_delayed_work(&ieee->associate_retry_wq, - RTLLIB_SOFTMAC_ASSOC_RETRY_TIME); - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static void rtllib_associate_abort_cb(struct timer_list *t) -{ - struct rtllib_device *dev = from_timer(dev, t, associate_timer); - - rtllib_associate_abort(dev); -} - -static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr) -{ - struct rtllib_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - netdev_dbg(ieee->dev, "Stopping scan\n"); - - ieee->softmac_stats.tx_auth_rq++; - - skb = rtllib_authentication_req(beacon, ieee, 0, daddr); - - if (!skb) { - rtllib_associate_abort(ieee); - } else { - ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATING; - netdev_dbg(ieee->dev, "Sending authentication request\n"); - softmac_mgmt_xmit(skb, ieee); - if (!timer_pending(&ieee->associate_timer)) { - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - } -} - -static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, - int chlen) -{ - u8 *c; - struct sk_buff *skb; - struct rtllib_network *beacon = &ieee->current_network; - - ieee->associate_seq++; - ieee->softmac_stats.tx_auth_rq++; - - skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid); - - if (!skb) { - rtllib_associate_abort(ieee); - } else { - c = skb_put(skb, chlen + 2); - *(c++) = MFIE_TYPE_CHALLENGE; - *(c++) = chlen; - memcpy(c, challenge, chlen); - - netdev_dbg(ieee->dev, - "Sending authentication challenge response\n"); - - rtllib_encrypt_fragment(ieee, skb, - sizeof(struct ieee80211_hdr_3addr)); - - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ / 2)); - } - kfree(challenge); -} - -static void rtllib_associate_step2(struct rtllib_device *ieee) -{ - struct sk_buff *skb; - struct rtllib_network *beacon = &ieee->current_network; - - del_timer_sync(&ieee->associate_timer); - - netdev_dbg(ieee->dev, "Sending association request\n"); - - ieee->softmac_stats.tx_ass_rq++; - skb = rtllib_association_req(beacon, ieee); - if (!skb) { - rtllib_associate_abort(ieee); - } else { - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ / 2)); - } -} - -static void rtllib_associate_complete_wq(void *data) -{ - struct rtllib_device *ieee = (struct rtllib_device *) - container_of(data, - struct rtllib_device, - associate_complete_wq); - struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl; - - netdev_info(ieee->dev, "Associated successfully with %pM\n", - ieee->current_network.bssid); - netdev_info(ieee->dev, "normal associate\n"); - notify_wx_assoc_event(ieee); - - netif_carrier_on(ieee->dev); - ieee->is_roaming = false; - if (rtllib_is_54g(&ieee->current_network)) { - ieee->rate = 108; - netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate); - } else { - ieee->rate = 22; - ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B); - netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate); - } - if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { - netdev_info(ieee->dev, "Successfully associated, ht enabled\n"); - ht_on_assoc_rsp(ieee); - } else { - netdev_info(ieee->dev, - "Successfully associated, ht not enabled(%d, %d)\n", - ieee->ht_info->current_ht_support, - ieee->ht_info->enable_ht); - memset(ieee->dot11ht_oper_rate_set, 0, 16); - } - ieee->link_detect_info.slot_num = 2 * (1 + - ieee->current_network.beacon_interval / - 500); - if (ieee->link_detect_info.num_recv_bcn_in_period == 0 || - ieee->link_detect_info.num_recv_data_in_period == 0) { - ieee->link_detect_info.num_recv_bcn_in_period = 1; - ieee->link_detect_info.num_recv_data_in_period = 1; - } - psc->lps_idle_count = 0; - ieee->link_change(ieee->dev); -} - -static void rtllib_sta_send_associnfo(struct rtllib_device *ieee) -{ -} - -static void rtllib_associate_complete(struct rtllib_device *ieee) -{ - del_timer_sync(&ieee->associate_timer); - - ieee->link_state = MAC80211_LINKED; - rtllib_sta_send_associnfo(ieee); - - schedule_work(&ieee->associate_complete_wq); -} - -static void rtllib_associate_procedure_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, - associate_procedure_wq); - rtllib_stop_scan_syncro(ieee); - ieee->rtllib_ips_leave(ieee->dev); - mutex_lock(&ieee->wx_mutex); - - rtllib_stop_scan(ieee); - ht_set_connect_bw_mode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - if (ieee->rf_power_state == rf_off) { - ieee->rtllib_ips_leave_wq(ieee->dev); - mutex_unlock(&ieee->wx_mutex); - return; - } - ieee->associate_seq = 1; - - rtllib_associate_step1(ieee, ieee->current_network.bssid); - - mutex_unlock(&ieee->wx_mutex); -} - -inline void rtllib_softmac_new_net(struct rtllib_device *ieee, - struct rtllib_network *net) -{ - u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1]; - int tmp_ssid_len = 0; - - short apset, ssidset, ssidbroad, apmatch, ssidmatch; - - /* we are interested in new only if we are not associated - * and we are not associating / authenticating - */ - if (ieee->link_state != MAC80211_NOLINK) - return; - - if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & - WLAN_CAPABILITY_ESS)) - return; - - if (ieee->iw_mode == IW_MODE_INFRA) { - /* if the user specified the AP MAC, we need also the essid - * This could be obtained by beacons or, if the network does not - * broadcast it, it can be put manually. - */ - apset = ieee->wap_set; - ssidset = ieee->ssid_set; - ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0'); - apmatch = (memcmp(ieee->current_network.bssid, net->bssid, - ETH_ALEN) == 0); - if (!ssidbroad) { - ssidmatch = (ieee->current_network.ssid_len == - net->hidden_ssid_len) && - (!strncmp(ieee->current_network.ssid, - net->hidden_ssid, net->hidden_ssid_len)); - if (net->hidden_ssid_len > 0) { - strncpy(net->ssid, net->hidden_ssid, - net->hidden_ssid_len); - net->ssid_len = net->hidden_ssid_len; - ssidbroad = 1; - } - } else { - ssidmatch = - (ieee->current_network.ssid_len == net->ssid_len) && - (!strncmp(ieee->current_network.ssid, net->ssid, - net->ssid_len)); - } - - /* if the user set the AP check if match. - * if the network does not broadcast essid we check the - * user supplied ANY essid - * if the network does broadcast and the user does not set - * essid it is OK - * if the network does broadcast and the user did set essid - * check if essid match - * if the ap is not set, check that the user set the bssid - * and the network does broadcast and that those two bssid match - */ - if ((apset && apmatch && - ((ssidset && ssidbroad && ssidmatch) || - (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) || - (!apset && ssidset && ssidbroad && ssidmatch) || - (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) { - /* Save the essid so that if it is hidden, it is - * replaced with the essid provided by the user. - */ - if (!ssidbroad) { - memcpy(tmp_ssid, ieee->current_network.ssid, - ieee->current_network.ssid_len); - tmp_ssid_len = ieee->current_network.ssid_len; - } - memcpy(&ieee->current_network, net, - sizeof(ieee->current_network)); - if (!ssidbroad) { - memcpy(ieee->current_network.ssid, tmp_ssid, - tmp_ssid_len); - ieee->current_network.ssid_len = tmp_ssid_len; - } - netdev_info(ieee->dev, - "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n", - ieee->current_network.ssid, - ieee->current_network.channel, - ieee->current_network.qos_data.supported, - ieee->ht_info->enable_ht, - ieee->current_network.bssht.bd_support_ht, - ieee->current_network.mode, - ieee->current_network.flags); - - if ((rtllib_act_scanning(ieee, false)) && - !(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) - rtllib_stop_scan_syncro(ieee); - - ht_reset_iot_setting(ieee->ht_info); - ieee->wmm_acm = 0; - if (ieee->iw_mode == IW_MODE_INFRA) { - /* Join the network for the first time */ - ieee->asoc_retry_count = 0; - if ((ieee->current_network.qos_data.supported == 1) && - ieee->current_network.bssht.bd_support_ht) - ht_reset_self_and_save_peer_setting(ieee, - &ieee->current_network); - else - ieee->ht_info->current_ht_support = false; - - ieee->link_state = RTLLIB_ASSOCIATING; - schedule_delayed_work(&ieee->associate_procedure_wq, 0); - } else { - if (rtllib_is_54g(&ieee->current_network)) { - ieee->rate = 108; - ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G); - netdev_info(ieee->dev, - "Using G rates\n"); - } else { - ieee->rate = 22; - ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B); - netdev_info(ieee->dev, - "Using B rates\n"); - } - memset(ieee->dot11ht_oper_rate_set, 0, 16); - ieee->link_state = MAC80211_LINKED; - } - } - } -} - -static void rtllib_softmac_check_all_nets(struct rtllib_device *ieee) -{ - unsigned long flags; - struct rtllib_network *target; - - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(target, &ieee->network_list, list) { - /* if the state become different that NOLINK means - * we had found what we are searching for - */ - - if (ieee->link_state != MAC80211_NOLINK) - break; - - if (ieee->scan_age == 0 || time_after(target->last_scanned + - ieee->scan_age, jiffies)) - rtllib_softmac_new_net(ieee, target); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static inline int auth_parse(struct net_device *dev, struct sk_buff *skb, - u8 **challenge, int *chlen) -{ - struct rtllib_authentication *a; - u8 *t; - - if (skb->len < (sizeof(struct rtllib_authentication) - - sizeof(struct rtllib_info_element))) { - netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len); - return -EINVAL; - } - *challenge = NULL; - a = (struct rtllib_authentication *)skb->data; - if (skb->len > (sizeof(struct rtllib_authentication) + 3)) { - t = skb->data + sizeof(struct rtllib_authentication); - - if (*(t++) == MFIE_TYPE_CHALLENGE) { - *chlen = *(t++); - *challenge = kmemdup(t, *chlen, GFP_ATOMIC); - if (!*challenge) - return -ENOMEM; - } - } - - if (a->status) { - netdev_dbg(dev, "auth_parse() failed\n"); - return -EINVAL; - } - - return 0; -} - -static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, - int *aid) -{ - struct rtllib_assoc_response_frame *response_head; - u16 status_code; - - if (skb->len < sizeof(struct rtllib_assoc_response_frame)) { - netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n", - skb->len); - return 0xcafe; - } - - response_head = (struct rtllib_assoc_response_frame *)skb->data; - *aid = le16_to_cpu(response_head->aid) & 0x3fff; - - status_code = le16_to_cpu(response_head->status); - if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES || - status_code == WLAN_STATUS_CAPS_UNSUPPORTED) && - ((ieee->mode == WIRELESS_MODE_G) && - (ieee->current_network.mode == WIRELESS_MODE_N_24G) && - (ieee->asoc_retry_count++ < (RT_ASOC_RETRY_LIMIT - 1)))) { - ieee->ht_info->iot_action |= HT_IOT_ACT_PURE_N_MODE; - } else { - ieee->asoc_retry_count = 0; - } - - return le16_to_cpu(response_head->status); -} - -void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr) -{ - struct sk_buff *buf = rtllib_null_func(ieee, pwr); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); -} -EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame); - -void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee) -{ - struct sk_buff *buf = rtllib_pspoll_func(ieee); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); -} - -static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) -{ - int timeout; - u8 dtim; - struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl; - - if (ieee->lps_delay_cnt) { - ieee->lps_delay_cnt--; - return 0; - } - - dtim = ieee->current_network.dtim_data; - if (!(dtim & RTLLIB_DTIM_VALID)) - return 0; - timeout = ieee->current_network.beacon_interval; - ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID; - /* there's no need to notify AP that I find you buffered - * with broadcast packet - */ - if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps)) - return 2; - - if (!time_after(jiffies, - dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout))) - return 0; - if (!time_after(jiffies, - ieee->last_rx_ps_time + msecs_to_jiffies(timeout))) - return 0; - if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) && - (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) - return 0; - - if (time) { - if (ieee->awake_pkt_sent) { - psc->lps_awake_intvl = 1; - } else { - u8 max_period = 5; - - if (psc->lps_awake_intvl == 0) - psc->lps_awake_intvl = 1; - psc->lps_awake_intvl = (psc->lps_awake_intvl >= - max_period) ? max_period : - (psc->lps_awake_intvl + 1); - } - { - u8 lps_awake_intvl_tmp = 0; - u8 period = ieee->current_network.dtim_period; - u8 count = ieee->current_network.tim.tim_count; - - if (count == 0) { - if (psc->lps_awake_intvl > period) - lps_awake_intvl_tmp = period + - (psc->lps_awake_intvl - - period) - - ((psc->lps_awake_intvl - period) % - period); - else - lps_awake_intvl_tmp = psc->lps_awake_intvl; - - } else { - if (psc->lps_awake_intvl > - ieee->current_network.tim.tim_count) - lps_awake_intvl_tmp = count + - (psc->lps_awake_intvl - count) - - ((psc->lps_awake_intvl - count) % period); - else - lps_awake_intvl_tmp = psc->lps_awake_intvl; - } - - *time = ieee->current_network.last_dtim_sta_time - + msecs_to_jiffies(ieee->current_network.beacon_interval * - lps_awake_intvl_tmp); - } - } - - return 1; -} - -static inline void rtllib_sta_ps(struct work_struct *work) -{ - struct rtllib_device *ieee; - u64 time; - short sleep; - unsigned long flags, flags2; - - ieee = container_of(work, struct rtllib_device, ps_task); - - spin_lock_irqsave(&ieee->lock, flags); - - if ((ieee->ps == RTLLIB_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->link_state != MAC80211_LINKED)) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - rtllib_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - sleep = rtllib_sta_ps_sleep(ieee, &time); - /* 2 wake, 1 sleep, 0 do nothing */ - if (sleep == 0) - goto out; - if (sleep == 1) { - if (ieee->sta_sleep == LPS_IS_SLEEP) { - ieee->enter_sleep_state(ieee->dev, time); - } else if (ieee->sta_sleep == LPS_IS_WAKE) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - if (ieee->ps_is_queue_empty(ieee->dev)) { - ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND; - ieee->ack_tx_to_ieee = 1; - rtllib_sta_ps_send_null_frame(ieee, 1); - ieee->ps_time = time; - } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - - ieee->awake_pkt_sent = false; - - } else if (sleep == 2) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - rtllib_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - -out: - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl) -{ - if (ieee->sta_sleep == LPS_IS_WAKE) { - if (nl) { - if (ieee->ht_info->iot_action & - HT_IOT_ACT_NULL_DATA_POWER_SAVING) { - ieee->ack_tx_to_ieee = 1; - rtllib_sta_ps_send_null_frame(ieee, 0); - } else { - ieee->ack_tx_to_ieee = 1; - rtllib_sta_ps_send_pspoll_frame(ieee); - } - } - return; - } - - if (ieee->sta_sleep == LPS_IS_SLEEP) - ieee->sta_wake_up(ieee->dev); - if (nl) { - if (ieee->ht_info->iot_action & - HT_IOT_ACT_NULL_DATA_POWER_SAVING) { - ieee->ack_tx_to_ieee = 1; - rtllib_sta_ps_send_null_frame(ieee, 0); - } else { - ieee->ack_tx_to_ieee = 1; - ieee->polling = true; - rtllib_sta_ps_send_pspoll_frame(ieee); - } - - } else { - ieee->sta_sleep = LPS_IS_WAKE; - ieee->polling = false; - } -} - -void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success) -{ - unsigned long flags, flags2; - - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) { - /* Null frame with PS bit set */ - if (success) { - ieee->sta_sleep = LPS_IS_SLEEP; - ieee->enter_sleep_state(ieee->dev, ieee->ps_time); - } - /* if the card report not success we can't be sure the AP - * has not RXed so we can't assume the AP believe us awake - */ - } else {/* 21112005 - tx again null without PS bit if lost */ - - if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - if (ieee->ht_info->iot_action & - HT_IOT_ACT_NULL_DATA_POWER_SAVING) - rtllib_sta_ps_send_null_frame(ieee, 0); - else - rtllib_sta_ps_send_pspoll_frame(ieee); - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(rtllib_ps_tx_ack); - -static void rtllib_process_action(struct rtllib_device *ieee, - struct sk_buff *skb) -{ - u8 *act = skb->data + RTLLIB_3ADDR_LEN; - u8 category = 0; - - category = *act; - act++; - switch (category) { - case ACT_CAT_BA: - switch (*act) { - case ACT_ADDBAREQ: - rtllib_rx_add_ba_req(ieee, skb); - break; - case ACT_ADDBARSP: - rtllib_rx_add_ba_rsp(ieee, skb); - break; - case ACT_DELBA: - rtllib_rx_DELBA(ieee, skb); - break; - } - break; - default: - break; - } -} - -static inline int -rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - u16 errcode; - int aid; - u8 *ies; - struct rtllib_assoc_response_frame *assoc_resp; - struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; - u16 frame_ctl = le16_to_cpu(header->frame_control); - - netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(frame_ctl)); - - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATED && - (ieee->iw_mode == IW_MODE_INFRA)) { - errcode = assoc_parse(ieee, skb, &aid); - if (!errcode) { - struct rtllib_network *network = - kzalloc(sizeof(struct rtllib_network), - GFP_ATOMIC); - - if (!network) - return 1; - ieee->link_state = MAC80211_LINKED; - ieee->assoc_id = aid; - ieee->softmac_stats.rx_ass_ok++; - /* station support qos */ - /* Let the register setting default with Legacy station */ - assoc_resp = (struct rtllib_assoc_response_frame *)skb->data; - if (ieee->current_network.qos_data.supported == 1) { - if (rtllib_parse_info_param(ieee, assoc_resp->info_element, - rx_stats->len - sizeof(*assoc_resp), - network, rx_stats)) { - kfree(network); - return 1; - } - memcpy(ieee->ht_info->peer_ht_cap_buf, - network->bssht.bd_ht_cap_buf, - network->bssht.bd_ht_cap_len); - memcpy(ieee->ht_info->peer_ht_info_buf, - network->bssht.bd_ht_info_buf, - network->bssht.bd_ht_info_len); - ieee->handle_assoc_response(ieee->dev, - (struct rtllib_assoc_response_frame *)header, network); - } - kfree(network); - - kfree(ieee->assocresp_ies); - ieee->assocresp_ies = NULL; - ies = &assoc_resp->info_element[0].id; - ieee->assocresp_ies_len = (skb->data + skb->len) - ies; - ieee->assocresp_ies = kmemdup(ies, - ieee->assocresp_ies_len, - GFP_ATOMIC); - if (!ieee->assocresp_ies) - ieee->assocresp_ies_len = 0; - - rtllib_associate_complete(ieee); - } else { - /* aid could not been allocated */ - ieee->softmac_stats.rx_ass_err++; - netdev_info(ieee->dev, - "Association response status code 0x%x\n", - errcode); - if (ieee->asoc_retry_count < RT_ASOC_RETRY_LIMIT) - schedule_delayed_work(&ieee->associate_procedure_wq, 0); - else - rtllib_associate_abort(ieee); - } - } - return 0; -} - -static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb) -{ - int errcode; - u8 *challenge; - int chlen = 0; - bool support_nmode = true, half_support_nmode = false; - - errcode = auth_parse(ieee->dev, skb, &challenge, &chlen); - - if (errcode) { - ieee->softmac_stats.rx_auth_rs_err++; - netdev_info(ieee->dev, - "Authentication response status code %d", errcode); - rtllib_associate_abort(ieee); - return; - } - - if (ieee->open_wep || !challenge) { - ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATED; - ieee->softmac_stats.rx_auth_rs_ok++; - if (!(ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE)) { - if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev)) { - if (is_ht_half_nmode_aps(ieee)) { - support_nmode = true; - half_support_nmode = true; - } else { - support_nmode = false; - half_support_nmode = false; - } - } - } - /* Dummy wirless mode setting to avoid encryption issue */ - if (support_nmode) { - ieee->set_wireless_mode(ieee->dev, - ieee->current_network.mode); - } else { - /*TODO*/ - ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G); - } - - if ((ieee->current_network.mode == WIRELESS_MODE_N_24G) && - half_support_nmode) { - netdev_info(ieee->dev, "======>enter half N mode\n"); - ieee->half_wireless_n24g_mode = true; - } else { - ieee->half_wireless_n24g_mode = false; - } - rtllib_associate_step2(ieee); - } else { - rtllib_auth_challenge(ieee, challenge, chlen); - } -} - -static inline int -rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) { - if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING && - (ieee->iw_mode == IW_MODE_INFRA)) { - netdev_dbg(ieee->dev, - "Received authentication response"); - rtllib_rx_auth_resp(ieee, skb); - } - } - return 0; -} - -static inline int -rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; - u16 frame_ctl; - - if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) - return 0; - - /* FIXME for now repeat all the association procedure - * both for disassociation and deauthentication - */ - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->link_state == MAC80211_LINKED && - (ieee->iw_mode == IW_MODE_INFRA)) { - frame_ctl = le16_to_cpu(header->frame_control); - netdev_info(ieee->dev, - "==========>received disassoc/deauth(%x) frame, reason code:%x\n", - WLAN_FC_GET_STYPE(frame_ctl), - ((struct rtllib_disassoc *)skb->data)->reason); - ieee->link_state = RTLLIB_ASSOCIATING; - ieee->softmac_stats.reassoc++; - ieee->is_roaming = true; - ieee->link_detect_info.busy_traffic = false; - rtllib_disassociate(ieee); - remove_peer_ts(ieee, header->addr2); - if (!(ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_CCMP | SEC_ALG_TKIP))) - schedule_delayed_work(&ieee->associate_procedure_wq, 5); - } - return 0; -} - -inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, - struct sk_buff *skb, - struct rtllib_rx_stats *rx_stats, u16 type, - u16 stype) -{ - struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; - u16 frame_ctl; - - if (!ieee->proto_started) - return 0; - - frame_ctl = le16_to_cpu(header->frame_control); - switch (WLAN_FC_GET_STYPE(frame_ctl)) { - case IEEE80211_STYPE_ASSOC_RESP: - case IEEE80211_STYPE_REASSOC_RESP: - if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1) - return 1; - break; - case IEEE80211_STYPE_ASSOC_REQ: - case IEEE80211_STYPE_REASSOC_REQ: - break; - case IEEE80211_STYPE_AUTH: - rtllib_rx_auth(ieee, skb, rx_stats); - break; - case IEEE80211_STYPE_DISASSOC: - case IEEE80211_STYPE_DEAUTH: - rtllib_rx_deauth(ieee, skb); - break; - case IEEE80211_STYPE_ACTION: - rtllib_process_action(ieee, skb); - break; - default: - return -1; - } - return 0; -} - -/* following are for a simpler TX queue management. - * Instead of using netif_[stop/wake]_queue the driver - * will use these two functions (plus a reset one), that - * will internally use the kernel netif_* and takes - * care of the ieee802.11 fragmentation. - * So the driver receives a fragment per time and might - * call the stop function when it wants to not - * have enough room to TX an entire packet. - * This might be useful if each fragment needs it's own - * descriptor, thus just keep a total free memory > than - * the max fragmentation threshold is not enough.. If the - * ieee802.11 stack passed a TXB struct then you need - * to keep N free descriptors where - * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD - * In this way you need just one and the 802.11 stack - * will take care of buffering fragments and pass them to - * the driver later, when it wakes the queue. - */ -void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee) -{ - unsigned int queue_index = txb->queue_index; - unsigned long flags; - int i; - struct cb_desc *tcb_desc = NULL; - unsigned long queue_len = 0; - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd param 0, no tx mgmt lock required */ - rtllib_sta_wakeup(ieee, 0); - - /* update the tx status */ - tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + - MAX_DEV_ADDR_SIZE); - if (tcb_desc->multicast) - ieee->stats.multicast++; - - /* if xmit available, just xmit it immediately, else just insert it to - * the wait queue - */ - for (i = 0; i < txb->nr_frags; i++) { - queue_len = skb_queue_len(&ieee->skb_waitq[queue_index]); - if ((queue_len != 0) || - (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) || - (ieee->queue_stop)) { - /* insert the skb packet to the wait queue - * as for the completion function, it does not need - * to check it any more. - */ - if (queue_len < 200) - skb_queue_tail(&ieee->skb_waitq[queue_index], - txb->fragments[i]); - else - kfree_skb(txb->fragments[i]); - } else { - ieee->softmac_data_hard_start_xmit(txb->fragments[i], - ieee->dev, ieee->rate); - } - } - - rtllib_txb_free(txb); - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void rtllib_reset_queue(struct rtllib_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - init_mgmt_queue(ieee); - if (ieee->tx_pending.txb) { - rtllib_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; - } - ieee->queue_stop = 0; - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(rtllib_reset_queue); - -void rtllib_stop_all_queues(struct rtllib_device *ieee) -{ - unsigned int i; - - for (i = 0; i < ieee->dev->num_tx_queues; i++) - txq_trans_cond_update(netdev_get_tx_queue(ieee->dev, i)); - - netif_tx_stop_all_queues(ieee->dev); -} - -void rtllib_wake_all_queues(struct rtllib_device *ieee) -{ - netif_tx_wake_all_queues(ieee->dev); -} - -/* this is called only in user context, with wx_mutex held */ -static void rtllib_start_bss(struct rtllib_device *ieee) -{ - unsigned long flags; - - /* check if we have already found the net we - * are interested in (if any). - * if not (we are disassociated and we are not - * in associating / authenticating phase) start the background scanning. - */ - rtllib_softmac_check_all_nets(ieee); - - /* ensure no-one start an associating process (thus setting - * the ieee->link_state to rtllib_ASSOCIATING) while we - * have just checked it and we are going to enable scan. - * The rtllib_new_net function is always called with - * lock held (from both rtllib_softmac_check_all_nets and - * the rx path), so we cannot be in the middle of such function - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->link_state == MAC80211_NOLINK) - rtllib_start_scan(ieee); - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static void rtllib_link_change_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, link_change_wq); - ieee->link_change(ieee->dev); -} - -/* called only in userspace context */ -void rtllib_disassociate(struct rtllib_device *ieee) -{ - netif_carrier_off(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) - rtllib_reset_queue(ieee); - - ieee->link_state = MAC80211_NOLINK; - ieee->is_set_key = false; - ieee->wap_set = 0; - - schedule_delayed_work(&ieee->link_change_wq, 0); - - notify_wx_assoc_event(ieee); -} - -static void rtllib_associate_retry_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, associate_retry_wq); - unsigned long flags; - - mutex_lock(&ieee->wx_mutex); - if (!ieee->proto_started) - goto exit; - - if (ieee->link_state != RTLLIB_ASSOCIATING_RETRY) - goto exit; - - /* until we do not set the state to MAC80211_NOLINK - * there are no possibility to have someone else trying - * to start an association procedure (we get here with - * ieee->link_state = RTLLIB_ASSOCIATING). - * When we set the state to MAC80211_NOLINK it is possible - * that the RX path run an attempt to associate, but - * both rtllib_softmac_check_all_nets and the - * RX path works with ieee->lock held so there are no - * problems. If we are still disassociated then start a scan. - * the lock here is necessary to ensure no one try to start - * an association procedure when we have just checked the - * state and we are going to start the scan. - */ - ieee->beinretry = true; - ieee->link_state = MAC80211_NOLINK; - - rtllib_softmac_check_all_nets(ieee); - - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->link_state == MAC80211_NOLINK) - rtllib_start_scan(ieee); - spin_unlock_irqrestore(&ieee->lock, flags); - - ieee->beinretry = false; -exit: - mutex_unlock(&ieee->wx_mutex); -} - -void rtllib_softmac_stop_protocol(struct rtllib_device *ieee) -{ - rtllib_stop_scan_syncro(ieee); - mutex_lock(&ieee->wx_mutex); - rtllib_stop_protocol(ieee); - mutex_unlock(&ieee->wx_mutex); -} -EXPORT_SYMBOL(rtllib_softmac_stop_protocol); - -void rtllib_stop_protocol(struct rtllib_device *ieee) -{ - if (!ieee->proto_started) - return; - - ieee->proto_started = 0; - ieee->proto_stoppping = 1; - ieee->rtllib_ips_leave(ieee->dev); - - del_timer_sync(&ieee->associate_timer); - mutex_unlock(&ieee->wx_mutex); - cancel_delayed_work_sync(&ieee->associate_retry_wq); - mutex_lock(&ieee->wx_mutex); - cancel_delayed_work_sync(&ieee->link_change_wq); - rtllib_stop_scan(ieee); - - if (ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED) - ieee->link_state = MAC80211_NOLINK; - - if (ieee->link_state == MAC80211_LINKED) { - if (ieee->iw_mode == IW_MODE_INFRA) - send_disassociation(ieee, 1, WLAN_REASON_DEAUTH_LEAVING); - rtllib_disassociate(ieee); - } - - remove_all_ts(ieee); - ieee->proto_stoppping = 0; - - kfree(ieee->assocreq_ies); - ieee->assocreq_ies = NULL; - ieee->assocreq_ies_len = 0; - kfree(ieee->assocresp_ies); - ieee->assocresp_ies = NULL; - ieee->assocresp_ies_len = 0; -} - -void rtllib_softmac_start_protocol(struct rtllib_device *ieee) -{ - mutex_lock(&ieee->wx_mutex); - rtllib_start_protocol(ieee); - mutex_unlock(&ieee->wx_mutex); -} -EXPORT_SYMBOL(rtllib_softmac_start_protocol); - -void rtllib_start_protocol(struct rtllib_device *ieee) -{ - short ch = 0; - int i = 0; - - if (ieee->proto_started) - return; - - ieee->proto_started = 1; - - if (ieee->current_network.channel == 0) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - return; /* no channel found */ - } while (!ieee->active_channel_map[ch]); - ieee->current_network.channel = ch; - } - - if (ieee->current_network.beacon_interval == 0) - ieee->current_network.beacon_interval = 100; - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - ieee->wmm_acm = 0; - /* if the user set the MAC of the ad-hoc cell and then - * switch to managed mode, shall we make sure that association - * attempts does not fail just because the user provide the essid - * and the nic is still checking for the AP MAC ?? - */ - switch (ieee->iw_mode) { - case IW_MODE_INFRA: - rtllib_start_bss(ieee); - break; - } -} - -int rtllib_softmac_init(struct rtllib_device *ieee) -{ - int i; - - memset(&ieee->current_network, 0, sizeof(struct rtllib_network)); - - ieee->link_state = MAC80211_NOLINK; - for (i = 0; i < 5; i++) - ieee->seq_ctrl[i] = 0; - - ieee->link_detect_info.slot_index = 0; - ieee->link_detect_info.slot_num = 2; - ieee->link_detect_info.num_recv_bcn_in_period = 0; - ieee->link_detect_info.num_recv_data_in_period = 0; - ieee->link_detect_info.num_tx_ok_in_period = 0; - ieee->link_detect_info.num_rx_ok_in_period = 0; - ieee->link_detect_info.num_rx_unicast_ok_in_period = 0; - ieee->is_aggregate_frame = false; - ieee->assoc_id = 0; - ieee->queue_stop = 0; - ieee->scanning_continue = 0; - ieee->softmac_features = 0; - ieee->wap_set = 0; - ieee->ssid_set = 0; - ieee->proto_started = 0; - ieee->proto_stoppping = 0; - ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE; - ieee->rate = 22; - ieee->ps = RTLLIB_PS_DISABLED; - ieee->sta_sleep = LPS_IS_WAKE; - - ieee->reg_dot11ht_oper_rate_set[0] = 0xff; - ieee->reg_dot11ht_oper_rate_set[1] = 0xff; - ieee->reg_dot11ht_oper_rate_set[4] = 0x01; - - ieee->reg_dot11tx_ht_oper_rate_set[0] = 0xff; - ieee->reg_dot11tx_ht_oper_rate_set[1] = 0xff; - ieee->reg_dot11tx_ht_oper_rate_set[4] = 0x01; - - ieee->first_ie_in_scan = false; - ieee->actscanning = false; - ieee->beinretry = false; - ieee->is_set_key = false; - init_mgmt_queue(ieee); - - ieee->tx_pending.txb = NULL; - - timer_setup(&ieee->associate_timer, rtllib_associate_abort_cb, 0); - - INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq); - INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq); - INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq); - INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq); - INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *)rtllib_associate_retry_wq); - INIT_WORK(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq); - - mutex_init(&ieee->wx_mutex); - mutex_init(&ieee->scan_mutex); - mutex_init(&ieee->ips_mutex); - - spin_lock_init(&ieee->mgmt_tx_lock); - spin_lock_init(&ieee->beacon_lock); - - INIT_WORK(&ieee->ps_task, rtllib_sta_ps); - - return 0; -} - -void rtllib_softmac_free(struct rtllib_device *ieee) -{ - del_timer_sync(&ieee->associate_timer); - - cancel_delayed_work_sync(&ieee->associate_retry_wq); - cancel_delayed_work_sync(&ieee->associate_procedure_wq); - cancel_delayed_work_sync(&ieee->softmac_scan_wq); - cancel_delayed_work_sync(&ieee->hw_wakeup_wq); - cancel_delayed_work_sync(&ieee->hw_sleep_wq); - cancel_delayed_work_sync(&ieee->link_change_wq); - cancel_work_sync(&ieee->associate_complete_wq); - cancel_work_sync(&ieee->ips_leave_wq); - cancel_work_sync(&ieee->wx_sync_scan_wq); - cancel_work_sync(&ieee->ps_task); -} - -static inline struct sk_buff * -rtllib_disauth_skb(struct rtllib_network *beacon, - struct rtllib_device *ieee, u16 rsn) -{ - struct sk_buff *skb; - struct rtllib_disauth *disauth; - int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - disauth = skb_put(skb, sizeof(struct rtllib_disauth)); - disauth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH); - disauth->header.duration_id = 0; - - ether_addr_copy(disauth->header.addr1, beacon->bssid); - ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr); - ether_addr_copy(disauth->header.addr3, beacon->bssid); - - disauth->reason = cpu_to_le16(rsn); - return skb; -} - -static inline struct sk_buff * -rtllib_disassociate_skb(struct rtllib_network *beacon, - struct rtllib_device *ieee, u16 rsn) -{ - struct sk_buff *skb; - struct rtllib_disassoc *disass; - int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - disass = skb_put(skb, sizeof(struct rtllib_disassoc)); - disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC); - disass->header.duration_id = 0; - - ether_addr_copy(disass->header.addr1, beacon->bssid); - ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr); - ether_addr_copy(disass->header.addr3, beacon->bssid); - - disass->reason = cpu_to_le16(rsn); - return skb; -} - -void send_disassociation(struct rtllib_device *ieee, bool deauth, u16 rsn) -{ - struct rtllib_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - if (deauth) - skb = rtllib_disauth_skb(beacon, ieee, rsn); - else - skb = rtllib_disassociate_skb(beacon, ieee, rsn); - - if (skb) - softmac_mgmt_xmit(skb, ieee); -} - -u8 rtllib_ap_sec_type(struct rtllib_device *ieee) -{ - static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04}; - static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; - int wpa_ie_len = ieee->wpa_ie_len; - struct lib80211_crypt_data *crypt; - int encrypt; - - crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) - || (crypt && crypt->ops && (strcmp(crypt->ops->name, "R-WEP") == 0)); - - /* simply judge */ - if (encrypt && (wpa_ie_len == 0)) { - return SEC_ALG_WEP; - } else if ((wpa_ie_len != 0)) { - if (((ieee->wpa_ie[0] == 0xdd) && - (!memcmp(&ieee->wpa_ie[14], ccmp_ie, 4))) || - ((ieee->wpa_ie[0] == 0x30) && - (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4)))) - return SEC_ALG_CCMP; - else - return SEC_ALG_TKIP; - } else { - return SEC_ALG_NONE; - } -} - -static void rtllib_mlme_disassociate_request(struct rtllib_device *rtllib, - u8 *addr, u8 rsn) -{ - u8 i; - u8 op_mode; - - remove_peer_ts(rtllib, addr); - - if (memcmp(rtllib->current_network.bssid, addr, 6) == 0) { - rtllib->link_state = MAC80211_NOLINK; - - for (i = 0; i < 6; i++) - rtllib->current_network.bssid[i] = 0x22; - op_mode = RT_OP_MODE_NO_LINK; - rtllib->op_mode = RT_OP_MODE_NO_LINK; - rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_MEDIA_STATUS, - (u8 *)(&op_mode)); - rtllib_disassociate(rtllib); - - rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_BSSID, - rtllib->current_network.bssid); - } -} - -static void rtllib_mgnt_disconnect_ap(struct rtllib_device *rtllib, u8 rsn) -{ - bool filter_out_nonassociated_bssid = false; - - filter_out_nonassociated_bssid = false; - rtllib->set_hw_reg_handler(rtllib->dev, HW_VAR_CECHK_BSSID, - (u8 *)(&filter_out_nonassociated_bssid)); - rtllib_mlme_disassociate_request(rtllib, rtllib->current_network.bssid, - rsn); - - rtllib->link_state = MAC80211_NOLINK; -} - -bool rtllib_mgnt_disconnect(struct rtllib_device *rtllib, u8 rsn) -{ - if (rtllib->ps != RTLLIB_PS_DISABLED) - rtllib->sta_wake_up(rtllib->dev); - - if (rtllib->link_state == MAC80211_LINKED) { - if (rtllib->iw_mode == IW_MODE_INFRA) - rtllib_mgnt_disconnect_ap(rtllib, rsn); - } - - return true; -} -EXPORT_SYMBOL(rtllib_mgnt_disconnect); - -void notify_wx_assoc_event(struct rtllib_device *ieee) -{ - union iwreq_data wrqu; - - if (ieee->cannot_notify) - return; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - if (ieee->link_state == MAC80211_LINKED) { - memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, - ETH_ALEN); - } else { - netdev_info(ieee->dev, "%s(): Tell user space disconnected\n", - __func__); - eth_zero_addr(wrqu.ap_addr.sa_data); - } - wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); -} -EXPORT_SYMBOL(notify_wx_assoc_event); diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c deleted file mode 100644 index 11542aea4a20..000000000000 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ /dev/null @@ -1,534 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Some pieces of code might be stolen from ipw2100 driver - * copyright of who own it's copyright ;-) - * - * PS wx handler mostly stolen from hostap, copyright who - * own it's copyright ;-) - */ -#include - -#include "rtllib.h" - -int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct iw_freq *fwrq = &wrqu->freq; - - mutex_lock(&ieee->wx_mutex); - - if (ieee->iw_mode == IW_MODE_INFRA) { - ret = 0; - goto out; - } - - /* if setting by freq convert to channel */ - if (fwrq->e == 1) { - if ((fwrq->m >= (int)2.412e8 && - fwrq->m <= (int)2.487e8)) { - fwrq->m = ieee80211_freq_khz_to_channel(fwrq->m / 100); - fwrq->e = 0; - } - } - - if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) { - ret = -EOPNOTSUPP; - goto out; - - } else { /* Set the channel */ - - if (ieee->active_channel_map[fwrq->m] != 1) { - ret = -EINVAL; - goto out; - } - ieee->current_network.channel = fwrq->m; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - } - - ret = 0; -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_freq); - -int rtllib_wx_get_freq(struct rtllib_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct iw_freq *fwrq = &wrqu->freq; - - if (ieee->current_network.channel == 0) - return -1; - fwrq->m = ieee80211_channel_to_freq_khz(ieee->current_network.channel, - NL80211_BAND_2GHZ) * 100; - fwrq->e = 1; - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_freq); - -int rtllib_wx_get_wap(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - unsigned long flags; - - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->link_state != MAC80211_LINKED && - ieee->link_state != MAC80211_LINKED_SCANNING && - ieee->wap_set == 0) - - eth_zero_addr(wrqu->ap_addr.sa_data); - else - memcpy(wrqu->ap_addr.sa_data, - ieee->current_network.bssid, ETH_ALEN); - - spin_unlock_irqrestore(&ieee->lock, flags); - - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_wap); - -int rtllib_wx_set_wap(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - int ret = 0; - unsigned long flags; - - short ifup = ieee->proto_started; - struct sockaddr *temp = (struct sockaddr *)awrq; - - rtllib_stop_scan_syncro(ieee); - - mutex_lock(&ieee->wx_mutex); - /* use ifconfig hw ether */ - - if (temp->sa_family != ARPHRD_ETHER) { - ret = -EINVAL; - goto out; - } - - if (is_zero_ether_addr(temp->sa_data)) { - spin_lock_irqsave(&ieee->lock, flags); - ether_addr_copy(ieee->current_network.bssid, temp->sa_data); - ieee->wap_set = 0; - spin_unlock_irqrestore(&ieee->lock, flags); - ret = -1; - goto out; - } - - if (ifup) - rtllib_stop_protocol(ieee); - - /* just to avoid to give inconsistent infos in the - * get wx method. not really needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - ieee->cannot_notify = false; - ether_addr_copy(ieee->current_network.bssid, temp->sa_data); - ieee->wap_set = !is_zero_ether_addr(temp->sa_data); - - spin_unlock_irqrestore(&ieee->lock, flags); - - if (ifup) - rtllib_start_protocol(ieee); -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_wap); - -int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int len, ret = 0; - unsigned long flags; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->current_network.ssid[0] == '\0' || - ieee->current_network.ssid_len == 0) { - ret = -1; - goto out; - } - - if (ieee->link_state != MAC80211_LINKED && - ieee->link_state != MAC80211_LINKED_SCANNING && - ieee->ssid_set == 0) { - ret = -1; - goto out; - } - len = ieee->current_network.ssid_len; - wrqu->essid.length = len; - strncpy(b, ieee->current_network.ssid, len); - wrqu->essid.flags = 1; - -out: - spin_unlock_irqrestore(&ieee->lock, flags); - - return ret; -} -EXPORT_SYMBOL(rtllib_wx_get_essid); - -int rtllib_wx_set_rate(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - u32 target_rate = wrqu->bitrate.value; - - ieee->rate = target_rate / 100000; - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_rate); - -int rtllib_wx_get_rate(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - u32 tmp_rate; - - tmp_rate = tx_count_to_data_rate(ieee, - ieee->softmac_stats.CurrentShowTxate); - wrqu->bitrate.value = tmp_rate * 500000; - - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_rate); - -int rtllib_wx_set_rts(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - if (wrqu->rts.disabled || !wrqu->rts.fixed) { - ieee->rts = DEFAULT_RTS_THRESHOLD; - } else { - if (wrqu->rts.value < MIN_RTS_THRESHOLD || - wrqu->rts.value > MAX_RTS_THRESHOLD) - return -EINVAL; - ieee->rts = wrqu->rts.value; - } - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_rts); - -int rtllib_wx_get_rts(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->rts.value = ieee->rts; - wrqu->rts.fixed = 0; /* no auto select */ - wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_rts); - -int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int set_mode_status = 0; - - rtllib_stop_scan_syncro(ieee); - mutex_lock(&ieee->wx_mutex); - switch (wrqu->mode) { - case IW_MODE_MONITOR: - case IW_MODE_INFRA: - break; - case IW_MODE_AUTO: - wrqu->mode = IW_MODE_INFRA; - break; - default: - set_mode_status = -EINVAL; - goto out; - } - - if (wrqu->mode == ieee->iw_mode) - goto out; - - if (wrqu->mode == IW_MODE_MONITOR) { - ieee->dev->type = ARPHRD_IEEE80211; - rtllib_enable_net_monitor_mode(ieee->dev, false); - } else { - ieee->dev->type = ARPHRD_ETHER; - if (ieee->iw_mode == IW_MODE_MONITOR) - rtllib_disable_net_monitor_mode(ieee->dev, false); - } - - if (!ieee->proto_started) { - ieee->iw_mode = wrqu->mode; - } else { - rtllib_stop_protocol(ieee); - ieee->iw_mode = wrqu->mode; - rtllib_start_protocol(ieee); - } - -out: - mutex_unlock(&ieee->wx_mutex); - return set_mode_status; -} -EXPORT_SYMBOL(rtllib_wx_set_mode); - -void rtllib_wx_sync_scan_wq(void *data) -{ - struct rtllib_device *ieee = container_of(data, struct rtllib_device, wx_sync_scan_wq); - short chan; - enum ht_extchnl_offset chan_offset = 0; - enum ht_channel_width bandwidth = 0; - int b40M = 0; - - mutex_lock(&ieee->wx_mutex); - if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) { - rtllib_start_scan_syncro(ieee); - goto out; - } - - chan = ieee->current_network.channel; - - ieee->leisure_ps_leave(ieee->dev); - /* notify AP to be in PS mode */ - rtllib_sta_ps_send_null_frame(ieee, 1); - rtllib_sta_ps_send_null_frame(ieee, 1); - - rtllib_stop_all_queues(ieee); - ieee->link_state = MAC80211_LINKED_SCANNING; - ieee->link_change(ieee->dev); - /* wait for ps packet to be kicked out successfully */ - msleep(50); - - ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); - - if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht && - ieee->ht_info->cur_bw_40mhz) { - b40M = 1; - chan_offset = ieee->ht_info->cur_sta_ext_chnl_offset; - bandwidth = (enum ht_channel_width)ieee->ht_info->cur_bw_40mhz; - ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20, - HT_EXTCHNL_OFFSET_NO_EXT); - } - - rtllib_start_scan_syncro(ieee); - - if (b40M) { - if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, chan + 2); - else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, chan - 2); - else - ieee->set_chan(ieee->dev, chan); - ieee->set_bw_mode_handler(ieee->dev, bandwidth, chan_offset); - } else { - ieee->set_chan(ieee->dev, chan); - } - - ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE); - - ieee->link_state = MAC80211_LINKED; - ieee->link_change(ieee->dev); - - /* Notify AP that I wake up again */ - rtllib_sta_ps_send_null_frame(ieee, 0); - - if (ieee->link_detect_info.num_recv_bcn_in_period == 0 || - ieee->link_detect_info.num_recv_data_in_period == 0) { - ieee->link_detect_info.num_recv_bcn_in_period = 1; - ieee->link_detect_info.num_recv_data_in_period = 1; - } - rtllib_wake_all_queues(ieee); - -out: - mutex_unlock(&ieee->wx_mutex); -} - -int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret = 0; - - if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) { - ret = -1; - goto out; - } - - if (ieee->link_state == MAC80211_LINKED) { - schedule_work(&ieee->wx_sync_scan_wq); - /* intentionally forget to up sem */ - return 0; - } - -out: - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_scan); - -int rtllib_wx_set_essid(struct rtllib_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0, len; - short proto_started; - unsigned long flags; - - rtllib_stop_scan_syncro(ieee); - mutex_lock(&ieee->wx_mutex); - - proto_started = ieee->proto_started; - - len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - ret = -1; - goto out; - } - - if (proto_started) - rtllib_stop_protocol(ieee); - - /* this is just to be sure that the GET wx callback - * has consistent infos. not needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (wrqu->essid.flags && wrqu->essid.length) { - strncpy(ieee->current_network.ssid, extra, len); - ieee->current_network.ssid_len = len; - ieee->cannot_notify = false; - ieee->ssid_set = 1; - } else { - ieee->ssid_set = 0; - ieee->current_network.ssid[0] = '\0'; - ieee->current_network.ssid_len = 0; - } - spin_unlock_irqrestore(&ieee->lock, flags); - - if (proto_started) - rtllib_start_protocol(ieee); -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_essid); - -int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - wrqu->mode = ieee->iw_mode; - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_mode); - -int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - const char *n = ieee->mode & (WIRELESS_MODE_N_24G) ? "n" : ""; - - scnprintf(wrqu->name, sizeof(wrqu->name), "802.11bg%s", n); - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_name); - -/* this is mostly stolen from hostap */ -int rtllib_wx_set_power(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - - if ((!ieee->sta_wake_up) || - (!ieee->enter_sleep_state) || - (!ieee->ps_is_queue_empty)) { - netdev_warn(ieee->dev, - "%s(): PS mode is tried to be use but driver missed a callback\n", - __func__); - return -1; - } - - mutex_lock(&ieee->wx_mutex); - - if (wrqu->power.disabled) { - ieee->ps = RTLLIB_PS_DISABLED; - goto exit; - } - if (wrqu->power.flags & IW_POWER_TIMEOUT) - ieee->ps_timeout = wrqu->power.value / 1000; - - if (wrqu->power.flags & IW_POWER_PERIOD) - ieee->ps_period = wrqu->power.value / 1000; - - switch (wrqu->power.flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - ieee->ps = RTLLIB_PS_UNICAST; - break; - case IW_POWER_MULTICAST_R: - ieee->ps = RTLLIB_PS_MBCAST; - break; - case IW_POWER_ALL_R: - ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST; - break; - - case IW_POWER_ON: - break; - - default: - ret = -EINVAL; - goto exit; - } -exit: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_power); - -/* this is stolen from hostap */ -int rtllib_wx_get_power(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - mutex_lock(&ieee->wx_mutex); - - if (ieee->ps == RTLLIB_PS_DISABLED) { - wrqu->power.disabled = 1; - goto exit; - } - - wrqu->power.disabled = 0; - - if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - wrqu->power.flags = IW_POWER_TIMEOUT; - wrqu->power.value = ieee->ps_timeout * 1000; - } else { - wrqu->power.flags = IW_POWER_PERIOD; - wrqu->power.value = ieee->ps_period * 1000; - } - - if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) == - (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) - wrqu->power.flags |= IW_POWER_ALL_R; - else if (ieee->ps & RTLLIB_PS_MBCAST) - wrqu->power.flags |= IW_POWER_MULTICAST_R; - else - wrqu->power.flags |= IW_POWER_UNICAST_R; - -exit: - mutex_unlock(&ieee->wx_mutex); - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_power); diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c deleted file mode 100644 index 8e2abd16eb86..000000000000 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ /dev/null @@ -1,901 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * Few modifications for Realtek's Wi-Fi drivers by - * Andrea Merello - * - * A special thanks goes to Realtek for their support ! - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtllib.h" - -/* 802.11 Data Frame - * - * - * 802.11 frame_control for data frames - 2 bytes - * ,--------------------------------------------------------------------. - * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| - * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| - * desc | ver | type | ^-subtype-^ |to |from|more|retry| pwr |more |wep | - * | | | x=0 data |DS | DS |frag| | mgm |data | | - * | | | x=1 data+ack | | | | | | | | - * '--------------------------------------------------------------------' - * /\ - * | - * 802.11 Data Frame | - * ,--------- 'ctrl' expands to >---' - * | - * ,--'---,-------------------------------------------------------------. - * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - * |------|------|---------|---------|---------|------|---------|------| - * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - * | | tion | (BSSID) | | | ence | data | | - * `--------------------------------------------------| |------' - * Total: 28 non-data bytes `----.----' - * | - * .- 'Frame data' expands to <---------------------------' - * | - * V - * ,---------------------------------------------------. - * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - * |------|------|---------|----------|------|---------| - * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - * | DSAP | SSAP | | | | Packet | - * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - * `-----------------------------------------| | - * Total: 8 non-data bytes `----.----' - * | - * .- 'IP Packet' expands, if WEP enabled, to <--' - * | - * V - * ,-----------------------. - * Bytes | 4 | 0-2296 | 4 | - * |-----|-----------|-----| - * Desc. | IV | Encrypted | ICV | - * | | IP Packet | | - * `-----------------------' - * Total: 8 non-data bytes - * - * - * 802.3 Ethernet Data Frame - * - * ,-----------------------------------------. - * Bytes | 6 | 6 | 2 | Variable | 4 | - * |-------|-------|------|-----------|------| - * Desc. | Dest. | Source| Type | IP Packet | fcs | - * | MAC | MAC | | | | - * `-----------------------------------------' - * Total: 18 non-data bytes - * - * In the event that fragmentation is required, the incoming payload is split - * into N parts of size ieee->fts. The first fragment contains the SNAP header - * and the remaining packets are just data. - * - * If encryption is enabled, each fragment payload size is reduced by enough - * space to add the prefix and postfix (IV and ICV totalling 8 bytes in - * the case of WEP) So if you have 1500 bytes of payload with ieee->fts set to - * 500 without encryption it will take 3 frames. With WEP it will take 4 frames - * as the payload of each frame is reduced to 492 bytes. - * - * SKB visualization - * - * ,- skb->data - * | - * | ETHERNET HEADER ,-<-- PAYLOAD - * | | 14 bytes from skb->data - * | 2 bytes for Type --> ,T. | (sizeof ethhdr) - * | | | | - * |,-Dest.--. ,--Src.---. | | | - * | 6 bytes| | 6 bytes | | | | - * v | | | | | | - * 0 | v 1 | v | v 2 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * ^ | ^ | ^ | - * | | | | | | - * | | | | `T' <---- 2 bytes for Type - * | | | | - * | | '---SNAP--' <-------- 6 bytes for SNAP - * | | - * `-IV--' <-------------------- 4 bytes for IV (WEP) - * - * SNAP HEADER - * - */ - -static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; -static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; - -static int rtllib_put_snap(u8 *data, u16 h_proto) -{ - struct rtllib_snap_hdr *snap; - u8 *oui; - - snap = (struct rtllib_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - - *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); - - return SNAP_SIZE + sizeof(u16); -} - -int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, - int hdr_len) -{ - struct lib80211_crypt_data *crypt = NULL; - int res; - - crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - - if (!(crypt && crypt->ops)) { - netdev_info(ieee->dev, "=========>%s(), crypt is null\n", - __func__); - return -1; - } - /* To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) - */ - - /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. - */ - atomic_inc(&crypt->refcnt); - res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) - res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); - - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_info(ieee->dev, "%s: Encryption failed: len=%d.\n", - ieee->dev->name, frag->len); - return -1; - } - - return 0; -} - -void rtllib_txb_free(struct rtllib_txb *txb) -{ - if (unlikely(!txb)) - return; - kfree(txb); -} - -static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size, - gfp_t gfp_mask) -{ - struct rtllib_txb *txb; - int i; - - txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask); - if (!txb) - return NULL; - - txb->nr_frags = nr_frags; - txb->frag_size = cpu_to_le16(txb_size); - - for (i = 0; i < nr_frags; i++) { - txb->fragments[i] = dev_alloc_skb(txb_size); - if (unlikely(!txb->fragments[i])) - goto err_free; - memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); - } - - return txb; - -err_free: - while (--i >= 0) - dev_kfree_skb_any(txb->fragments[i]); - kfree(txb); - - return NULL; -} - -static int rtllib_classify(struct sk_buff *skb) -{ - struct ethhdr *eth; - struct iphdr *ip; - - eth = (struct ethhdr *)skb->data; - if (eth->h_proto != htons(ETH_P_IP)) - return 0; - -#ifdef VERBOSE_DEBUG - print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, skb->data, - skb->len); -#endif - ip = ip_hdr(skb); - switch (ip->tos & 0xfc) { - case 0x20: - return 2; - case 0x40: - return 1; - case 0x60: - return 3; - case 0x80: - return 4; - case 0xa0: - return 5; - case 0xc0: - return 6; - case 0xe0: - return 7; - default: - return 0; - } -} - -static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, - struct sk_buff *skb, - struct cb_desc *tcb_desc) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - struct tx_ts_record *ts = NULL; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - if (rtllib_act_scanning(ieee, false)) - return; - - if (!ht_info->current_ht_support || !ht_info->enable_ht) - return; - if (!is_qos_data_frame(skb->data)) - return; - if (is_multicast_ether_addr(hdr->addr1)) - return; - - if (tcb_desc->bdhcp || ieee->cnt_after_link < 2) - return; - - if (ht_info->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION) - return; - - if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev)) - return; - if (ht_info->current_ampdu_enable) { - if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), hdr->addr1, - skb->priority, TX_DIR, true)) { - netdev_info(ieee->dev, "%s: can't get TS\n", __func__); - return; - } - if (!ts->tx_admitted_ba_record.b_valid) { - if (ieee->wpa_ie_len && (ieee->pairwise_key_type == - KEY_TYPE_NA)) { - ; - } else if (tcb_desc->bdhcp == 1) { - ; - } else if (!ts->disable_add_ba) { - rtllib_ts_start_add_ba_process(ieee, ts); - } - return; - } else if (!ts->using_ba) { - if (SN_LESS(ts->tx_admitted_ba_record.ba_start_seq_ctrl.field.seq_num, - (ts->tx_cur_seq + 1) % 4096)) - ts->using_ba = true; - else - return; - } - if (ieee->iw_mode == IW_MODE_INFRA) { - tcb_desc->ampdu_enable = true; - tcb_desc->ampdu_factor = ht_info->current_ampdu_factor; - tcb_desc->ampdu_density = ht_info->current_mpdu_density; - } - } -} - -static void rtllib_query_short_preamble_mode(struct rtllib_device *ieee, - struct cb_desc *tcb_desc) -{ - tcb_desc->use_short_preamble = false; - if (tcb_desc->data_rate == 2) - return; - else if (ieee->current_network.capability & - WLAN_CAPABILITY_SHORT_PREAMBLE) - tcb_desc->use_short_preamble = true; -} - -static void rtllib_query_ht_cap_short_gi(struct rtllib_device *ieee, - struct cb_desc *tcb_desc) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - tcb_desc->use_short_gi = false; - - if (!ht_info->current_ht_support || !ht_info->enable_ht) - return; - - if (ht_info->cur_bw_40mhz && ht_info->cur_short_gi_40mhz) - tcb_desc->use_short_gi = true; - else if (!ht_info->cur_bw_40mhz && ht_info->cur_short_gi_20mhz) - tcb_desc->use_short_gi = true; -} - -static void rtllib_query_bandwidth_mode(struct rtllib_device *ieee, - struct cb_desc *tcb_desc) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - tcb_desc->packet_bw = false; - - if (!ht_info->current_ht_support || !ht_info->enable_ht) - return; - - if (tcb_desc->multicast || tcb_desc->broadcast) - return; - - if ((tcb_desc->data_rate & 0x80) == 0) - return; - if (ht_info->cur_bw_40mhz && ht_info->cur_tx_bw40mhz && - !ieee->bandwidth_auto_switch.forced_tx_20MHz) - tcb_desc->packet_bw = true; -} - -static void rtllib_query_protectionmode(struct rtllib_device *ieee, - struct cb_desc *tcb_desc, - struct sk_buff *skb) -{ - struct rt_hi_throughput *ht_info; - - tcb_desc->rtsstbc = false; - tcb_desc->rts_use_short_gi = false; - tcb_desc->cts_enable = false; - tcb_desc->RTSSC = 0; - tcb_desc->rts_bw = false; - - if (tcb_desc->broadcast || tcb_desc->multicast) - return; - - if (is_broadcast_ether_addr(skb->data + 16)) - return; - - if (ieee->mode < WIRELESS_MODE_N_24G) { - if (skb->len > ieee->rts) { - tcb_desc->rts_enable = true; - tcb_desc->rts_rate = MGN_24M; - } else if (ieee->current_network.buseprotection) { - tcb_desc->rts_enable = true; - tcb_desc->cts_enable = true; - tcb_desc->rts_rate = MGN_24M; - } - return; - } - - ht_info = ieee->ht_info; - - while (true) { - if (ht_info->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) { - tcb_desc->cts_enable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->rts_enable = true; - break; - } else if (ht_info->iot_action & (HT_IOT_ACT_FORCED_RTS | - HT_IOT_ACT_PURE_N_MODE)) { - tcb_desc->rts_enable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - if (ieee->current_network.buseprotection) { - tcb_desc->rts_enable = true; - tcb_desc->cts_enable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - if (ht_info->current_ht_support && ht_info->enable_ht) { - u8 ht_op_mode = ht_info->current_op_mode; - - if ((ht_info->cur_bw_40mhz && (ht_op_mode == 2 || - ht_op_mode == 3)) || - (!ht_info->cur_bw_40mhz && ht_op_mode == 3)) { - tcb_desc->rts_rate = MGN_24M; - tcb_desc->rts_enable = true; - break; - } - } - if (skb->len > ieee->rts) { - tcb_desc->rts_rate = MGN_24M; - tcb_desc->rts_enable = true; - break; - } - if (tcb_desc->ampdu_enable) { - tcb_desc->rts_rate = MGN_24M; - tcb_desc->rts_enable = false; - break; - } - goto NO_PROTECTION; - } - if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - tcb_desc->use_short_preamble = true; - return; -NO_PROTECTION: - tcb_desc->rts_enable = false; - tcb_desc->cts_enable = false; - tcb_desc->rts_rate = 0; - tcb_desc->RTSSC = 0; - tcb_desc->rts_bw = false; -} - -static void rtllib_txrate_selectmode(struct rtllib_device *ieee, - struct cb_desc *tcb_desc) -{ - if (ieee->tx_dis_rate_fallback) - tcb_desc->tx_dis_rate_fallback = true; - - if (ieee->tx_use_drv_assinged_rate) - tcb_desc->tx_use_drv_assinged_rate = true; - if (!tcb_desc->tx_dis_rate_fallback || - !tcb_desc->tx_use_drv_assinged_rate) { - if (ieee->iw_mode == IW_MODE_INFRA) - tcb_desc->ratr_index = 0; - } -} - -static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, - u8 *dst) -{ - u16 seqnum = 0; - - if (is_multicast_ether_addr(dst)) - return 0; - if (is_qos_data_frame(skb->data)) { - struct tx_ts_record *ts = NULL; - - if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), dst, - skb->priority, TX_DIR, true)) - return 0; - seqnum = ts->tx_cur_seq; - ts->tx_cur_seq = (ts->tx_cur_seq + 1) % 4096; - return seqnum; - } - return 0; -} - -static int wme_downgrade_ac(struct sk_buff *skb) -{ - switch (skb->priority) { - case 6: - case 7: - skb->priority = 5; /* VO -> VI */ - return 0; - case 4: - case 5: - skb->priority = 3; /* VI -> BE */ - return 0; - case 0: - case 3: - skb->priority = 1; /* BE -> BK */ - return 0; - default: - return -1; - } -} - -static u8 rtllib_current_rate(struct rtllib_device *ieee) -{ - if (ieee->mode & IEEE_MODE_MASK) - return ieee->rate; - - if (ieee->ht_curr_op_rate) - return ieee->ht_curr_op_rate; - else - return ieee->rate & 0x7F; -} - -static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) -{ - struct rtllib_device *ieee = (struct rtllib_device *) - netdev_priv_rsl(dev); - struct rtllib_txb *txb = NULL; - struct ieee80211_qos_hdr *frag_hdr; - int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; - unsigned long flags; - struct net_device_stats *stats = &ieee->stats; - int ether_type = 0, encrypt; - int bytes, fc, qos_ctl = 0, hdr_len; - struct sk_buff *skb_frag; - struct ieee80211_qos_hdr header = { /* Ensure zero initialized */ - .duration_id = 0, - .seq_ctrl = 0, - .qos_ctrl = 0 - }; - int qos_activated = ieee->current_network.qos_data.active; - u8 dest[ETH_ALEN]; - u8 src[ETH_ALEN]; - struct lib80211_crypt_data *crypt = NULL; - struct cb_desc *tcb_desc; - u8 is_multicast = false; - bool bdhcp = false; - - spin_lock_irqsave(&ieee->lock, flags); - - /* If there is no driver handler to take the TXB, don't bother - * creating it... - */ - if (!(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) || - ((!ieee->softmac_data_hard_start_xmit && - (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { - netdev_warn(ieee->dev, "No xmit handler.\n"); - goto success; - } - - if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", - skb->len); - goto success; - } - /* Save source and destination addresses */ - ether_addr_copy(dest, skb->data); - ether_addr_copy(src, skb->data + ETH_ALEN); - - memset(skb->cb, 0, sizeof(skb->cb)); - ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, - "Could not allocate TXB\n"); - goto failed; - } - - txb->encrypted = 0; - txb->payload_size = cpu_to_le16(skb->len); - skb_put_data(txb->fragments[0], skb->data, skb->len); - - goto success; - } - - if (skb->len > 282) { - if (ether_type == ETH_P_IP) { - const struct iphdr *ip = (struct iphdr *) - ((u8 *)skb->data + 14); - if (ip->protocol == IPPROTO_UDP) { - struct udphdr *udp; - - udp = (struct udphdr *)((u8 *)ip + - (ip->ihl << 2)); - if (((((u8 *)udp)[1] == 68) && - (((u8 *)udp)[3] == 67)) || - ((((u8 *)udp)[1] == 67) && - (((u8 *)udp)[3] == 68))) { - bdhcp = true; - ieee->lps_delay_cnt = 200; - } - } - } else if (ether_type == ETH_P_ARP) { - netdev_info(ieee->dev, - "=================>DHCP Protocol start tx ARP pkt!!\n"); - bdhcp = true; - ieee->lps_delay_cnt = - ieee->current_network.tim.tim_count; - } - } - - skb->priority = rtllib_classify(skb); - crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops; - if (!encrypt && ieee->ieee802_1x && - ieee->drop_unencrypted && ether_type != ETH_P_PAE) { - stats->tx_dropped++; - goto success; - } - if (crypt && !encrypt && ether_type == ETH_P_PAE) { - struct eapol *eap = (struct eapol *)(skb->data + - sizeof(struct ethhdr) - SNAP_SIZE - - sizeof(u16)); - netdev_dbg(ieee->dev, - "TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - - /* Advance the SKB to the start of the payload */ - skb_pull(skb, sizeof(struct ethhdr)); - - /* Determine total amount of storage required for TXB packets */ - bytes = skb->len + SNAP_SIZE + sizeof(u16); - - if (encrypt) - fc = RTLLIB_FTYPE_DATA | IEEE80211_FCTL_PROTECTED; - else - fc = RTLLIB_FTYPE_DATA; - - if (qos_activated) - fc |= IEEE80211_STYPE_QOS_DATA; - else - fc |= IEEE80211_STYPE_DATA; - - if (ieee->iw_mode == IW_MODE_INFRA) { - fc |= IEEE80211_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, - * Addr3 = DA - */ - ether_addr_copy(header.addr1, - ieee->current_network.bssid); - ether_addr_copy(header.addr2, src); - ether_addr_copy(header.addr3, dest); - } - - is_multicast = is_multicast_ether_addr(header.addr1); - - header.frame_control = cpu_to_le16(fc); - - /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) - */ - if (is_multicast) { - frag_size = MAX_FRAG_THRESHOLD; - qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; - } else { - frag_size = ieee->fts; - qos_ctl = 0; - } - - if (qos_activated) { - hdr_len = RTLLIB_3ADDR_LEN + 2; - - /* in case we are a client verify acm is not set for this ac */ - while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { - netdev_info(ieee->dev, "skb->priority = %x\n", - skb->priority); - if (wme_downgrade_ac(skb)) - break; - netdev_info(ieee->dev, "converted skb->priority = %x\n", - skb->priority); - } - - qos_ctl |= skb->priority; - header.qos_ctrl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); - - } else { - hdr_len = RTLLIB_3ADDR_LEN; - } - /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account - * for it when determining the amount of payload space. - */ - bytes_per_frag = frag_size - hdr_len; - if (ieee->config & - (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) - bytes_per_frag -= RTLLIB_FCS_LEN; - - /* Each fragment may need to have room for encrypting - * pre/postfix - */ - if (encrypt) { - bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + - crypt->ops->extra_mpdu_postfix_len + - crypt->ops->extra_msdu_prefix_len + - crypt->ops->extra_msdu_postfix_len; - } - /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment - */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; - - /* When we allocate the TXB we allocate enough space for the - * reserve and full fragment bytes (bytes_per_frag doesn't - * include prefix, postfix, header, FCS, etc.) - */ - txb = rtllib_alloc_txb(nr_frags, frag_size + - ieee->tx_headroom, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - txb->encrypted = encrypt; - txb->payload_size = cpu_to_le16(bytes); - - if (qos_activated) - txb->queue_index = UP2AC(skb->priority); - else - txb->queue_index = WME_AC_BE; - - for (i = 0; i < nr_frags; i++) { - skb_frag = txb->fragments[i]; - tcb_desc = (struct cb_desc *)(skb_frag->cb + - MAX_DEV_ADDR_SIZE); - if (qos_activated) { - skb_frag->priority = skb->priority; - tcb_desc->queue_index = UP2AC(skb->priority); - } else { - skb_frag->priority = WME_AC_BE; - tcb_desc->queue_index = WME_AC_BE; - } - skb_reserve(skb_frag, ieee->tx_headroom); - - if (encrypt) { - if (ieee->hwsec_active) - tcb_desc->hw_sec = 1; - else - tcb_desc->hw_sec = 0; - skb_reserve(skb_frag, - crypt->ops->extra_mpdu_prefix_len + - crypt->ops->extra_msdu_prefix_len); - } else { - tcb_desc->hw_sec = 0; - } - frag_hdr = skb_put_data(skb_frag, &header, hdr_len); - - /* If this is not the last fragment, then add the - * MOREFRAGS bit to the frame control - */ - if (i != nr_frags - 1) { - frag_hdr->frame_control = cpu_to_le16(fc | - IEEE80211_FCTL_MOREFRAGS); - bytes = bytes_per_frag; - - } else { - /* The last fragment has the remaining length */ - bytes = bytes_last_frag; - } - if ((qos_activated) && (!is_multicast)) { - frag_hdr->seq_ctrl = - cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, - header.addr1)); - frag_hdr->seq_ctrl = - cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctrl) << 4 | i); - } else { - frag_hdr->seq_ctrl = - cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); - } - /* Put a SNAP header on the first fragment */ - if (i == 0) { - rtllib_put_snap(skb_put(skb_frag, - SNAP_SIZE + - sizeof(u16)), ether_type); - bytes -= SNAP_SIZE + sizeof(u16); - } - - skb_put_data(skb_frag, skb->data, bytes); - - /* Advance the SKB... */ - skb_pull(skb, bytes); - - /* Encryption routine will move the header forward in - * order to insert the IV between the header and the - * payload - */ - if (encrypt) - rtllib_encrypt_fragment(ieee, skb_frag, - hdr_len); - if (ieee->config & - (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) - skb_put(skb_frag, 4); - } - - if ((qos_activated) && (!is_multicast)) { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; - } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - - success: - if (txb) { - tcb_desc = (struct cb_desc *) - (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->tx_enable_fw_calc_dur = 1; - tcb_desc->priority = skb->priority; - - if (ether_type == ETH_P_PAE) { - if (ieee->ht_info->iot_action & - HT_IOT_ACT_WA_IOT_Broadcom) { - tcb_desc->data_rate = - mgnt_query_tx_rate_exclude_cck_rates(ieee); - tcb_desc->tx_dis_rate_fallback = false; - } else { - tcb_desc->data_rate = ieee->basic_rate; - tcb_desc->tx_dis_rate_fallback = 1; - } - - tcb_desc->ratr_index = 7; - tcb_desc->tx_use_drv_assinged_rate = 1; - } else { - if (is_multicast_ether_addr(header.addr1)) - tcb_desc->multicast = 1; - if (is_broadcast_ether_addr(header.addr1)) - tcb_desc->broadcast = 1; - rtllib_txrate_selectmode(ieee, tcb_desc); - if (tcb_desc->multicast || tcb_desc->broadcast) - tcb_desc->data_rate = ieee->basic_rate; - else - tcb_desc->data_rate = rtllib_current_rate(ieee); - - if (bdhcp) { - if (ieee->ht_info->iot_action & - HT_IOT_ACT_WA_IOT_Broadcom) { - tcb_desc->data_rate = - mgnt_query_tx_rate_exclude_cck_rates(ieee); - tcb_desc->tx_dis_rate_fallback = false; - } else { - tcb_desc->data_rate = MGN_1M; - tcb_desc->tx_dis_rate_fallback = 1; - } - - tcb_desc->ratr_index = 7; - tcb_desc->tx_use_drv_assinged_rate = 1; - tcb_desc->bdhcp = 1; - } - - rtllib_query_short_preamble_mode(ieee, tcb_desc); - rtllib_tx_query_agg_cap(ieee, txb->fragments[0], - tcb_desc); - rtllib_query_ht_cap_short_gi(ieee, tcb_desc); - rtllib_query_bandwidth_mode(ieee, tcb_desc); - rtllib_query_protectionmode(ieee, tcb_desc, - txb->fragments[0]); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); - dev_kfree_skb_any(skb); - if (txb) { - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += le16_to_cpu(txb->payload_size); - rtllib_softmac_xmit(txb, ieee); - } else { - rtllib_txb_free(txb); - } - } - - return 0; - - failed: - spin_unlock_irqrestore(&ieee->lock, flags); - netif_stop_queue(dev); - stats->tx_errors++; - return 1; -} - -netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev) -{ - memset(skb->cb, 0, sizeof(skb->cb)); - return rtllib_xmit_inter(skb, dev) ? NETDEV_TX_BUSY : NETDEV_TX_OK; -} -EXPORT_SYMBOL(rtllib_xmit); diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c deleted file mode 100644 index c730d921463d..000000000000 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ /dev/null @@ -1,752 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright(c) 2004 Intel Corporation. All rights reserved. - * - * Portions of this file are based on the WEP enablement code provided by the - * Host AP project hostap-drivers v0.1.3 - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - */ -#include -#include -#include -#include -#include "rtllib.h" - -static const char * const rtllib_modes[] = { - "a", "b", "g", "?", "N-24G" -}; - -#define MAX_CUSTOM_LEN 64 -static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, - char *start, char *stop, - struct rtllib_network *network, - struct iw_request_info *info) -{ - char custom[MAX_CUSTOM_LEN]; - char proto_name[6]; - char *pname = proto_name; - char *p; - struct iw_event iwe; - int i, j; - u16 max_rate, rate; - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - /* Remaining entries will be displayed in the order we provide them */ - - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - if (network->ssid_len > 0) { - iwe.u.data.length = min_t(u8, network->ssid_len, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - } else if (network->hidden_ssid_len == 0) { - iwe.u.data.length = sizeof(""); - start = iwe_stream_add_point(info, start, stop, &iwe, ""); - } else { - iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, network->hidden_ssid); - } - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) { - if (network->mode & BIT(i)) { - strcpy(pname, rtllib_modes[i]); - pname += strlen(rtllib_modes[i]); - } - } - *pname = '\0'; - snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - if (network->capability & - (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { - if (network->capability & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); - } - - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = network->channel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); - - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (network->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - /* Add basic and extended rates */ - max_rate = 0; - p = custom; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); - for (i = 0, j = 0; i < network->rates_len;) { - if (j < network->rates_ex_len && - ((network->rates_ex[j] & 0x7F) < - (network->rates[i] & 0x7F))) - rate = network->rates_ex[j++] & 0x7F; - else - rate = network->rates[i++] & 0x7F; - if (rate > max_rate) - max_rate = rate; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - } - for (; j < network->rates_ex_len; j++) { - rate = network->rates_ex[j] & 0x7F; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - if (rate > max_rate) - max_rate = rate; - } - - if (network->mode >= WIRELESS_MODE_N_24G) { - struct ht_capab_ele *ht_cap = NULL; - bool is40M = false, isShortGI = false; - u8 max_mcs = 0; - - if (!memcmp(network->bssht.bd_ht_cap_buf, EWC11NHTCap, 4)) - ht_cap = (struct ht_capab_ele *) - &network->bssht.bd_ht_cap_buf[4]; - else - ht_cap = (struct ht_capab_ele *) - &network->bssht.bd_ht_cap_buf[0]; - is40M = (ht_cap->chl_width) ? 1 : 0; - isShortGI = (ht_cap->chl_width) ? - ((ht_cap->short_gi_40mhz) ? 1 : 0) : - ((ht_cap->short_gi_20mhz) ? 1 : 0); - - max_mcs = ht_get_highest_mcs_rate(ieee, ht_cap->MCS, - MCS_FILTER_ALL); - rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f]; - if (rate > max_rate) - max_rate = rate; - } - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.value = max_rate * 500000; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - /* Add quality statistics */ - /* TODO: Fix these values... */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = network->stats.signal; - iwe.u.qual.level = network->stats.rssi; - iwe.u.qual.noise = network->stats.noise; - iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK; - if (!(network->stats.mask & RTLLIB_STATMASK_RSSI)) - iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; - if (!(network->stats.mask & RTLLIB_STATMASK_NOISE)) - iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; - if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL)) - iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; - iwe.u.qual.updated = 7; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); - - iwe.cmd = IWEVCUSTOM; - p = custom; - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - memset(&iwe, 0, sizeof(iwe)); - if (network->wpa_ie_len) { - char buf[MAX_WPA_IE_LEN]; - - memcpy(buf, network->wpa_ie, network->wpa_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->wpa_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - memset(&iwe, 0, sizeof(iwe)); - if (network->rsn_ie_len) { - char buf[MAX_WPA_IE_LEN]; - - memcpy(buf, network->rsn_ie, network->rsn_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->rsn_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - /* add info for WZC */ - memset(&iwe, 0, sizeof(iwe)); - if (network->wzc_ie_len) { - char buf[MAX_WZC_IE_LEN]; - - memcpy(buf, network->wzc_ie, network->wzc_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->wzc_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - /* Add EXTRA: Age to display seconds since last beacon/probe response - * for given network. - */ - iwe.cmd = IWEVCUSTOM; - p = custom; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - " Last beacon: %lums ago", - (100 * (jiffies - network->last_scanned)) / HZ); - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - return start; -} - -int rtllib_wx_get_scan(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rtllib_network *network; - unsigned long flags; - - char *ev = extra; - char *stop = ev + wrqu->data.length; - int i = 0; - int err = 0; - - netdev_dbg(ieee->dev, "Getting scan\n"); - mutex_lock(&ieee->wx_mutex); - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(network, &ieee->network_list, list) { - i++; - if ((stop - ev) < 200) { - err = -E2BIG; - break; - } - if (ieee->scan_age == 0 || - time_after(network->last_scanned + ieee->scan_age, jiffies)) - ev = rtl819x_translate_scan(ieee, ev, stop, network, - info); - else - netdev_dbg(ieee->dev, - "Network '%s ( %pM)' hidden due to age (%lums).\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - (100 * (jiffies - network->last_scanned)) / - HZ); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - mutex_unlock(&ieee->wx_mutex); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - - netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i); - - return err; -} -EXPORT_SYMBOL(rtllib_wx_get_scan); - -int rtllib_wx_set_encode(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &wrqu->encoding; - struct net_device *dev = ieee->dev; - struct rtllib_security sec = { - .flags = 0 - }; - int i, key, key_provided, len; - struct lib80211_crypt_data **crypt; - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > NUM_WEP_KEYS) - return -EINVAL; - key--; - key_provided = 1; - } else { - key_provided = 0; - key = ieee->crypt_info.tx_keyidx; - } - - netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ? - "provided" : "default"); - crypt = &ieee->crypt_info.crypt[key]; - if (erq->flags & IW_ENCODE_DISABLED) { - if (key_provided && *crypt) { - netdev_dbg(ieee->dev, - "Disabling encryption on key %d.\n", key); - lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); - } else { - netdev_dbg(ieee->dev, "Disabling encryption.\n"); - } - - /* Check all the keys to see if any are still configured, - * and if no key index was provided, de-init them all - */ - for (i = 0; i < NUM_WEP_KEYS; i++) { - if (ieee->crypt_info.crypt[i]) { - if (key_provided) - break; - lib80211_crypt_delayed_deinit(&ieee->crypt_info, - &ieee->crypt_info.crypt[i]); - } - } - - if (i == NUM_WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - } - - goto done; - } - - sec.enabled = 1; - sec.flags |= SEC_ENABLED; - - if (*crypt && (*crypt)->ops && - strcmp((*crypt)->ops->name, "R-WEP") != 0) { - /* changing to use WEP; deinit previously used algorithm - * on this key - */ - lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); - } - - if (!*crypt) { - struct lib80211_crypt_data *new_crypt; - - /* take WEP into use */ - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); - if (!new_crypt) - return -ENOMEM; - new_crypt->ops = lib80211_get_crypto_ops("R-WEP"); - if (!new_crypt->ops) { - request_module("rtllib_crypt_wep"); - new_crypt->ops = lib80211_get_crypto_ops("R-WEP"); - } - - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(key); - - if (!new_crypt->ops || !new_crypt->priv) { - kfree(new_crypt); - new_crypt = NULL; - - netdev_warn(dev, - "%s: could not initialize WEP: load module rtllib_crypt_wep\n", - dev->name); - return -EOPNOTSUPP; - } - *crypt = new_crypt; - } - - /* If a new key was provided, set it up */ - if (erq->length > 0) { - len = erq->length <= 5 ? 5 : 13; - memcpy(sec.keys[key], keybuf, erq->length); - if (len > erq->length) - memset(sec.keys[key] + erq->length, 0, - len - erq->length); - netdev_dbg(ieee->dev, "Setting key %d to '%s' (%d:%d bytes)\n", - key, escape_essid(sec.keys[key], len), erq->length, - len); - sec.key_sizes[key] = len; - (*crypt)->ops->set_key(sec.keys[key], len, NULL, - (*crypt)->priv); - sec.flags |= (1 << key); - /* This ensures a key will be activated if no key is - * explicitly set - */ - if (key == sec.active_key) - sec.flags |= SEC_ACTIVE_KEY; - ieee->crypt_info.tx_keyidx = key; - - } else { - len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, - NULL, (*crypt)->priv); - if (len == 0) { - /* Set a default key of all 0 */ - netdev_info(ieee->dev, "Setting key %d to all zero.\n", key); - - memset(sec.keys[key], 0, 13); - (*crypt)->ops->set_key(sec.keys[key], 13, NULL, - (*crypt)->priv); - sec.key_sizes[key] = 13; - sec.flags |= (1 << key); - } - - /* No key data - just set the default TX key index */ - if (key_provided) { - netdev_dbg(ieee->dev, - "Setting key %d as default Tx key.\n", key); - ieee->crypt_info.tx_keyidx = key; - sec.active_key = key; - sec.flags |= SEC_ACTIVE_KEY; - } - } - done: - ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); - ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : - WLAN_AUTH_SHARED_KEY; - sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.flags |= SEC_AUTH_MODE; - netdev_dbg(ieee->dev, "Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? - "OPEN" : "SHARED KEY"); - - /* For now we just support WEP, so only set that security level... - * TODO: When WPA is added this is one place that needs to change - */ - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_encode); - -int rtllib_wx_get_encode(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &wrqu->encoding; - int len, key; - struct lib80211_crypt_data *crypt; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > NUM_WEP_KEYS) - return -EINVAL; - key--; - } else { - key = ieee->crypt_info.tx_keyidx; - } - crypt = ieee->crypt_info.crypt[key]; - - erq->flags = key + 1; - - if (!crypt || !crypt->ops) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); - - erq->length = max(len, 0); - - erq->flags |= IW_ENCODE_ENABLED; - - if (ieee->open_wep) - erq->flags |= IW_ENCODE_OPEN; - else - erq->flags |= IW_ENCODE_RESTRICTED; - - return 0; -} -EXPORT_SYMBOL(rtllib_wx_get_encode); - -int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct net_device *dev = ieee->dev; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int i, idx; - int group_key = 0; - const char *alg, *module; - const struct lib80211_crypto_ops *ops; - struct lib80211_crypt_data **crypt; - - struct rtllib_security sec = { - .flags = 0, - }; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > NUM_WEP_KEYS) - return -EINVAL; - idx--; - } else { - idx = ieee->crypt_info.tx_keyidx; - } - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - crypt = &ieee->crypt_info.crypt[idx]; - group_key = 1; - } else { - /* some Cisco APs use idx>0 for unicast in dynamic WEP */ - if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) - return -EINVAL; - if (ieee->iw_mode == IW_MODE_INFRA) - crypt = &ieee->crypt_info.crypt[idx]; - else - return -EINVAL; - } - - sec.flags |= SEC_ENABLED; - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - if (*crypt) - lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); - - for (i = 0; i < NUM_WEP_KEYS; i++) { - if (ieee->crypt_info.crypt[i]) - break; - } - if (i == NUM_WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_LEVEL; - } - goto done; - } - - sec.enabled = 1; - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - alg = "R-WEP"; - module = "rtllib_crypt_wep"; - break; - case IW_ENCODE_ALG_TKIP: - alg = "R-TKIP"; - module = "rtllib_crypt_tkip"; - break; - case IW_ENCODE_ALG_CCMP: - alg = "R-CCMP"; - module = "rtllib_crypt_ccmp"; - break; - default: - netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg); - ret = -EINVAL; - goto done; - } - netdev_dbg(dev, "alg name:%s\n", alg); - - ops = lib80211_get_crypto_ops(alg); - if (!ops) { - char tempbuf[100]; - - memset(tempbuf, 0x00, 100); - sprintf(tempbuf, "%s", module); - request_module("%s", tempbuf); - ops = lib80211_get_crypto_ops(alg); - } - if (!ops) { - netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg); - ret = -EINVAL; - goto done; - } - - if (!*crypt || (*crypt)->ops != ops) { - struct lib80211_crypt_data *new_crypt; - - lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); - - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); - if (!new_crypt) { - ret = -ENOMEM; - goto done; - } - new_crypt->ops = ops; - if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) - new_crypt->priv = new_crypt->ops->init(idx); - - if (!new_crypt->priv) { - kfree(new_crypt); - ret = -EINVAL; - goto done; - } - *crypt = new_crypt; - } - - if (ext->key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, - (*crypt)->priv) < 0) { - netdev_info(dev, "key setting failed\n"); - ret = -EINVAL; - goto done; - } - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - ieee->crypt_info.tx_keyidx = idx; - sec.active_key = idx; - sec.flags |= SEC_ACTIVE_KEY; - } - if (ext->alg != IW_ENCODE_ALG_NONE) { - sec.key_sizes[idx] = ext->key_len; - sec.flags |= (1 << idx); - if (ext->alg == IW_ENCODE_ALG_WEP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (ext->alg == IW_ENCODE_ALG_TKIP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (ext->alg == IW_ENCODE_ALG_CCMP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - /* Don't set sec level for group keys. */ - if (group_key) - sec.flags &= ~SEC_LEVEL; - } -done: - return ret; -} -EXPORT_SYMBOL(rtllib_wx_set_encode_ext); - -int rtllib_wx_set_mlme(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - u8 i = 0; - bool deauth = false; - struct iw_mlme *mlme = (struct iw_mlme *)extra; - - if (ieee->link_state != MAC80211_LINKED) - return -ENOLINK; - - mutex_lock(&ieee->wx_mutex); - - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - deauth = true; - fallthrough; - case IW_MLME_DISASSOC: - if (deauth) - netdev_info(ieee->dev, "disauth packet !\n"); - else - netdev_info(ieee->dev, "dis associate packet!\n"); - - ieee->cannot_notify = true; - - send_disassociation(ieee, deauth, mlme->reason_code); - rtllib_disassociate(ieee); - - ieee->wap_set = 0; - for (i = 0; i < 6; i++) - ieee->current_network.bssid[i] = 0x55; - - ieee->ssid_set = 0; - ieee->current_network.ssid[0] = '\0'; - ieee->current_network.ssid_len = 0; - break; - default: - mutex_unlock(&ieee->wx_mutex); - return -EOPNOTSUPP; - } - - mutex_unlock(&ieee->wx_mutex); - - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_mlme); - -int rtllib_wx_set_auth(struct rtllib_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* Host AP driver does not use these parameters and allows - * wpa_supplicant to control them internally. - */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = data->value; - break; - case IW_AUTH_DROP_UNENCRYPTED: - ieee->drop_unencrypted = data->value; - break; - - case IW_AUTH_80211_AUTH_ALG: - if (data->value & IW_AUTH_ALG_SHARED_KEY) { - ieee->open_wep = 0; - ieee->auth_mode = 1; - } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) { - ieee->open_wep = 1; - ieee->auth_mode = 0; - } else if (data->value & IW_AUTH_ALG_LEAP) { - ieee->open_wep = 1; - ieee->auth_mode = 2; - } else { - return -EINVAL; - } - break; - - case IW_AUTH_WPA_ENABLED: - ieee->wpa_enabled = (data->value) ? 1 : 0; - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - ieee->ieee802_1x = data->value; - break; - case IW_AUTH_PRIVACY_INVOKED: - ieee->privacy_invoked = data->value; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_auth); - -int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len) -{ - u8 *buf; - u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - - if (len > MAX_WPA_IE_LEN || (len && !ie)) - return -EINVAL; - - if (len) { - eid = ie[0]; - if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) { - ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN); - buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - ieee->wps_ie = buf; - return 0; - } - } - ieee->wps_ie_len = 0; - kfree(ieee->wps_ie); - ieee->wps_ie = NULL; - if (len) { - if (len != ie[1] + 2) - return -EINVAL; - buf = kmemdup(ie, len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_gen_ie); From 02f220b5267042d0de649614eec84ded8aeecb4f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:55 +0200 Subject: [PATCH 047/126] wifi: ipw2x00/lib80211: move remaining lib80211 into libipw There's already much code in libipw that used to be shared with more drivers, but now with the prior cleanups, those old Intel ipw2x00 drivers are also the only ones using whatever is now left of lib80211. Move lib80211 entirely into libipw. Link: https://patch.msgid.link/20241007202707.915ef7b9e7c7.Ib9876d2fe3c90f11d6df458b16d0b7d4bf551a8d@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/ipw2x00/Kconfig | 6 - drivers/net/wireless/intel/ipw2x00/Makefile | 6 +- drivers/net/wireless/intel/ipw2x00/ipw2100.c | 7 +- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 4 +- drivers/net/wireless/intel/ipw2x00/ipw2200.h | 2 - drivers/net/wireless/intel/ipw2x00/libipw.h | 101 ++++++- .../wireless/intel/ipw2x00/libipw_crypto.c | 246 +++++++++++++++++ .../intel/ipw2x00/libipw_crypto_ccmp.c | 76 +++--- .../intel/ipw2x00/libipw_crypto_tkip.c | 106 ++++---- .../intel/ipw2x00/libipw_crypto_wep.c | 73 +++-- .../wireless/intel/ipw2x00/libipw_module.c | 36 ++- .../net/wireless/intel/ipw2x00/libipw_rx.c | 9 +- .../net/wireless/intel/ipw2x00/libipw_tx.c | 4 +- .../net/wireless/intel/ipw2x00/libipw_wx.c | 43 ++- include/net/lib80211.h | 122 --------- net/wireless/Kconfig | 33 --- net/wireless/Makefile | 4 - net/wireless/lib80211.c | 257 ------------------ 18 files changed, 525 insertions(+), 610 deletions(-) create mode 100644 drivers/net/wireless/intel/ipw2x00/libipw_crypto.c rename net/wireless/lib80211_crypt_ccmp.c => drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c (83%) rename net/wireless/lib80211_crypt_tkip.c => drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c (87%) rename net/wireless/lib80211_crypt_wep.c => drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c (72%) delete mode 100644 include/net/lib80211.h delete mode 100644 net/wireless/lib80211.c diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig index 1650d5865aa0..d9c042772399 100644 --- a/drivers/net/wireless/intel/ipw2x00/Kconfig +++ b/drivers/net/wireless/intel/ipw2x00/Kconfig @@ -10,7 +10,6 @@ config IPW2100 select WEXT_SPY select WEXT_PRIV select FW_LOADER - select LIB80211 select LIBIPW help A driver for the Intel PRO/Wireless 2100 Network @@ -72,7 +71,6 @@ config IPW2200 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 @@ -162,10 +160,6 @@ config LIBIPW select CRYPTO select CRYPTO_MICHAEL_MIC 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 diff --git a/drivers/net/wireless/intel/ipw2x00/Makefile b/drivers/net/wireless/intel/ipw2x00/Makefile index e1ec50359dff..60c5faccbe15 100644 --- a/drivers/net/wireless/intel/ipw2x00/Makefile +++ b/drivers/net/wireless/intel/ipw2x00/Makefile @@ -12,4 +12,8 @@ libipw-objs := \ libipw_tx.o \ libipw_rx.o \ libipw_wx.o \ - libipw_geo.o + libipw_geo.o \ + libipw_crypto.o \ + libipw_crypto_ccmp.o \ + libipw_crypto_tkip.o \ + libipw_crypto_wep.o diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index b6636002c7d2..a89e06c1b8ee 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -148,9 +148,6 @@ that only one external action is invoked at a time. #include #include #include - -#include - #include "ipw2100.h" #include "ipw.h" @@ -7571,7 +7568,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 +7660,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) { diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index eed9ef17bc29..f4fd1fc784b7 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -6549,7 +6549,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 +6648,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) { diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h index 8ebf09121e17..46f119123b49 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h @@ -31,8 +31,6 @@ #include #include #include - -#include #include #define DRV_NAME "ipw2200" diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h index bad080d33c07..bc727c99ff3c 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw.h +++ b/drivers/net/wireless/intel/ipw2x00/libipw.h @@ -25,8 +25,6 @@ #include /* ARRAY_SIZE */ #include #include - -#include #include #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; @@ -751,7 +819,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 +1056,31 @@ 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); + #endif /* LIBIPW_H */ diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c new file mode 100644 index 000000000000..32639e0e8430 --- /dev/null +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * libipw -- common bits for IPW drivers + * + * Copyright(c) 2008 John W. Linville + * + * Portions copied from old ieee80211 component, w/ original copyright + * notices below: + * + * Host AP crypto routines + * + * Copyright (c) 2002-2003, Jouni Malinen + * Portions Copyright (C) 2004, Intel Corporation + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#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)); +} diff --git a/net/wireless/lib80211_crypt_ccmp.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c similarity index 83% rename from net/wireless/lib80211_crypt_ccmp.c rename to drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c index 5aad139130e1..bf900d8c8ad3 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c @@ -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 * Copyright (c) 2008, John W. Linville @@ -18,17 +18,10 @@ #include #include #include - #include - #include #include - -#include - -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); diff --git a/net/wireless/lib80211_crypt_tkip.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c similarity index 87% rename from net/wireless/lib80211_crypt_tkip.c rename to drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c index 63e68e5e121e..32288697da4f 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c @@ -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 * Copyright (c) 2008, John W. Linville @@ -21,25 +21,18 @@ #include #include #include - #include #include #include - #include #include #include #include - -#include - -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); diff --git a/net/wireless/lib80211_crypt_wep.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c similarity index 72% rename from net/wireless/lib80211_crypt_wep.c rename to drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c index 3b148c7bef85..c3a4ccb9de17 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c @@ -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 * Copyright (c) 2008, John W. Linville @@ -16,17 +16,11 @@ #include #include #include - -#include - #include #include +#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); diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c index 43bab92a4148..0a16127bfd68 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c @@ -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 diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c index 48d6870bbf4e..1fe05e73a17c 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c @@ -27,9 +27,6 @@ #include #include #include - -#include - #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; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c index e22a6732a4c3..80edaa3dea9c 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c @@ -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; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c index dbc7153d0a3d..db71d81b0d4f 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c @@ -21,10 +21,7 @@ #include #include #include - -#include #include - #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) { diff --git a/include/net/lib80211.h b/include/net/lib80211.h deleted file mode 100644 index fd0f15d87d80..000000000000 --- a/include/net/lib80211.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * lib80211.h -- common bits for IEEE802.11 wireless drivers - * - * Copyright (c) 2008, John W. Linville - * - * Some bits copied from old ieee80211 component, w/ original copyright - * notices below: - * - * Original code based on Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * - * Copyright (c) 2004, Intel Corporation - * - */ - -#ifndef LIB80211_H -#define LIB80211_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_WEP_KEYS 4 - -enum { - IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), -}; - -struct module; - -struct lib80211_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 lib80211_crypt_data { - struct list_head list; /* delayed deletion list */ - const struct lib80211_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - -struct lib80211_crypt_info { - char *name; - /* Most clients will already have a lock, - so just point to that. */ - spinlock_t *lock; - - struct lib80211_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; -}; - -int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, - spinlock_t *lock); -void lib80211_crypt_info_free(struct lib80211_crypt_info *info); -int lib80211_register_crypto_ops(const struct lib80211_crypto_ops *ops); -int lib80211_unregister_crypto_ops(const struct lib80211_crypto_ops *ops); -const struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name); -void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, - struct lib80211_crypt_data **crypt); - -#endif /* LIB80211_H */ diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 10345388ad13..733c53ad4de5 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -212,36 +212,3 @@ config CFG80211_KUNIT_TEST If unsure, say N. endif # CFG80211 - -config LIB80211 - tristate - default n - help - This options enables a library of common routines used - by IEEE802.11 wireless LAN drivers. - - Drivers should select this themselves if needed. - -config LIB80211_CRYPT_WEP - tristate - select CRYPTO_LIB_ARC4 - -config LIB80211_CRYPT_CCMP - tristate - select CRYPTO - select CRYPTO_AES - select CRYPTO_CCM - -config LIB80211_CRYPT_TKIP - tristate - select CRYPTO_LIB_ARC4 - -config LIB80211_DEBUG - bool "lib80211 debugging messages" - depends on LIB80211 - default n - help - You can enable this if you want verbose debugging messages - from lib80211. - - If unsure, say N. diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 1d49cc8b6da1..27f211bd9954 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -1,9 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CFG80211) += cfg80211.o -obj-$(CONFIG_LIB80211) += lib80211.o -obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o -obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o -obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o obj-y += tests/ obj-$(CONFIG_WEXT_CORE) += wext-core.o diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c deleted file mode 100644 index 64c447040786..000000000000 --- a/net/wireless/lib80211.c +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * lib80211 -- common bits for IEEE802.11 drivers - * - * Copyright(c) 2008 John W. Linville - * - * Portions copied from old ieee80211 component, w/ original copyright - * notices below: - * - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen - * Portions Copyright (C) 2004, Intel Corporation - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DRV_DESCRIPTION "common routines for IEEE802.11 drivers" - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_AUTHOR("John W. Linville "); -MODULE_LICENSE("GPL"); - -struct lib80211_crypto_alg { - struct list_head list; - const struct lib80211_crypto_ops *ops; -}; - -static LIST_HEAD(lib80211_crypto_algs); -static DEFINE_SPINLOCK(lib80211_crypto_lock); - -static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, - int force); -static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); -static void lib80211_crypt_deinit_handler(struct timer_list *t); - -int lib80211_crypt_info_init(struct lib80211_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, lib80211_crypt_deinit_handler, - 0); - - return 0; -} -EXPORT_SYMBOL(lib80211_crypt_info_init); - -void lib80211_crypt_info_free(struct lib80211_crypt_info *info) -{ - int i; - - lib80211_crypt_quiescing(info); - del_timer_sync(&info->crypt_deinit_timer); - lib80211_crypt_deinit_entries(info, 1); - - for (i = 0; i < NUM_WEP_KEYS; i++) { - struct lib80211_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(lib80211_crypt_info_free); - -static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, - int force) -{ - struct lib80211_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 lib80211_crypt_quiescing(struct lib80211_crypt_info *info) -{ - unsigned long flags; - - spin_lock_irqsave(info->lock, flags); - info->crypt_quiesced = 1; - spin_unlock_irqrestore(info->lock, flags); -} - -static void lib80211_crypt_deinit_handler(struct timer_list *t) -{ - struct lib80211_crypt_info *info = from_timer(info, t, - crypt_deinit_timer); - unsigned long flags; - - lib80211_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 lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, - struct lib80211_crypt_data **crypt) -{ - struct lib80211_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(lib80211_crypt_delayed_deinit); - -int lib80211_register_crypto_ops(const struct lib80211_crypto_ops *ops) -{ - unsigned long flags; - struct lib80211_crypto_alg *alg; - - alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) - return -ENOMEM; - - alg->ops = ops; - - spin_lock_irqsave(&lib80211_crypto_lock, flags); - list_add(&alg->list, &lib80211_crypto_algs); - spin_unlock_irqrestore(&lib80211_crypto_lock, flags); - - printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s'\n", - ops->name); - - return 0; -} -EXPORT_SYMBOL(lib80211_register_crypto_ops); - -int lib80211_unregister_crypto_ops(const struct lib80211_crypto_ops *ops) -{ - struct lib80211_crypto_alg *alg; - unsigned long flags; - - spin_lock_irqsave(&lib80211_crypto_lock, flags); - list_for_each_entry(alg, &lib80211_crypto_algs, list) { - if (alg->ops == ops) - goto found; - } - spin_unlock_irqrestore(&lib80211_crypto_lock, flags); - return -EINVAL; - - found: - printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm '%s'\n", - ops->name); - list_del(&alg->list); - spin_unlock_irqrestore(&lib80211_crypto_lock, flags); - kfree(alg); - return 0; -} -EXPORT_SYMBOL(lib80211_unregister_crypto_ops); - -const struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name) -{ - struct lib80211_crypto_alg *alg; - unsigned long flags; - - spin_lock_irqsave(&lib80211_crypto_lock, flags); - list_for_each_entry(alg, &lib80211_crypto_algs, list) { - if (strcmp(alg->ops->name, name) == 0) - goto found; - } - spin_unlock_irqrestore(&lib80211_crypto_lock, flags); - return NULL; - - found: - spin_unlock_irqrestore(&lib80211_crypto_lock, flags); - return alg->ops; -} -EXPORT_SYMBOL(lib80211_get_crypto_ops); - -static void *lib80211_crypt_null_init(int keyidx) -{ - return (void *)1; -} - -static void lib80211_crypt_null_deinit(void *priv) -{ -} - -static const struct lib80211_crypto_ops lib80211_crypt_null = { - .name = "NULL", - .init = lib80211_crypt_null_init, - .deinit = lib80211_crypt_null_deinit, - .owner = THIS_MODULE, -}; - -static int __init lib80211_init(void) -{ - pr_info(DRV_DESCRIPTION "\n"); - return lib80211_register_crypto_ops(&lib80211_crypt_null); -} - -static void __exit lib80211_exit(void) -{ - lib80211_unregister_crypto_ops(&lib80211_crypt_null); - BUG_ON(!list_empty(&lib80211_crypto_algs)); -} - -module_init(lib80211_init); -module_exit(lib80211_exit); From 4991d2e7ad387ca9cf10298453ceaac17c41a639 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 20:26:56 +0200 Subject: [PATCH 048/126] staging: don't recommend using lib80211 No longer document drivers should switch to lib80211, they really should never have done that. While at it, also remove the recommendation to use cfg80211, if it switches to mac80211 then it implicitly uses cfg80211 but doesn't need to do anything about that, normally. Reviewed-by: Greg Kroah-Hartman Link: https://patch.msgid.link/20241007202707.87481ddcfc00.I2cfb9940807e9c5017a052efcd3d1f2b6dc15fb1@changeid Signed-off-by: Johannes Berg --- drivers/staging/ks7010/TODO | 2 -- drivers/staging/rtl8712/TODO | 1 - drivers/staging/rtl8723bs/TODO | 1 - drivers/staging/vt6655/TODO | 1 - drivers/staging/vt6656/TODO | 1 - 5 files changed, 6 deletions(-) diff --git a/drivers/staging/ks7010/TODO b/drivers/staging/ks7010/TODO index 80c97543b977..8ad05b6e3947 100644 --- a/drivers/staging/ks7010/TODO +++ b/drivers/staging/ks7010/TODO @@ -27,9 +27,7 @@ Now the TODOs: - fix the 'card removal' event when card is inserted when booting - check what other upstream wireless mechanisms can be used instead of the custom ones here -- Switch to use LIB80211. - Switch to use MAC80211. -- Switch to use CFG80211. Please send any patches to: Greg Kroah-Hartman diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO index 847c8c41f4f7..5aed36efa7cb 100644 --- a/drivers/staging/rtl8712/TODO +++ b/drivers/staging/rtl8712/TODO @@ -1,6 +1,5 @@ TODO: - merge Realtek's bugfixes and new features into the driver -- switch to use LIB80211 - switch to use MAC80211 - checkpatch.pl fixes - only a few remain diff --git a/drivers/staging/rtl8723bs/TODO b/drivers/staging/rtl8723bs/TODO index 3d8f5a634a10..4c413f9d3df0 100644 --- a/drivers/staging/rtl8723bs/TODO +++ b/drivers/staging/rtl8723bs/TODO @@ -5,7 +5,6 @@ TODO: - checkpatch.pl fixes - most of the remaining ones are lines too long. Many of them will require refactoring - merge Realtek's bugfixes and new features into the driver -- switch to use LIB80211 - switch to use MAC80211 Please send any patches to Greg Kroah-Hartman , diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO index 63607ef9c97e..7f6870f2ee5d 100644 --- a/drivers/staging/vt6655/TODO +++ b/drivers/staging/vt6655/TODO @@ -8,7 +8,6 @@ TODO: - abstract VT3253 chipset specific code - add common vt665x infrastructure - kill ttype.h -- switch to use LIB80211 - switch to use MAC80211 - verify unsigned long usage for x86-64 arch - reduce .data footprint diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO index 876cdccb6948..cca78d2d3cfe 100644 --- a/drivers/staging/vt6656/TODO +++ b/drivers/staging/vt6656/TODO @@ -8,7 +8,6 @@ TODO: - abstract VT3184 chipset specific code - add common vt665x infrastructure - kill ttype.h -- done -- switch to use LIB80211 - switch to use MAC80211 - use kernel coding style - sparse fixes From 3a1d429ebd43bcfdf3590096ca72cbf593d1598b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 21:02:53 +0200 Subject: [PATCH 049/126] wifi: wext/libipw: move spy implementation to libipw There's no driver left using this other than ipw2200, so move the data bookkeeping and code into libipw. Link: https://patch.msgid.link/20241007210254.037d864cda7d.Ib2197cb056ff05746d3521a5fba637062acb7314@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/ipw2x00/Kconfig | 3 - drivers/net/wireless/intel/ipw2x00/Makefile | 1 + drivers/net/wireless/intel/ipw2x00/ipw2200.c | 10 +-- drivers/net/wireless/intel/ipw2x00/libipw.h | 13 ++++ .../net/wireless/intel/ipw2x00/libipw_rx.c | 2 +- .../net/wireless/intel/ipw2x00/libipw_spy.c | 62 +++++++++---------- include/net/iw_handler.h | 18 ------ net/wireless/Kconfig | 3 - net/wireless/Makefile | 1 - 9 files changed, 51 insertions(+), 62 deletions(-) rename net/wireless/wext-spy.c => drivers/net/wireless/intel/ipw2x00/libipw_spy.c (81%) diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig index d9c042772399..ce34118f1e90 100644 --- a/drivers/net/wireless/intel/ipw2x00/Kconfig +++ b/drivers/net/wireless/intel/ipw2x00/Kconfig @@ -7,7 +7,6 @@ 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 LIBIPW @@ -68,7 +67,6 @@ config IPW2200 depends on PCI && CFG80211 select CFG80211_WEXT_EXPORT select WIRELESS_EXT - select WEXT_SPY select WEXT_PRIV select FW_LOADER select LIBIPW @@ -156,7 +154,6 @@ config LIBIPW tristate depends on PCI && CFG80211 select WIRELESS_EXT - select WEXT_SPY select CRYPTO select CRYPTO_MICHAEL_MIC select CRC32 diff --git a/drivers/net/wireless/intel/ipw2x00/Makefile b/drivers/net/wireless/intel/ipw2x00/Makefile index 60c5faccbe15..91e6091c4ebf 100644 --- a/drivers/net/wireless/intel/ipw2x00/Makefile +++ b/drivers/net/wireless/intel/ipw2x00/Makefile @@ -13,6 +13,7 @@ libipw-objs := \ libipw_rx.o \ libipw_wx.o \ libipw_geo.o \ + libipw_spy.o \ libipw_crypto.o \ libipw_crypto_ccmp.o \ libipw_crypto_tkip.o \ diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index f4fd1fc784b7..0008b4615731 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -9856,10 +9856,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,7 +11636,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; + priv->ieee->spy_enabled = true; net_dev->wireless_data = &priv->wireless_data; net_dev->wireless_handlers = &ipw_wx_handler_def; net_dev->ethtool_ops = &ipw_ethtool_ops; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h index bc727c99ff3c..3c20353e5a41 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw.h +++ b/drivers/net/wireless/intel/ipw2x00/libipw.h @@ -788,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; @@ -1083,4 +1084,16 @@ 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 */ diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c index 1fe05e73a17c..7e41cb7bbfe0 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c @@ -393,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 */ diff --git a/net/wireless/wext-spy.c b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c similarity index 81% rename from net/wireless/wext-spy.c rename to drivers/net/wireless/intel/ipw2x00/libipw_spy.c index b379a0371653..979aeb10aeeb 100644 --- a/net/wireless/wext-spy.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c @@ -14,19 +14,20 @@ #include #include #include +#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; + if (dev->wireless_data && dev->wireless_data->libipw && + dev->wireless_data->libipw->spy_enabled) + return &dev->wireless_data->libipw->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 +37,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 +70,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 +102,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 +129,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 +153,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 +190,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 +230,3 @@ void wireless_spy_update(struct net_device * dev, } } } -EXPORT_SYMBOL(wireless_spy_update); diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index 7af1082ea9a0..a7b502958d27 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -418,8 +418,6 @@ struct iw_spy_data { struct libipw_device; /* The struct */ struct iw_public_data { - /* Driver enhanced spy support */ - struct iw_spy_data * spy_data; /* Legacy structure managed by the ipw2x00-specific IEEE 802.11 layer */ struct libipw_device * libipw; }; @@ -443,22 +441,6 @@ static inline void wireless_nlevent_flush(void) {} /* We may need a function to send a stream of events to user space. * More on that later... */ -/* Standard handler for SIOCSIWSPY */ -int iw_handler_set_spy(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -/* Standard handler for SIOCGIWSPY */ -int iw_handler_get_spy(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -/* Standard handler for SIOCSIWTHRSPY */ -int iw_handler_set_thrspy(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -/* Standard handler for SIOCGIWTHRSPY */ -int iw_handler_get_thrspy(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -/* Driver call to update spy records */ -void wireless_spy_update(struct net_device *dev, unsigned char *address, - struct iw_quality *wstats); - /************************* INLINE FUNCTIONS *************************/ /* * Function that are so simple that it's more efficient inlining them diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 733c53ad4de5..8c8bd8b75708 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -11,9 +11,6 @@ config WEXT_PROC depends on PROC_FS depends on WEXT_CORE -config WEXT_SPY - bool - config WEXT_PRIV bool diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 27f211bd9954..62a83faf0e07 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -4,7 +4,6 @@ obj-y += tests/ obj-$(CONFIG_WEXT_CORE) += wext-core.o obj-$(CONFIG_WEXT_PROC) += wext-proc.o -obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o From 49e3307da0f1dbad776650cf522f984b633d3afe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 21:14:30 +0200 Subject: [PATCH 050/126] wifi: cfg80211: stop exporting wext symbols CFG80211_WEXT_EXPORT is no longer needed, if we only make ipw2200 return the static name for SIOCGIWNAME itself. Link: https://patch.msgid.link/20241007211431.8d4a7242ce92.I66ceb885ddfa52c368feeea1ea884bf988c525f2@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/ipw2x00/Kconfig | 1 - drivers/net/wireless/intel/ipw2x00/ipw2200.c | 10 +++++++++- net/wireless/Kconfig | 9 +-------- net/wireless/scan.c | 2 -- net/wireless/wext-compat.c | 9 --------- net/wireless/wext-compat.h | 6 ------ 6 files changed, 10 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig index ce34118f1e90..5e98be664d38 100644 --- a/drivers/net/wireless/intel/ipw2x00/Kconfig +++ b/drivers/net/wireless/intel/ipw2x00/Kconfig @@ -65,7 +65,6 @@ 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_PRIV select FW_LOADER diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 0008b4615731..c0e9d2109e34 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -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, @@ -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), diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 8c8bd8b75708..2d67b5f2010e 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -185,19 +185,12 @@ config CFG80211_CRDA_SUPPORT If unsure, say Y. config CFG80211_WEXT - bool "cfg80211 wireless extensions compatibility" if !CFG80211_WEXT_EXPORT + bool "cfg80211 wireless extensions compatibility" select WEXT_CORE - default y if CFG80211_WEXT_EXPORT help Enable this option if you need old userspace for wireless extensions with cfg80211-based drivers. -config CFG80211_WEXT_EXPORT - bool - help - Drivers should select this option if they require cfg80211's - wext compatibility symbols to be exported. - config CFG80211_KUNIT_TEST tristate "KUnit tests for cfg80211" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 59a90bf3c0d6..8ba618f4734f 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -3594,7 +3594,6 @@ int cfg80211_wext_siwscan(struct net_device *dev, kfree(creq); return err; } -EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan); static char *ieee80211_scan_add_ies(struct iw_request_info *info, const struct cfg80211_bss_ies *ies, @@ -3966,5 +3965,4 @@ int cfg80211_wext_giwscan(struct net_device *dev, return res; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan); #endif diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index cd9f8f6e298b..0c8d3797a02e 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -30,7 +30,6 @@ int cfg80211_wext_giwname(struct net_device *dev, strcpy(wrqu->name, "IEEE 802.11"); return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwname); int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -69,7 +68,6 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, return ret; } -EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode); int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -105,7 +103,6 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, } return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode); int cfg80211_wext_giwrange(struct net_device *dev, @@ -220,7 +217,6 @@ int cfg80211_wext_giwrange(struct net_device *dev, return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange); /** @@ -281,7 +277,6 @@ int cfg80211_wext_siwrts(struct net_device *dev, wiphy_unlock(&rdev->wiphy); return err; } -EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts); int cfg80211_wext_giwrts(struct net_device *dev, struct iw_request_info *info, @@ -296,7 +291,6 @@ int cfg80211_wext_giwrts(struct net_device *dev, return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts); int cfg80211_wext_siwfrag(struct net_device *dev, struct iw_request_info *info, @@ -327,7 +321,6 @@ int cfg80211_wext_siwfrag(struct net_device *dev, return err; } -EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag); int cfg80211_wext_giwfrag(struct net_device *dev, struct iw_request_info *info, @@ -342,7 +335,6 @@ int cfg80211_wext_giwfrag(struct net_device *dev, return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag); static int cfg80211_wext_siwretry(struct net_device *dev, struct iw_request_info *info, @@ -413,7 +405,6 @@ int cfg80211_wext_giwretry(struct net_device *dev, return 0; } -EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry); static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, struct net_device *dev, bool pairwise, diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index c02eb789e676..8251ca5df8ae 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -5,12 +5,6 @@ #include #include -#ifdef CONFIG_CFG80211_WEXT_EXPORT -#define EXPORT_WEXT_HANDLER(h) EXPORT_SYMBOL_GPL(h) -#else -#define EXPORT_WEXT_HANDLER(h) -#endif /* CONFIG_CFG80211_WEXT_EXPORT */ - int cfg80211_ibss_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wextfreq, char *extra); From 836265d31631e28000fc8917ce697fc687a58724 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 21:35:25 +0200 Subject: [PATCH 051/126] wifi: remove iw_public_data from struct net_device Given the previous patches, we no longer need the struct iw_public_data etc., it's only used by the old Intel drivers (and ps3_gelic creates it but then doesn't use it). Remove all of that, including the pointer in struct net_device. Link: https://patch.msgid.link/20241007213525.8b2d52b60531.I6a27aaf30bded9a0977f07f47fba2bd31a3b3330@changeid Signed-off-by: Johannes Berg --- .../networking/net_cachelines/net_device.rst | 1 - .../net/ethernet/toshiba/ps3_gelic_wireless.c | 1 - .../net/ethernet/toshiba/ps3_gelic_wireless.h | 1 - drivers/net/wireless/intel/ipw2x00/ipw2100.c | 2 -- drivers/net/wireless/intel/ipw2x00/ipw2100.h | 2 -- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 1 - drivers/net/wireless/intel/ipw2x00/ipw2200.h | 2 -- .../net/wireless/intel/ipw2x00/libipw_spy.c | 7 ++++--- include/linux/netdevice.h | 2 -- include/net/iw_handler.h | 18 ------------------ 10 files changed, 4 insertions(+), 33 deletions(-) diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst index 22b07c814f4a..b7d1d4c7a1ab 100644 --- a/Documentation/networking/net_cachelines/net_device.rst +++ b/Documentation/networking/net_cachelines/net_device.rst @@ -51,7 +51,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 diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 44488c153ea2..4fbe4b7cd12a 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -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; } diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h index 1f203d1ae8db..dbabf538e10a 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.h @@ -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; }; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index a89e06c1b8ee..15bf35f2de2a 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -6022,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; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.h b/drivers/net/wireless/intel/ipw2x00/ipw2100.h index b34085ade3aa..6f81f509b9cb 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.h +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.h @@ -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; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index c0e9d2109e34..be1d971b3d32 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -11645,7 +11645,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, net_dev->netdev_ops = &ipw_netdev_ops; priv->ieee->spy_enabled = true; - net_dev->wireless_data = &priv->wireless_data; net_dev->wireless_handlers = &ipw_wx_handler_def; net_dev->ethtool_ops = &ipw_ethtool_ops; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h index 46f119123b49..d3db54e6d37c 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h @@ -1274,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; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_spy.c b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c index 979aeb10aeeb..ba876e92f7f6 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_spy.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_spy.c @@ -18,9 +18,10 @@ static struct iw_spy_data *get_spydata(struct net_device *dev) { - if (dev->wireless_data && dev->wireless_data->libipw && - dev->wireless_data->libipw->spy_enabled) - return &dev->wireless_data->libipw->spy_data; + struct libipw_device *ieee = netdev_priv(dev); + + if (ieee->spy_enabled) + return &ieee->spy_data; return NULL; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e87b5e488325..f0abed1e6e45 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1773,7 +1773,6 @@ enum netdev_reg_state { * @wireless_handlers: List of functions to handle Wireless Extensions, * instead of ioctl, * see for details. - * @wireless_data: Instance data managed by the core of wireless extensions * * @netdev_ops: Includes several pointers to callbacks, * if one wants to override the ndo_*() functions @@ -2150,7 +2149,6 @@ struct net_device { #ifdef CONFIG_WIRELESS_EXT const struct iw_handler_def *wireless_handlers; - struct iw_public_data *wireless_data; #endif const struct ethtool_ops *ethtool_ops; #ifdef CONFIG_NET_L3_MASTER_DEV diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index a7b502958d27..fc44fcca1d5c 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -404,24 +404,6 @@ struct iw_spy_data { u_char spy_thr_under[IW_MAX_SPY]; }; -/* --------------------- DEVICE WIRELESS DATA --------------------- */ -/* - * This is all the wireless data specific to a device instance that - * is managed by the core of Wireless Extensions or the 802.11 layer. - * We only keep pointer to those structures, so that a driver is free - * to share them between instances. - * This structure should be initialised before registering the device. - * Access to this data follow the same rules as any other struct net_device - * data (i.e. valid as long as struct net_device exist, same locking rules). - */ -/* Forward declaration */ -struct libipw_device; -/* The struct */ -struct iw_public_data { - /* Legacy structure managed by the ipw2x00-specific IEEE 802.11 layer */ - struct libipw_device * libipw; -}; - /**************************** PROTOTYPES ****************************/ /* * Functions part of the Wireless Extensions (defined in net/wireless/wext-core.c). From aee809aaa2d13bf560fe38d28c4969605e6d9d0e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 21:47:16 +0200 Subject: [PATCH 052/126] wifi: cfg80211: unexport wireless_nlevent_flush() This no longer needs to be exported, so don't export it. Link: https://patch.msgid.link/20241007214715.3dd736dc3ac0.I1388536e99c37f28a007dd753c473ad21513d9a9@changeid Signed-off-by: Johannes Berg --- include/net/iw_handler.h | 6 ------ net/wireless/wext-compat.h | 6 ++++++ net/wireless/wext-core.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index fc44fcca1d5c..804587b7592b 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -413,12 +413,6 @@ struct iw_spy_data { /* Send a single event to user space */ void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, const char *extra); -#ifdef CONFIG_WEXT_CORE -/* flush all previous wext events - if work is done from netdev notifiers */ -void wireless_nlevent_flush(void); -#else -static inline void wireless_nlevent_flush(void) {} -#endif /* We may need a function to send a stream of events to user space. * More on that later... */ diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index 8251ca5df8ae..f680dd134582 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -5,6 +5,12 @@ #include #include +#ifdef CONFIG_WEXT_CORE +void wireless_nlevent_flush(void); +#else +static inline void wireless_nlevent_flush(void) {} +#endif + int cfg80211_ibss_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wextfreq, char *extra); diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 3bb04b05c5ce..00c640b3e86e 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -20,6 +20,7 @@ #include #include #include +#include "wext-compat.h" typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *, unsigned int, struct iw_request_info *, @@ -356,7 +357,6 @@ void wireless_nlevent_flush(void) } up_read(&net_rwsem); } -EXPORT_SYMBOL_GPL(wireless_nlevent_flush); static int wext_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void *ptr) From 9e1a98aac11b757e2634304bbe6bed5f5a58e0ee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 21:50:25 +0200 Subject: [PATCH 053/126] wifi: wext: merge adjacent CONFIG_COMPAT ifdef blocks Simplify this, and also add a comment at the #endif. Link: https://patch.msgid.link/20241007215025.5ecdad1e02ed.I54efa895efc496e06ba41e1c39c9df9e23b0171f@changeid Signed-off-by: Johannes Berg --- include/linux/wireless.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/linux/wireless.h b/include/linux/wireless.h index e6e34d74dda0..03e5d3fe226d 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h @@ -21,8 +21,7 @@ struct compat_iw_point { __u16 length; __u16 flags; }; -#endif -#ifdef CONFIG_COMPAT + struct __compat_iw_event { __u16 len; /* Real length of this stuff */ __u16 cmd; /* Wireless IOCTL */ @@ -49,5 +48,5 @@ struct __compat_iw_event { #define IW_EV_COMPAT_POINT_LEN \ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \ IW_EV_COMPAT_POINT_OFF) -#endif +#endif /* CONFIG_COMPAT */ #endif /* _LINUX_WIRELESS_H */ From ff919efb5fe8256fba132b5f2c58df3c38bdd0b3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 22:00:03 +0200 Subject: [PATCH 054/126] wireless: wext: shorten struct iw_ioctl_description There's no need for "future" extensions in an internal struct, and we don't need a u32 for flags, use just a u8. Also remove the unused IW_DESCR_FLAG_WAIT flag. Link: https://patch.msgid.link/20241007220003.309bd52fa763.I9a1229fa7f2be53d4f50e63671ed441d0968bb41@changeid Signed-off-by: Johannes Berg --- include/net/iw_handler.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index 804587b7592b..c9b46b996197 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -279,8 +279,6 @@ #define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ /* SET : Omit payload from generated iwevent */ #define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */ -/* Driver level flags */ -#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ /****************************** TYPES ******************************/ @@ -373,11 +371,10 @@ struct iw_handler_def { */ struct iw_ioctl_description { __u8 header_type; /* NULL, iw_point or other */ - __u8 token_type; /* Future */ + __u8 flags; /* Special handling of the request */ __u16 token_size; /* Granularity of payload */ __u16 min_tokens; /* Min acceptable token number */ __u16 max_tokens; /* Max acceptable token number */ - __u32 flags; /* Special handling of the request */ }; /* Need to think of short header translation table. Later. */ From db03488897a70367aeafe82d07a78943d2a6068e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 9 Oct 2024 08:33:05 +0200 Subject: [PATCH 055/126] Revert "wifi: cfg80211: unexport wireless_nlevent_flush()" Revert this, I neglected to take into account the fact that cfg80211 itself can be a module, but wext is always builtin. Fixes: aee809aaa2d1 ("wifi: cfg80211: unexport wireless_nlevent_flush()") Signed-off-by: Johannes Berg --- include/net/iw_handler.h | 6 ++++++ net/wireless/wext-compat.h | 6 ------ net/wireless/wext-core.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index c9b46b996197..b80e474cb0aa 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -410,6 +410,12 @@ struct iw_spy_data { /* Send a single event to user space */ void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, const char *extra); +#ifdef CONFIG_WEXT_CORE +/* flush all previous wext events - if work is done from netdev notifiers */ +void wireless_nlevent_flush(void); +#else +static inline void wireless_nlevent_flush(void) {} +#endif /* We may need a function to send a stream of events to user space. * More on that later... */ diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index f680dd134582..8251ca5df8ae 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -5,12 +5,6 @@ #include #include -#ifdef CONFIG_WEXT_CORE -void wireless_nlevent_flush(void); -#else -static inline void wireless_nlevent_flush(void) {} -#endif - int cfg80211_ibss_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wextfreq, char *extra); diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 00c640b3e86e..3bb04b05c5ce 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -20,7 +20,6 @@ #include #include #include -#include "wext-compat.h" typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *, unsigned int, struct iw_request_info *, @@ -357,6 +356,7 @@ void wireless_nlevent_flush(void) } up_read(&net_rwsem); } +EXPORT_SYMBOL_GPL(wireless_nlevent_flush); static int wext_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void *ptr) From e6802d1e6974026c0862afc685276ebf31fc1b2d Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Thu, 3 Oct 2024 18:51:37 +0800 Subject: [PATCH 056/126] wifi: rtw89: coex: Update priority setting for Wi-Fi is scanning Update coexistence priority setting for Wi-Fi scanning channel, the new setting will allow Wi-Fi do RX while Bluetooth audio is not busy. Forced to set new TDMA policy while RF calibration request come, to make sure the calibration can do well, and switch to normal setting while the calibration is done. Remove the code that no longer use. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241003105140.10867-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 58 +++++++++++++---------- drivers/net/wireless/realtek/rtw89/core.h | 1 - 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 6da1193422fb..9cd036112a48 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -125,6 +125,9 @@ static const u32 cxtbl[] = { 0xfafaaafa, /* 23 */ 0xfafffaff, /* 24 */ 0xea6a5a5a, /* 25 */ + 0xfaff5aff, /* 26 */ + 0xffffdfff, /* 27 */ + 0xe6555555, /* 28 */ }; static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { @@ -224,7 +227,7 @@ static const union rtw89_btc_wl_state_map btc_scanning_map = { .scan = 1, .connecting = 1, .roaming = 1, - .transacting = 1, + .dbccing = 1, ._4way = 1, }, }; @@ -3017,7 +3020,7 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev) struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; if (wl->status.map.connecting || wl->status.map._4way || - wl->status.map.roaming) { + wl->status.map.roaming || wl->status.map.dbccing) { cx->state_map = BTC_WLINKING; } else if (wl->status.map.scan) { /* wl scan */ if (bt_linfo->status.map.inq_pag) @@ -3721,8 +3724,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) tbl_w1 = cxtbl[16]; } - btc->bt_req_en = false; - switch (type) { case BTC_CXP_USERDEF0: btc->update_policy_force = true; @@ -3744,6 +3745,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) case BTC_CXP_OFF_WL: _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); break; + case BTC_CXP_OFF_WL2: + _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); + _slot_set_type(btc, CXST_OFF, SLOT_ISO); + break; case BTC_CXP_OFF_EQ0: _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); _slot_set_type(btc, CXST_OFF, SLOT_ISO); @@ -3757,6 +3762,12 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) case BTC_CXP_OFF_EQ3: _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); break; + case BTC_CXP_OFF_EQ4: + _slot_set_tbl(btc, CXST_OFF, cxtbl[26]); + break; + case BTC_CXP_OFF_EQ5: + _slot_set_tbl(btc, CXST_OFF, cxtbl[27]); + break; case BTC_CXP_OFF_BWB0: _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); break; @@ -3788,7 +3799,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) } break; case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ - btc->bt_req_en = true; _write_scbd(rtwdev, BTC_WSCB_TDMA, true); *t = t_def[CXTD_OFF_EXT]; @@ -3831,9 +3841,9 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); break; case BTC_CXP_OFFE_2GBWMIXB: - _slot_set(btc, CXST_E2G, 0, 0x55555555, SLOT_MIX); + _slot_set(btc, CXST_E2G, 0, 0xea5a5555, SLOT_MIX); _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, - cpu_to_le32(0x55555555), s_def[CXST_EBT].cxtype); + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); break; case BTC_CXP_OFFE_WL: /* for 4-way */ _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX); @@ -3842,6 +3852,8 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) default: break; } + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); break; @@ -4246,6 +4258,7 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec, _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); break; case BTC_ANT_WRFK: + case BTC_ANT_WRFK2: rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL); _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO); _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); @@ -4814,8 +4827,16 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev) rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n", __func__, rfk.band); - _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK); - _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK); + btc->dm.tdma_instant_excute = 1; + + if (rfk.state == BTC_WRFK_ONESHOT_START || + btc->ant_type == BTC_ANT_SHARED) { + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK2); + _set_policy(rtwdev, BTC_CXP_OFF_WL2, BTC_ACT_WL_RFK); + } else { + _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK); + _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK); + } } static void _set_btg_ctrl(struct rtw89_dev *rtwdev) @@ -5334,7 +5355,7 @@ static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev) policy_type = BTC_CXP_OFFE_WL; else if (btc->cx.wl.status.val & btc_scanning_map.val) policy_type = BTC_CXP_OFFE_2GBWMIXB; - else if (btc->cx.bt.link_info.profile_cnt.now == 0) + else if (btc->cx.bt.link_info.status.map.connect == 0) policy_type = BTC_CXP_OFFE_2GISOB; else policy_type = BTC_CXP_OFFE_2GBWISOB; @@ -6944,18 +6965,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) goto exit; } - if (cx->state_map == BTC_WLINKING) { - if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA || - mode == BTC_WLINK_5G) { - _action_wl_scan(rtwdev); - bt->scan_rx_low_pri = false; - goto exit; - } - } - - if (wl->status.map.scan) { + if (wl->status.val & btc_scanning_map.val) { _action_wl_scan(rtwdev); - bt->scan_rx_low_pri = false; + bt->scan_rx_low_pri = true; goto exit; } @@ -7191,10 +7203,6 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++; - wl->scan_info.band[phy_idx] = band; - wl->scan_info.phy_map |= BIT(phy_idx); - _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); - if (rtwdev->dbcc_en) { wl->dbcc_info.scan_band[phy_idx] = band; _update_dbcc_band(rtwdev, phy_idx); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index d9cf39cc4cec..ff0d3253f1cb 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -1352,7 +1352,6 @@ struct rtw89_btc_wl_smap { u32 connecting: 1; u32 roaming: 1; u32 dbccing: 1; - u32 transacting: 1; u32 _4way: 1; u32 rf_off: 1; u32 lps: 2; From afa753d823aeef920e0a98272fd6842d4620292f Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Thu, 3 Oct 2024 18:51:38 +0800 Subject: [PATCH 057/126] wifi: rtw89: coex: Reorder Bluetooth info related logic Reorder Bluetooth firmware related event index, it should be the same with Wi-Fi firmware definition. To fix coexistence can not recognize Bluetooth PAN(Personal area network) profile correctly, modified the related logic. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241003105140.10867-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 74 +++++++++++++---------- drivers/net/wireless/realtek/rtw89/core.h | 2 + 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 9cd036112a48..1c0169e2927e 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -5267,8 +5267,14 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; + struct rtw89_btc_dm *dm = &btc->dm; u8 profile_map = 0; + if (dm->freerun_chk) { + _action_freerun(rtwdev); + return; + } + if (bt_linfo->hfp_desc.exist) profile_map |= BTC_BT_HFP; @@ -5283,30 +5289,20 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) switch (profile_map) { case BTC_BT_NOPROFILE: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); - else if (pan.active) + if (pan.active) _action_bt_pan(rtwdev); else _action_bt_idle(rtwdev); break; case BTC_BT_HFP: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); - else - _action_bt_hfp(rtwdev); + _action_bt_hfp(rtwdev); break; case BTC_BT_HFP | BTC_BT_HID: case BTC_BT_HID: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); - else - _action_bt_hid(rtwdev); + _action_bt_hid(rtwdev); break; case BTC_BT_A2DP: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); - else if (a2dp.sink) + if (a2dp.sink) _action_bt_a2dpsink(rtwdev); else if (bt_linfo->multi_link.now && !hid.pair_cnt) _action_bt_a2dp_pan(rtwdev); @@ -5319,13 +5315,18 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) case BTC_BT_A2DP | BTC_BT_HFP: case BTC_BT_A2DP | BTC_BT_HID: case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else if (pan.active) + _action_bt_a2dp_pan_hid(rtwdev); else _action_bt_a2dp_hid(rtwdev); break; case BTC_BT_A2DP | BTC_BT_PAN: - _action_bt_a2dp_pan(rtwdev); + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else + _action_bt_a2dp_pan(rtwdev); break; case BTC_BT_PAN | BTC_BT_HFP: case BTC_BT_PAN | BTC_BT_HID: @@ -5335,7 +5336,10 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID: case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP: default: - _action_bt_a2dp_pan_hid(rtwdev); + if (a2dp.sink) + _action_bt_a2dpsink(rtwdev); + else + _action_bt_a2dp_pan_hid(rtwdev); break; } } @@ -6927,6 +6931,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) bt->scan_rx_low_pri = false; igno_bt = false; + dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */ + if (always_freerun) { _action_freerun(rtwdev); igno_bt = true; @@ -7397,13 +7403,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) "[BTC], %s(): bt_info[2]=0x%02x\n", __func__, bt->raw_info[2]); - /* reset to mo-connect before update */ - b->status.val = BTC_BLINK_NOCONNECT; b->profile_cnt.last = b->profile_cnt.now; - b->relink.last = b->relink.now; - a2dp->exist_last = a2dp->exist; - b->multi_link.last = b->multi_link.now; - bt->inq_pag.last = bt->inq_pag.now; b->profile_cnt.now = 0; hid->type = 0; @@ -7422,7 +7422,8 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) b->profile_cnt.now += (u8)hid->exist; a2dp->exist = btinfo.lb2.a2dp; b->profile_cnt.now += (u8)a2dp->exist; - pan->active = btinfo.lb2.pan; + pan->exist = btinfo.lb2.pan; + b->profile_cnt.now += (u8)pan->exist; btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK); /* parse raw info low-Byte3 */ @@ -7446,8 +7447,14 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) /* parse raw info high-Byte1 */ btinfo.val = bt->raw_info[BTC_BTINFO_H1]; b->status.map.ble_connect = btinfo.hb1.ble_connect; - if (btinfo.hb1.ble_connect) - hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU); + if (btinfo.hb1.ble_connect) { + if (hid->exist) + hid->type |= BTC_HID_BLE; + else if (btinfo.hb1.voice) + hid->type |= BTC_HID_RCU_VOICE; + else + hid->type |= BTC_HID_RCU; + } cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit); bt->reinit = btinfo.hb1.reinit; @@ -7459,7 +7466,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) if (bt->igno_wl && !cx->wl.status.map.rf_off) _set_bt_ignore_wlan_act(rtwdev, false); - hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0); bt->ble_scan_en = btinfo.hb1.ble_scan; cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw); @@ -7469,8 +7475,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) /* parse raw info high-Byte2 */ btinfo.val = bt->raw_info[BTC_BTINFO_H2]; - pan->exist = btinfo.hb2.pan_active; - b->profile_cnt.now += (u8)pan->exist; + pan->active = !!btinfo.hb2.pan_active; cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update); b->afh_update = btinfo.hb2.afh_update; @@ -7478,8 +7483,9 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) b->slave_role = btinfo.hb2.slave; hid->slot_info = btinfo.hb2.hid_slot; hid->pair_cnt = btinfo.hb2.hid_cnt; - hid->type |= (hid->slot_info == BTC_HID_218 ? - BTC_HID_218 : BTC_HID_418); + if (!b->status.map.ble_connect || hid->pair_cnt > 1) + hid->type |= (hid->slot_info == BTC_HID_218 ? + BTC_HID_218 : BTC_HID_418); /* parse raw info high-Byte3 */ btinfo.val = bt->raw_info[BTC_BTINFO_H3]; a2dp->bitpool = btinfo.hb3.a2dp_bitpool; @@ -8031,8 +8037,10 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, return; switch (func) { - case BTF_EVNT_RPT: case BTF_EVNT_BUF_OVERFLOW: + pfwinfo->event[func]++; + break; + case BTF_EVNT_RPT: pfwinfo->event[func]++; /* Don't need rtw89_leave_ps_mode() */ btc_fw_event(rtwdev, func, buf, len); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ff0d3253f1cb..c89c380f2871 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2938,6 +2938,7 @@ struct rtw89_btc_dm { u8 wl_pre_agc: 2; u8 wl_lna2: 1; + u8 freerun_chk: 1; u8 wl_pre_agc_rb: 2; u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */ u8 slot_req_more: 1; @@ -2976,6 +2977,7 @@ enum rtw89_btc_btf_fw_event { BTF_EVNT_BT_REG = 3, BTF_EVNT_CX_RUNINFO = 4, BTF_EVNT_BT_PSD = 5, + BTF_EVNT_BT_DEV_INFO = 6, BTF_EVNT_BUF_OVERFLOW, BTF_EVNT_C2H_LOOPBACK, BTF_EVNT_MAX, From e7a7f705a85439dae22796c9404a93075b5b4df2 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Thu, 3 Oct 2024 18:51:39 +0800 Subject: [PATCH 058/126] wifi: rtw89: coex: Solved BT PAN profile idle decrease Wi-Fi throughput Some Bluetooth device will make up connection as PAN link, though the connection is idle, it will still report the PAN link is active. The coexistence mechanism will enable TDMA to protect the PAN, it makes Wi-Fi throughput degrade at least 50%. But the link is idle, don't need so much bandwidth. Add TDMA case to let Wi-Fi can do traffic 80% bandwidth. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241003105140.10867-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 1c0169e2927e..3350e982ca5a 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -4636,12 +4636,21 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) static void _action_bt_pan(struct rtw89_dev *rtwdev) { struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; + struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; + struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); switch (btc->cx.state_map) { case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */ - _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN); + if (a2dp.active || !pan.exist) { + btc->dm.slot_dur[CXST_W1] = 80; + btc->dm.slot_dur[CXST_B1] = 20; + _set_policy(rtwdev, BTC_CXP_PFIX_TDW1B1, BTC_ACT_BT_PAN); + } else { + _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN); + } break; case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */ _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN); From 5ab2f7830228af5db5555b5a2cde9e153f63407b Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Thu, 3 Oct 2024 18:51:40 +0800 Subject: [PATCH 059/126] wifi: rtw89: coex: Add function to reorder Wi-Fi firmware report index To parsing firmware report correctly, driver need to re-order the report index to match with different chips and different Wi-Fi firmware version. Use wrong index to parse the report will lead the coexistence run into wrong mechanism. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241003105140.10867-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 85 +++++++++++++++++++---- drivers/net/wireless/realtek/rtw89/core.h | 4 +- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 3350e982ca5a..989e6e882c6e 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -137,77 +137,88 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, - .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6, + .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800, + .max_role_num = 6, }, {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, - .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6, + .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800, + .max_role_num = 6, }, {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, + .max_role_num = 6, }, {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, + .max_role_num = 5, }, {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0), .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, + .max_role_num = 5, }, {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0), .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, + .max_role_num = 5, }, {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, + .max_role_num = 6, }, {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800, + .max_role_num = 6, }, {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0), .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280, + .max_role_num = 5, }, {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0), .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280, + .max_role_num = 5, }, {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0), .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024, + .max_role_num = 5, }, /* keep it to be the last as default entry */ @@ -216,7 +227,8 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0, - .fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5, + .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024, + .max_role_num = 5, }, }; @@ -8029,6 +8041,53 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) } } +static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func) +{ + struct rtw89_btc *btc = &rtwdev->btc; + const struct rtw89_btc_ver *ver = btc->ver; + + switch (func) { + case BTF_EVNT_RPT: + case BTF_EVNT_BT_INFO: + case BTF_EVNT_BT_SCBD: + case BTF_EVNT_BT_REG: + case BTF_EVNT_CX_RUNINFO: + case BTF_EVNT_BT_PSD: + return func; + case BTF_EVNT_BT_DEV_INFO: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_BUF_OVERFLOW; + else + return BTF_EVNT_BT_DEV_INFO; + case BTF_EVNT_BT_LEAUDIO_INFO: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_C2H_LOOPBACK; + else if (ver->fwc2hfunc == 1) + return BTF_EVNT_BUF_OVERFLOW; + else if (ver->fwc2hfunc == 2) + return func; + else + return BTF_EVNT_MAX; + case BTF_EVNT_BUF_OVERFLOW: + if (ver->fwc2hfunc == 0) + return BTF_EVNT_MAX; + else if (ver->fwc2hfunc == 1) + return BTF_EVNT_C2H_LOOPBACK; + else if (ver->fwc2hfunc == 2) + return func; + else + return BTF_EVNT_MAX; + case BTF_EVNT_C2H_LOOPBACK: + if (ver->fwc2hfunc == 2) + return func; + else + return BTF_EVNT_MAX; + case BTF_EVNT_MAX: + default: + return BTF_EVNT_MAX; + } +} + void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len, u8 class, u8 func) { @@ -8045,6 +8104,8 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, if (class != BTFC_FW_EVENT) return; + func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func); + switch (func) { case BTF_EVNT_BUF_OVERFLOW: pfwinfo->event[func]++; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index c89c380f2871..ff7c90533c62 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2977,7 +2977,8 @@ enum rtw89_btc_btf_fw_event { BTF_EVNT_BT_REG = 3, BTF_EVNT_CX_RUNINFO = 4, BTF_EVNT_BT_PSD = 5, - BTF_EVNT_BT_DEV_INFO = 6, + BTF_EVNT_BT_DEV_INFO = 6, /* fwc2hfunc > 0 */ + BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */ BTF_EVNT_BUF_OVERFLOW, BTF_EVNT_C2H_LOOPBACK, BTF_EVNT_MAX, @@ -3144,6 +3145,7 @@ struct rtw89_btc_ver { u8 fcxinit; u8 fwevntrptl; + u8 fwc2hfunc; u8 drvinfo_type; u16 info_buf; u8 max_role_num; From fc442560016d9246460b317771bebbcbaf910aa2 Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Fri, 4 Oct 2024 14:54:08 +0800 Subject: [PATCH 060/126] wifi: rtw89: wow: do not configure CPU IO to receive packets for old firmware The older firmware of 8852A and 8852B can't receive packets via CPU IO function and will lead to WoWLAN fail if calling it. So use firmware feature to distinguish. Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241004065408.10261-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 2 ++ drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ff7c90533c62..38df161bfd35 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4445,6 +4445,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_WOW_REASON_V1, RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, RTW89_FW_FEATURE_RFK_RXDCK_V0, + RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX, }; struct rtw89_fw_suit { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 752a3c2536d4..2c2fdf21f065 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -665,11 +665,13 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), + __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX), __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), + __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER), diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index b3f417003087..e09f926bb4a0 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -6521,6 +6521,9 @@ int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable) struct rtw89_mac_c2h_info c2h_info = {}; u32 ret; + if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw)) + return 0; + h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL; h2c_info.content_len = sizeof(h2c_info.u.hdr); h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN); @@ -6557,6 +6560,9 @@ static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow) rtw89_write32(rtwdev, R_AX_TF_FWD, 0); rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0); + if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw)) + return 0; + if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY); else From 5ab202f26746925d10422ea89e8413f33869ac4e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 11 Oct 2024 11:58:20 +0200 Subject: [PATCH 061/126] wifi: ipw: select CRYPTO_LIB_ARC4 With the WEP/TKIP code having moved to libipw, it now needs to select CRYPTO_LIB_ARC4 to have the dependency, and I forgot to move that. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202410111727.FxATs8Yj-lkp@intel.com/ Fixes: 02f220b52670 ("wifi: ipw2x00/lib80211: move remaining lib80211 into libipw") Signed-off-by: Johannes Berg Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241011115820.070c468b271d.Iac76e81b5cd9a5b949b8c154381128e8131d581d@changeid --- drivers/net/wireless/intel/ipw2x00/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig index 5e98be664d38..b92df91adb3a 100644 --- a/drivers/net/wireless/intel/ipw2x00/Kconfig +++ b/drivers/net/wireless/intel/ipw2x00/Kconfig @@ -155,6 +155,7 @@ config LIBIPW select WIRELESS_EXT select CRYPTO select CRYPTO_MICHAEL_MIC + select CRYPTO_LIB_ARC4 select CRC32 help This option enables the hardware independent IEEE 802.11 From 0d7c2194f17c764df0354af13551cc6f92ef5a44 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 18 Sep 2024 13:10:26 +0200 Subject: [PATCH 062/126] wifi: mwifiex: add missing locking for cfg80211 calls cfg80211_rx_assoc_resp() and cfg80211_rx_mlme_mgmt() need to be called with the wiphy locked, so lock it before calling these functions. Fixes: 36995892c271 ("wifi: mwifiex: add host mlme for client mode") Reviewed-by: Francesco Dolcini Signed-off-by: Sascha Hauer Acked-by: Brian Norris Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240918-mwifiex-cleanup-1-v2-1-2d0597187d3c@pengutronix.de --- drivers/net/wireless/marvell/mwifiex/cmdevt.c | 2 ++ drivers/net/wireless/marvell/mwifiex/util.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 1cff001bdc51..b30ed321c625 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -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; } } diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c index 42c04bf858da..1f1f6280a0f2 100644 --- a/drivers/net/wireless/marvell/mwifiex/util.c +++ b/drivers/net/wireless/marvell/mwifiex/util.c @@ -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 && From c8945c8cd41ab4f8d0d59a4e9861e9c9017840af Mon Sep 17 00:00:00 2001 From: Yan Zhen Date: Fri, 20 Sep 2024 10:59:17 +0800 Subject: [PATCH 063/126] wifi: rt2x00: convert comma to semicolon To ensure code clarity and prevent potential errors, it's advisable to employ the ';' as a statement separator, except when ',' are intentionally used for specific purposes. Signed-off-by: Yan Zhen Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240920025917.1959932-1-yanzhen@vivo.com --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 3bb81bcff0ac..60c2a12e9d5e 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -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); From 98ca3178ad797a5ae9df50a69be49292d1734485 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 26 Sep 2024 21:50:55 +0200 Subject: [PATCH 064/126] wifi: wilc1000: Keep slot powered on during suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WILC3000 can suspend and enter low power state. According to local measurements, the WILC3000 consumes the same amount of power if the slot is powered up and WILC3000 is suspended, and if the WILC3000 is powered off. Use the former option, keep the WILC3000 powered up as that allows for things like WoWlan to work. Note that this is tested on WILC3000 only, not on WILC1000 . Signed-off-by: Marek Vasut Tested-by: Alexis Lothoré Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240926195113.2823392-1-marex@denx.de --- drivers/net/wireless/microchip/wilc1000/sdio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index b4da05d5a498..d67662b6b2a1 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -969,7 +969,6 @@ static int wilc_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); struct wilc *wilc = sdio_get_drvdata(func); - int ret; dev_info(dev, "sdio suspend\n"); @@ -983,13 +982,7 @@ static int wilc_sdio_suspend(struct device *dev) wilc_sdio_disable_interrupt(wilc); - ret = wilc_sdio_reset(wilc); - if (ret) { - dev_err(&func->dev, "Fail reset sdio\n"); - return ret; - } - - return 0; + return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } static int wilc_sdio_resume(struct device *dev) From 1b292a161cfb02868ffd0dc8b87a4a84b633f941 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:10 +0200 Subject: [PATCH 065/126] dt-bindings: wireless: wilc1000: Document WILC3000 compatible string Document compatible string for the WILC3000 chip. The chip is similar to WILC1000, except that the register layout is slightly different and it does not support WPA3/SAE. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-1-marex@denx.de --- .../bindings/net/wireless/microchip,wilc1000.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml index 2460ccc08237..5d40f22765bb 100644 --- a/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml +++ b/Documentation/devicetree/bindings/net/wireless/microchip,wilc1000.yaml @@ -16,7 +16,11 @@ description: properties: compatible: - const: microchip,wilc1000 + oneOf: + - items: + - const: microchip,wilc3000 + - const: microchip,wilc1000 + - const: microchip,wilc1000 reg: true From 719e469eb9a29a0ef624af51878c8d7217929b84 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:11 +0200 Subject: [PATCH 066/126] wifi: wilc1000: Clean up usage of wilc_get_chipid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the use of wilc_get_chipid(), use cached chip ID wherever possible. Remove duplicated partial chip ID read implementations from the driver. Update wilc_get_chipid() to always read the chip ID out of the hardware and update the cached chip ID, and make it return a proper return value instead of a chipid. Call wilc_get_chipid() early to make the cached chip ID available to various sites using is_wilc1000() to access the cached chip ID. Reviewed-by: Alexis Lothoré Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-2-marex@denx.de --- .../net/wireless/microchip/wilc1000/netdev.c | 6 +- .../net/wireless/microchip/wilc1000/sdio.c | 17 +---- drivers/net/wireless/microchip/wilc1000/spi.c | 2 +- .../net/wireless/microchip/wilc1000/wlan.c | 75 +++++++++++-------- .../net/wireless/microchip/wilc1000/wlan.h | 2 +- 5 files changed, 53 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 9ecf3fb29b55..086e70d833e0 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -195,13 +195,13 @@ 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; int ret; - chip_id = wilc_get_chipid(wilc, false); + if (!is_wilc1000(wilc->chipid)) + return -EINVAL; - netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id, + netdev_info(dev, "WILC1000 loading firmware [%s]\n", WILC1000_FW(WILC1000_API_VER)); ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER), diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index d67662b6b2a1..7bc6d788f33a 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -182,6 +182,10 @@ 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_load_mac_from_nv(wilc); if (ret) { pr_err("Can not retrieve MAC address from chip\n"); @@ -667,7 +671,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 +759,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; } diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 05b577b1068e..81cf82c9175e 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -245,7 +245,7 @@ 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; diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 533939e71534..28212ff28c11 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -1402,9 +1402,38 @@ 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, 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; struct wilc_vif *vif = netdev_priv(dev); @@ -1412,9 +1441,11 @@ static int init_chip(struct net_device *dev) acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); - 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, ®); @@ -1445,34 +1476,6 @@ static int init_chip(struct net_device *dev) 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; - } - - wilc->chipid = chipid; - } - return wilc->chipid; -} - int wilc_load_mac_from_nv(struct wilc *wl) { int ret = -EINVAL; @@ -1535,9 +1538,19 @@ int wilc_wlan_init(struct net_device *dev) if (!wilc->hif_func->hif_is_init(wilc)) { acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); ret = wilc->hif_func->hif_init(wilc, false); + if (!ret) + ret = wilc_get_chipid(wilc); release_bus(wilc, WILC_BUS_RELEASE_ONLY); if (ret) goto fail; + + if (!is_wilc1000(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) diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index dd2fb3c2f06a..44dce53d2491 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h @@ -443,6 +443,6 @@ void chip_wakeup(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 From 0a6ea2e235efc129da8cde277adc7915077357ba Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:12 +0200 Subject: [PATCH 067/126] wifi: wilc1000: Fold chip_allow_sleep()/chip_wakeup() into wlan.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neither chip_allow_sleep()/chip_wakeup() is used outside of wlan.c . Make both functions static and remove both the exported symbol and entries from wlan.h . Make chip_allow_sleep() return error code in preparation for the follow up patches. Move acquire_bus() and release_bus() to avoid forward declaration of chip_allow_sleep()/chip_wakeup(). Reviewed-by: Alexis Lothoré Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-3-marex@denx.de --- .../net/wireless/microchip/wilc1000/wlan.c | 49 +++++++++---------- .../net/wireless/microchip/wilc1000/wlan.h | 2 - 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 28212ff28c11..875f0bb8af67 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -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(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,28 @@ 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 void chip_wakeup(struct wilc *wilc) { u32 ret = 0; u32 clk_status_val = 0, trials = 0; @@ -674,7 +660,20 @@ void chip_wakeup(struct wilc *wilc) if (wilc->io_type == WILC_HIF_SPI) wilc->hif_func->hif_reset(wilc); } -EXPORT_SYMBOL_GPL(chip_wakeup); + +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); +} void host_wakeup_notify(struct wilc *wilc) { diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index 44dce53d2491..90ba76cf14dd 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h @@ -438,8 +438,6 @@ 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 wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, u32 count); int wilc_wlan_init(struct net_device *dev); From 1241c5650ff7a0236cebb89acca8aade48839fd6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:13 +0200 Subject: [PATCH 068/126] wifi: wilc1000: Fill in missing error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add error handling to chip_wakeup() and propagate the errors throughout the entire driver. Add error handling to acquire_bus()/release_bus() and host_sleep_notify()/host_wakeup_notify() functions as a result as well. Fill the error handling to all call sites. Reviewed-by: Alexis Lothoré Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-4-marex@denx.de --- .../net/wireless/microchip/wilc1000/sdio.c | 11 +- .../net/wireless/microchip/wilc1000/wlan.c | 154 +++++++++++++----- .../net/wireless/microchip/wilc1000/wlan.h | 4 +- 3 files changed, 118 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 7bc6d788f33a..9173f6f3beab 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -960,6 +960,7 @@ static int wilc_sdio_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); struct wilc *wilc = sdio_get_drvdata(func); + int ret; dev_info(dev, "sdio suspend\n"); @@ -969,7 +970,11 @@ static int wilc_sdio_suspend(struct device *dev) if (!IS_ERR(wilc->rtc_clk)) clk_disable_unprepare(wilc->rtc_clk); - host_sleep_notify(wilc); + ret = host_sleep_notify(wilc); + if (ret) { + clk_prepare_enable(wilc->rtc_clk); + return ret; + } wilc_sdio_disable_interrupt(wilc); @@ -992,9 +997,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[] = { diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 875f0bb8af67..521caa498035 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -601,7 +601,7 @@ static int chip_allow_sleep(struct wilc *wilc) return 0; } -static void chip_wakeup(struct wilc *wilc) +static int chip_wakeup(struct wilc *wilc) { u32 ret = 0; u32 clk_status_val = 0, trials = 0; @@ -630,20 +630,20 @@ static 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; @@ -652,42 +652,63 @@ static 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); + + return 0; } -static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire) +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) - chip_wakeup(wilc); + 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 void release_bus(struct wilc *wilc, enum bus_release release) +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) - chip_allow_sleep(wilc); + ret = chip_allow_sleep(wilc); mutex_unlock(&wilc->hif_cs); + + return ret; } -void host_wakeup_notify(struct wilc *wilc) +int host_wakeup_notify(struct wilc *wilc) { - acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); + int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); + + if (ret) + return ret; + wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + 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); + int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); + + if (ret) + return ret; + wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); } EXPORT_SYMBOL_GPL(host_sleep_notify); @@ -714,6 +735,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; @@ -784,7 +806,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 { @@ -859,7 +884,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; @@ -921,7 +948,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) @@ -930,7 +959,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); @@ -1059,8 +1090,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) @@ -1069,7 +1106,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); @@ -1081,6 +1120,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); @@ -1091,7 +1131,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); @@ -1100,11 +1142,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) @@ -1122,7 +1170,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__); @@ -1141,7 +1191,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) { @@ -1150,7 +1200,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; @@ -1181,16 +1234,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) @@ -1226,9 +1281,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) @@ -1434,11 +1489,13 @@ EXPORT_SYMBOL_GPL(wilc_get_chipid); static int init_chip(struct net_device *dev) { 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; ret = wilc_get_chipid(wilc); if (ret) @@ -1470,17 +1527,19 @@ static int init_chip(struct net_device *dev) } release: - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; + 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); @@ -1519,14 +1578,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; @@ -1535,11 +1594,16 @@ 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); if (!ret) ret = wilc_get_chipid(wilc); - release_bus(wilc, WILC_BUS_RELEASE_ONLY); + rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY); + if (!ret && rv) + ret = rv; if (ret) goto fail; diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index 90ba76cf14dd..552590823e44 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h @@ -436,8 +436,8 @@ 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); +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); From 577c04fc3b8e364e65f0d8704242e0d24a2164a2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:14 +0200 Subject: [PATCH 069/126] wifi: wilc1000: Fold wilc_create_wiphy() into cfg80211.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wilc_create_wiphy() is not used outside of cfg80211.c . Make the function static and remove its entry from cfg80211.h Reviewed-by: Alexis Lothoré Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-5-marex@denx.de --- .../wireless/microchip/wilc1000/cfg80211.c | 94 +++++++++---------- .../wireless/microchip/wilc1000/cfg80211.h | 1 - 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index eb37b228d54e..11e0f8a47346 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -1757,53 +1757,7 @@ 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; @@ -1861,6 +1815,52 @@ struct wilc *wilc_create_wiphy(struct device *dev) 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_unregister(wl->wiphy); + wiphy_free(wl->wiphy); + return ret; +} +EXPORT_SYMBOL_GPL(wilc_cfg80211_init); + int wilc_init_host_int(struct net_device *net) { int ret; diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h index 8c65951cfaf9..fc04cc6615c1 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.h +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h @@ -10,7 +10,6 @@ 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); 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); From fbdf0c5248dce4b55181e9aff8f1b61819ba6bd7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Oct 2024 13:44:15 +0200 Subject: [PATCH 070/126] wifi: wilc1000: Register wiphy after reading out chipid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register wiphy after reading out chipid, so the chipid can be used to determine chip features and not advertise WPA3/SAE support to userspace on WILC3000. Note that wilc_netdev_cleanup() will deregister the wiphy in fail path. Tested-by: Alexis Lothoré Tested-on: WILC1000SD 07 SDIO WILC_WIFI_FW_REL_16_1_2 Tested-on: WILC3000 A SDIO WILC_WIFI_FW_REL_16_1_1 Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-6-marex@denx.de --- .../net/wireless/microchip/wilc1000/cfg80211.c | 16 ++++++++-------- .../net/wireless/microchip/wilc1000/cfg80211.h | 1 + drivers/net/wireless/microchip/wilc1000/sdio.c | 4 ++++ drivers/net/wireless/microchip/wilc1000/spi.c | 4 ++++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index 11e0f8a47346..283f8df04688 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -1761,7 +1761,6 @@ 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) @@ -1804,14 +1803,8 @@ static 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; } @@ -1855,12 +1848,19 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type, free_wl: wlan_deinit_locks(wl); - wiphy_unregister(wl->wiphy); wiphy_free(wl->wiphy); return ret; } EXPORT_SYMBOL_GPL(wilc_cfg80211_init); +int wilc_cfg80211_register(struct wilc *wilc) +{ + 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; diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h index fc04cc6615c1..2dc9c1c42d60 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.h +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h @@ -10,6 +10,7 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type, const struct wilc_hif_func *ops); +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); diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 9173f6f3beab..56a929281d6a 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -186,6 +186,10 @@ static int wilc_sdio_probe(struct sdio_func *func, 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"); diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 81cf82c9175e..28d211ee6009 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -249,6 +249,10 @@ static int wilc_bus_probe(struct spi_device *spi) if (ret) goto power_down; + ret = wilc_cfg80211_register(wilc); + if (ret) + goto power_down; + ret = wilc_load_mac_from_nv(wilc); if (ret) { pr_err("Can not retrieve MAC address from chip\n"); From e1408c115ef9bd7dcd5c74be9755291e5c699f8e Mon Sep 17 00:00:00 2001 From: Ajay Singh Date: Fri, 4 Oct 2024 13:44:16 +0200 Subject: [PATCH 071/126] wifi: wilc1000: Add WILC3000 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the WILC3000 chip. The chip is similar to WILC1000, except that the register layout is slightly different and it does not support WPA3/SAE. Reviewed-by: Alexis Lothoré Tested-by: Alexis Lothoré Tested-on: WILC1000SD 07 SDIO WILC_WIFI_FW_REL_16_1_2 Tested-on: WILC1000SD 07 SPI WILC_WIFI_FW_REL_16_1_2 Tested-on: WILC3000 A SDIO WILC_WIFI_FW_REL_16_1_1 Tested-on: WILC3000 A SPI WILC_WIFI_FW_REL_16_1_1 Signed-off-by: Ajay Singh Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004114551.40236-7-marex@denx.de --- .../wireless/microchip/wilc1000/cfg80211.c | 4 +- .../net/wireless/microchip/wilc1000/netdev.c | 29 ++- .../net/wireless/microchip/wilc1000/sdio.c | 62 ++++- drivers/net/wireless/microchip/wilc1000/spi.c | 2 +- .../net/wireless/microchip/wilc1000/wlan.c | 222 +++++++++++++++--- .../net/wireless/microchip/wilc1000/wlan.h | 45 +++- 6 files changed, 300 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index 283f8df04688..b0dae6f7c633 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -1855,7 +1855,9 @@ EXPORT_SYMBOL_GPL(wilc_cfg80211_init); int wilc_cfg80211_register(struct wilc *wilc) { - wilc->wiphy->features |= NL80211_FEATURE_SAE; + /* WPA3/SAE supported only on WILC1000 */ + if (is_wilc1000(wilc->chipid)) + wilc->wiphy->features |= NL80211_FEATURE_SAE; return wiphy_register(wilc->wiphy); } diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 086e70d833e0..3bb13aa33413 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -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; @@ -196,19 +202,23 @@ static int wilc_wlan_get_firmware(struct net_device *dev) struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; const struct firmware *wilc_fw; + char *firmware; int ret; - if (!is_wilc1000(wilc->chipid)) + 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, "WILC1000 loading firmware [%s]\n", - 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; @@ -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)); diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 56a929281d6a..5262c8846c13 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -810,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)) @@ -838,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); diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 28d211ee6009..ce2a9cdd6aa7 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -1233,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; } diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 521caa498035..9d80adc45d6b 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -541,7 +541,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) return rqe; } -static int 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; @@ -601,7 +601,41 @@ static int chip_allow_sleep(struct wilc *wilc) return 0; } -static int chip_wakeup(struct wilc *wilc) +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; @@ -613,15 +647,15 @@ static int 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; } @@ -663,6 +697,74 @@ static int chip_wakeup(struct wilc *wilc) return 0; } +static int chip_wakeup_wilc3000(struct wilc *wilc) +{ + 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; @@ -695,7 +797,9 @@ int host_wakeup_notify(struct wilc *wilc) if (ret) return ret; - wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1); + 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); @@ -707,7 +811,9 @@ int host_sleep_notify(struct wilc *wilc) if (ret) return ret; - wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1); + 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); @@ -842,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; @@ -1212,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; @@ -1462,21 +1597,25 @@ int wilc_get_chipid(struct wilc *wilc) u32 rfrevid = 0; if (wilc->chipid == 0) { - 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->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; @@ -1526,6 +1665,21 @@ static int init_chip(struct net_device *dev) } } + 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; + } + + 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; + } + } + release: rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); @@ -1607,7 +1761,7 @@ int wilc_wlan_init(struct net_device *dev) if (ret) goto fail; - if (!is_wilc1000(wilc->chipid)) { + if (!is_wilc1000(wilc->chipid) && !is_wilc3000(wilc->chipid)) { netdev_err(dev, "Unsupported chipid: %x\n", wilc->chipid); ret = -EINVAL; goto fail; diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index 552590823e44..b9e7f9222ead 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h @@ -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); From d0847e16ca2a98ef53b631e78d83d5a7f7e27295 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 27 Sep 2024 11:43:16 +0300 Subject: [PATCH 072/126] wifi: mwifiex: cleanup struct mwifiex_auto_tdls_peer Remove set but otherwise unused 'do_setup' member of 'struct mwifiex_auto_tdls_peer'. Compile tested only. Signed-off-by: Dmitry Antipov Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240927084317.96687-1-dmantipov@yandex.ru --- drivers/net/wireless/marvell/mwifiex/main.h | 1 - drivers/net/wireless/marvell/mwifiex/tdls.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 366590236ed7..f993dd885d15 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -801,7 +801,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 diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c index 7823e67694e8..0a5f340876c3 100644 --- a/drivers/net/wireless/marvell/mwifiex/tdls.c +++ b/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -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, From 6dc94457725465407bdaae5455e7c0492dacdc4f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 27 Sep 2024 11:43:17 +0300 Subject: [PATCH 073/126] wifi: mwifiex: cleanup struct mwifiex_private Remove set but otherwise unused 'adhoc_is_link_sensed' and 'assoc_resp_ht_param' members of 'struct mwifiex_private' and simplify related code in 'mwifiex_ret_802_11_associate()'. Compile tested only. Signed-off-by: Dmitry Antipov Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20240927084317.96687-2-dmantipov@yandex.ru --- drivers/net/wireless/marvell/mwifiex/join.c | 11 ++--------- drivers/net/wireless/marvell/mwifiex/main.h | 2 -- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +----- drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 2 -- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c index 6d8f1d1d7ca4..5a1a0287c1d5 100644 --- a/drivers/net/wireless/marvell/mwifiex/join.c +++ b/drivers/net/wireless/marvell/mwifiex/join.c @@ -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", diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index f993dd885d15..0674dcf7a537 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -573,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]; @@ -682,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; }; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index b5f3821a6a8f..400348abeee5 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -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)) diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index d3cba6895f8c..e06a0622973e 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -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); From 29dd3e48b9bd88bf65a1e760126fa18d1def7b30 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 3 Oct 2024 15:24:17 +0200 Subject: [PATCH 074/126] wifi: wilc1000: Set MAC after operation mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems it is necessary to set WILC MAC address after operation mode, otherwise the MAC address of the WILC MAC is reset back to what is in nvmem. This causes a failure to associate with AP after the WILC MAC address was overridden by userspace. Test case: " ap$ cat << EOF > hostap.conf interface=wlan0 ssid=ssid hw_mode=g channel=6 wpa=2 wpa_passphrase=pass wpa_key_mgmt=WPA-PSK EOF ap$ hostapd -d hostap.conf ap$ ifconfig wlan0 10.0.0.1 " " sta$ ifconfig wlan0 hw ether 00:11:22:33:44:55 sta$ wpa_supplicant -i wlan0 -c <(wpa_passphrase ssid pass) sta$ ifconfig wlan0 10.0.0.2 sta$ ping 10.0.0.1 # fails without this patch " AP still indicates SA with original MAC address from nvmem without this patch: " nl80211: RX frame da=ff:ff:ff:ff:ff:ff sa=60:01:23:45:67:89 bssid=ff:ff:ff:ff:ff:ff ... ^^^^^^^^^^^^^^^^^ " Fixes: 83d9b54ee5d4 ("wifi: wilc1000: read MAC address from fuse at probe") Tested-by: Alexis Lothoré Signed-off-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241003132504.52233-1-marex@denx.de --- drivers/net/wireless/microchip/wilc1000/netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 3bb13aa33413..7e84fc0fd911 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -618,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) { @@ -628,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; From e2e25113473b524c4b8d804c8c3b0a8de7ae0883 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 4 Oct 2024 01:42:52 +0100 Subject: [PATCH 075/126] wifi: brcmfmac: Remove unused brcmf_cfg80211_get_iftype() brcmf_cfg80211_get_iftype() has been unused since 2013's commit 5cd51c2bad56 ("brcmfmac: Find correct MAC descriptor in case of TDLS.") Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004004252.470836-1-linux@treblig.org --- .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 ------- .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 349aa3439502..297a7c738c01 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -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) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index dc3a6a537507..2abae8894614 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -443,7 +443,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); s32 brcmf_cfg80211_up(struct net_device *ndev); s32 brcmf_cfg80211_down(struct net_device *ndev); struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings); -enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type); From 13d21a2896081ce649914e529168696770a2524a Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 4 Oct 2024 01:42:59 +0100 Subject: [PATCH 076/126] wifi: brcmsmac: Remove unused brcms_debugfs_get_devdir() brcms_debugfs_get_devdir() has been unused since it was added by commit 8e21df23894e ("brcmsmac: hardware info in debugfs") Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241004004259.470853-1-linux@treblig.org --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c | 5 ----- drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h | 1 - 2 files changed, 6 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c index 6d776ef6ff54..81df41c7fbb5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c @@ -56,11 +56,6 @@ void brcms_debugfs_detach(struct brcms_pub *drvr) debugfs_remove_recursive(drvr->dbgfs_dir); } -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) -{ - return drvr->dbgfs_dir; -} - static int brcms_debugfs_hardware_read(struct seq_file *s, void *data) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h index 56898e6d789d..d30a9fa30f1b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h @@ -70,7 +70,6 @@ void brcms_debugfs_init(void); void brcms_debugfs_exit(void); void brcms_debugfs_attach(struct brcms_pub *drvr); void brcms_debugfs_detach(struct brcms_pub *drvr); -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr); void brcms_debugfs_create_files(struct brcms_pub *drvr); #endif /* _BRCMS_DEBUG_H_ */ From 7cc7267a01631f7379c751078115ac6614f9529e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 7 Oct 2024 15:16:39 +0200 Subject: [PATCH 077/126] wifi: brcmfmac: of: use devm_clk_get_optional_enabled_with_rate() Fold the separate clk_set_rate() call into the clock getter. Signed-off-by: Bartosz Golaszewski Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241007131639.98358-1-brgl@bgdev.pl --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index b90e23bb9366..ae98e371dbfd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -116,12 +116,11 @@ int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, of_node_put(root); } - clk = devm_clk_get_optional_enabled(dev, "lpo"); + 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"); - clk_set_rate(clk, 32768); if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) return 0; From d241a139c2e9f8a479f25c75ebd5391e6a448500 Mon Sep 17 00:00:00 2001 From: Alper Nebi Yasak Date: Tue, 8 Oct 2024 01:20:54 +0300 Subject: [PATCH 078/126] wifi: mwifiex: Fix memcpy() field-spanning write warning in mwifiex_config_scan() Replace one-element array with a flexible-array member in `struct mwifiex_ie_types_wildcard_ssid_params` to fix the following warning on a MT8173 Chromebook (mt8173-elm-hana): [ 356.775250] ------------[ cut here ]------------ [ 356.784543] memcpy: detected field-spanning write (size 6) of single field "wildcard_ssid_tlv->ssid" at drivers/net/wireless/marvell/mwifiex/scan.c:904 (size 1) [ 356.813403] WARNING: CPU: 3 PID: 742 at drivers/net/wireless/marvell/mwifiex/scan.c:904 mwifiex_scan_networks+0x4fc/0xf28 [mwifiex] The "(size 6)" above is exactly the length of the SSID of the network this device was connected to. The source of the warning looks like: ssid_len = user_scan_in->ssid_list[i].ssid_len; [...] memcpy(wildcard_ssid_tlv->ssid, user_scan_in->ssid_list[i].ssid, ssid_len); There is a #define WILDCARD_SSID_TLV_MAX_SIZE that uses sizeof() on this struct, but it already didn't account for the size of the one-element array, so it doesn't need to be changed. Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") Signed-off-by: Alper Nebi Yasak Acked-by: Brian Norris Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241007222301.24154-1-alpernebiyasak@gmail.com --- drivers/net/wireless/marvell/mwifiex/fw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h index d03129d5d24e..4a96281792cc 100644 --- a/drivers/net/wireless/marvell/mwifiex/fw.h +++ b/drivers/net/wireless/marvell/mwifiex/fw.h @@ -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 From b2d23b83d8d017fa031fe9d2552d8007bfdb88b8 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sat, 12 Oct 2024 21:38:52 +0100 Subject: [PATCH 079/126] wifi: cw1200: Remove unused cw1200_queue_requeue_all() cw1200_queue_requeue_all() has been unused since it was added in 2013 by commit a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241012203852.229151-1-linux@treblig.org --- drivers/net/wireless/st/cw1200/queue.c | 27 -------------------------- drivers/net/wireless/st/cw1200/queue.h | 1 - 2 files changed, 28 deletions(-) diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c index 805a3c1bf8fe..259739e53fc1 100644 --- a/drivers/net/wireless/st/cw1200/queue.c +++ b/drivers/net/wireless/st/cw1200/queue.c @@ -411,33 +411,6 @@ int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id) return ret; } -int cw1200_queue_requeue_all(struct cw1200_queue *queue) -{ - struct cw1200_queue_item *item, *tmp; - struct cw1200_queue_stats *stats = queue->stats; - spin_lock_bh(&queue->lock); - - list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) { - --queue->num_pending; - ++queue->link_map_cache[item->txpriv.link_id]; - - spin_lock_bh(&stats->lock); - ++stats->num_queued; - ++stats->link_map_cache[item->txpriv.link_id]; - spin_unlock_bh(&stats->lock); - - ++item->generation; - item->packet_id = cw1200_queue_mk_packet_id(queue->generation, - queue->queue_id, - item->generation, - item - queue->pool); - list_move(&item->head, &queue->queue); - } - spin_unlock_bh(&queue->lock); - - return 0; -} - int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id) { int ret = 0; diff --git a/drivers/net/wireless/st/cw1200/queue.h b/drivers/net/wireless/st/cw1200/queue.h index 96ac69ae97de..d46304b58747 100644 --- a/drivers/net/wireless/st/cw1200/queue.h +++ b/drivers/net/wireless/st/cw1200/queue.h @@ -85,7 +85,6 @@ int cw1200_queue_get(struct cw1200_queue *queue, struct ieee80211_tx_info **tx_info, const struct cw1200_txpriv **txpriv); int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id); -int cw1200_queue_requeue_all(struct cw1200_queue *queue); int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id); int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id, From 074a8b54dacc1920f54381f3661ecee6786b0c21 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 7 Oct 2024 15:00:45 +0300 Subject: [PATCH 080/126] wifi: mac80211: Add support to indicate that a new interface is to be added Add support to indicate to the driver that an interface is about to be added so that the driver could prepare its resources early if it needs so. Signed-off-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.e0e8563e1c30.Ifccc96a46a347eb15752caefc9f4eff31f75ed47@changeid Signed-off-by: Johannes Berg --- include/net/mac80211.h | 8 ++++++++ net/mac80211/cfg.c | 18 ++++++++++++++++++ net/mac80211/driver-ops.h | 12 ++++++++++++ net/mac80211/trace.h | 19 +++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 333e0fae6796..0b8df8ec5a3b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4444,6 +4444,12 @@ struct ieee80211_prep_tx_info { * if the requested TID-To-Link mapping can be accepted or not. * If it's not accepted the driver may suggest a preferred mapping and * modify @ttlm parameter with the suggested TID-to-Link mapping. + * @prep_add_interface: prepare for interface addition. This can be used by + * drivers to prepare for the addition of a new interface, e.g., allocate + * the needed resources etc. This callback doesn't guarantee that an + * interface with the specified type would be added, and thus drivers that + * implement this callback need to handle such cases. The type is the full + * &enum nl80211_iftype. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -4828,6 +4834,8 @@ struct ieee80211_ops { enum ieee80211_neg_ttlm_res (*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_neg_ttlm *ttlm); + void (*prep_add_interface)(struct ieee80211_hw *hw, + enum nl80211_iftype type); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 847304a3a29a..ce9558cd1576 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -194,6 +194,24 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, } } + /* Let the driver know that an interface is going to be added. + * Indicate so only for interface types that will be added to the + * driver. + */ + switch (type) { + case NL80211_IFTYPE_AP_VLAN: + break; + case NL80211_IFTYPE_MONITOR: + if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) || + !(params->flags & MONITOR_FLAG_ACTIVE)) + break; + fallthrough; + default: + drv_prep_add_interface(local, + ieee80211_vif_type_p2p(&sdata->vif)); + break; + } + return wdev; } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index d382d9729e85..48bc2da728c0 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1728,4 +1728,16 @@ drv_can_neg_ttlm(struct ieee80211_local *local, return res; } + +static inline void +drv_prep_add_interface(struct ieee80211_local *local, + enum nl80211_iftype type) +{ + trace_drv_prep_add_interface(local, type); + if (local->ops->prep_add_interface) + local->ops->prep_add_interface(&local->hw, type); + + trace_drv_return_void(local); +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index dc498cd8cd91..e6f0ce8e5d43 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -3154,6 +3154,25 @@ TRACE_EVENT(drv_neg_ttlm_res, LOCAL_PR_ARG, VIF_PR_ARG, __entry->res ) ); + +TRACE_EVENT(drv_prep_add_interface, + TP_PROTO(struct ieee80211_local *local, + enum nl80211_iftype type), + + TP_ARGS(local, type), + TP_STRUCT__entry(LOCAL_ENTRY + __field(u32, type) + ), + + TP_fast_assign(LOCAL_ASSIGN; + __entry->type = type; + ), + + TP_printk(LOCAL_PR_FMT " type: %u\n ", + LOCAL_PR_ARG, __entry->type + ) +); + #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH From 62262dd00c319195f2e14022903b7ebbb53119bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 15:00:46 +0300 Subject: [PATCH 081/126] wifi: cfg80211: disallow SMPS in AP mode In practice, userspace hasn't been able to set this for many years, and mac80211 has already rejected it (which is now no longer needed), so reject SMPS mode (other than "OFF" to be a bit more compatible) in AP mode. Also remove the parameter from the AP settings struct. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.fe1fc46484cf.I8676fb52b818a4bedeb9c25b901e1396277ffc0b@changeid Signed-off-by: Johannes Berg --- .../net/wireless/quantenna/qtnfmac/commands.c | 2 +- include/net/cfg80211.h | 2 -- net/mac80211/cfg.c | 3 -- net/wireless/nl80211.c | 30 ++----------------- 4 files changed, 4 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index 9540ad6196d7..956c5763662f 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -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; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 69ec1eb41a09..c8ce5c2e14f4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1460,7 +1460,6 @@ struct cfg80211_unsol_bcast_probe_resp { * @crypto: crypto settings * @privacy: the BSS uses privacy * @auth_type: Authentication type (algorithm) - * @smps_mode: SMPS mode * @inactivity_timeout: time in seconds to determine station's inactivity. * @p2p_ctwindow: P2P CT Window * @p2p_opp_ps: P2P opportunistic PS @@ -1498,7 +1497,6 @@ struct cfg80211_ap_settings { struct cfg80211_crypto_settings crypto; bool privacy; enum nl80211_auth_type auth_type; - enum nl80211_smps_mode smps_mode; int inactivity_timeout; u8 p2p_ctwindow; bool p2p_opp_ps; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ce9558cd1576..548b9bbdac04 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1312,9 +1312,6 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, if (old) return -EALREADY; - if (params->smps_mode != NL80211_SMPS_OFF) - return -EOPNOTSUPP; - link->smps_mode = IEEE80211_SMPS_OFF; link->needed_rx_chains = sdata->local->rx_chains; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4e3609176880..fb35c03af34c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6227,33 +6227,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) goto out; } - if (info->attrs[NL80211_ATTR_SMPS_MODE]) { - params->smps_mode = - nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]); - switch (params->smps_mode) { - case NL80211_SMPS_OFF: - break; - case NL80211_SMPS_STATIC: - if (!(rdev->wiphy.features & - NL80211_FEATURE_STATIC_SMPS)) { - err = -EINVAL; - goto out; - } - break; - case NL80211_SMPS_DYNAMIC: - if (!(rdev->wiphy.features & - NL80211_FEATURE_DYNAMIC_SMPS)) { - err = -EINVAL; - goto out; - } - break; - default: - err = -EINVAL; - goto out; - } - } else { - params->smps_mode = NL80211_SMPS_OFF; - } + if (info->attrs[NL80211_ATTR_SMPS_MODE] && + nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]) != NL80211_SMPS_OFF) + return -EOPNOTSUPP; params->pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]); if (params->pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) { From 9c5f2c7eeb585834f8dadb552b4fd811dd2dee6f Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Mon, 7 Oct 2024 15:00:47 +0300 Subject: [PATCH 082/126] wifi: mac80211: rename IEEE80211_CHANCTX_CHANGE_MIN_WIDTH The name is misleading, this actually indicates that ieee80211_chanctx_conf::min_def was updated. Rename it to IEEE80211_CHANCTX_CHANGE_MIN_DEF. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.726b5f12ae0c.I3bd9e594c9d2735183ec049a4c7224bd0a9599c9@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 ++-- include/net/mac80211.h | 4 ++-- net/mac80211/chan.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a327893c6dce..11cd1a8fdd9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -5067,7 +5067,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 +5075,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; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0b8df8ec5a3b..c42ad5a0c303 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -213,7 +213,7 @@ struct ieee80211_low_level_stats { * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel, * this is used only with channel switching with CSA - * @IEEE80211_CHANCTX_CHANGE_MIN_WIDTH: The min required channel width changed + * @IEEE80211_CHANCTX_CHANGE_MIN_DEF: The min chandef changed * @IEEE80211_CHANCTX_CHANGE_AP: The AP channel definition changed, so (wider * bandwidth) OFDMA settings need to be changed * @IEEE80211_CHANCTX_CHANGE_PUNCTURING: The punctured channel(s) bitmap @@ -224,7 +224,7 @@ enum ieee80211_chanctx_change { IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2), IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3), - IEEE80211_CHANCTX_CHANGE_MIN_WIDTH = BIT(4), + IEEE80211_CHANCTX_CHANGE_MIN_DEF = BIT(4), IEEE80211_CHANCTX_CHANGE_AP = BIT(5), IEEE80211_CHANCTX_CHANGE_PUNCTURING = BIT(6), }; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index a155e418d26b..3f7df45b0431 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -409,7 +409,7 @@ _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, if (!ctx->driver_present) return 0; - return IEEE80211_CHANCTX_CHANGE_MIN_WIDTH; + return IEEE80211_CHANCTX_CHANGE_MIN_DEF; } static void ieee80211_chan_bw_change(struct ieee80211_local *local, From e21dd758cf4c51d508e6665b653c5836103d1027 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 Oct 2024 15:00:48 +0300 Subject: [PATCH 083/126] wifi: mac80211: make bss_param_ch_cnt available for the low level driver Drivers may need to track this. Make it available for them, and maintain the value when beacons are received. When link X receives a beacon, iterate the RNR elements and update all the links with their respective data. Track the link id that updated the data so that each link can know whether the update came from its own beacon or from another link. In case, the update came from the link's own beacon, always update the updater link id. The purpose is to let the low level driver know if a link is losing its beacons. If link X is losing its beacons, it can still track the bss_param_ch_cnt and know where the update came from. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.e2d8d1a722ad.I04b883daba2cd48e5730659eb62ca1614c899cbb@changeid Signed-off-by: Johannes Berg --- include/net/mac80211.h | 15 ++++++ net/mac80211/ieee80211_i.h | 2 - net/mac80211/mlme.c | 93 +++++++++++++++++++++++++++++++++++++- 3 files changed, 106 insertions(+), 4 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c42ad5a0c303..20562676e9cd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -740,6 +740,19 @@ struct ieee80211_parsed_tpe { * @eht_80mhz_full_bw_ul_mumimo: in AP-mode, does this BSS support the * reception of an EHT TB PPDU on an RU that spans the entire PPDU * bandwidth + * @bss_param_ch_cnt: in BSS-mode, the BSS params change count. This + * information is the latest known value. It can come from this link's + * beacon or from a beacon sent by another link. + * @bss_param_ch_cnt_link_id: in BSS-mode, the link_id to which the beacon + * that updated &bss_param_ch_cnt belongs. E.g. if link 1 doesn't hear + * its beacons, and link 2 sent a beacon with an RNR element that updated + * link 1's BSS params change count, then, link 1's + * bss_param_ch_cnt_link_id will be 2. That means that link 1 knows that + * link 2 was the link that updated its bss_param_ch_cnt value. + * In case link 1 hears its beacon again, bss_param_ch_cnt_link_id will + * be updated to 1, even if bss_param_ch_cnt didn't change. This allows + * the link to know that it heard the latest value from its own beacon + * (as opposed to hearing its value from another link's beacon). */ struct ieee80211_bss_conf { struct ieee80211_vif *vif; @@ -834,6 +847,8 @@ struct ieee80211_bss_conf { bool eht_su_beamformee; bool eht_mu_beamformer; bool eht_80mhz_full_bw_ul_mumimo; + u8 bss_param_ch_cnt; + u8 bss_param_ch_cnt_link_id; }; /** diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index afb867dc6b24..d884d05826d3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1015,8 +1015,6 @@ struct ieee80211_link_data_managed { int wmm_last_param_set; int mu_edca_last_param_set; - - u8 bss_param_ch_cnt; }; struct ieee80211_link_data_ap { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0303972c23e4..93a11a59339c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2643,6 +2643,89 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link, &ifmgd->csa_connection_drop_work); } +struct sta_bss_param_ch_cnt_data { + struct ieee80211_sub_if_data *sdata; + u8 reporting_link_id; + u8 mld_id; +}; + +static enum cfg80211_rnr_iter_ret +ieee80211_sta_bss_param_ch_cnt_iter(void *_data, u8 type, + const struct ieee80211_neighbor_ap_info *info, + const u8 *tbtt_info, u8 tbtt_info_len) +{ + struct sta_bss_param_ch_cnt_data *data = _data; + struct ieee80211_sub_if_data *sdata = data->sdata; + const struct ieee80211_tbtt_info_ge_11 *ti; + u8 bss_param_ch_cnt; + int link_id; + + if (type != IEEE80211_TBTT_INFO_TYPE_TBTT) + return RNR_ITER_CONTINUE; + + if (tbtt_info_len < sizeof(*ti)) + return RNR_ITER_CONTINUE; + + ti = (const void *)tbtt_info; + + if (ti->mld_params.mld_id != data->mld_id) + return RNR_ITER_CONTINUE; + + link_id = le16_get_bits(ti->mld_params.params, + IEEE80211_RNR_MLD_PARAMS_LINK_ID); + bss_param_ch_cnt = + le16_get_bits(ti->mld_params.params, + IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); + + if (bss_param_ch_cnt != 255 && + link_id < ARRAY_SIZE(sdata->link)) { + struct ieee80211_link_data *link = + sdata_dereference(sdata->link[link_id], sdata); + + if (link && link->conf->bss_param_ch_cnt != bss_param_ch_cnt) { + link->conf->bss_param_ch_cnt = bss_param_ch_cnt; + link->conf->bss_param_ch_cnt_link_id = + data->reporting_link_id; + } + } + + return RNR_ITER_CONTINUE; +} + +static void +ieee80211_mgd_update_bss_param_ch_cnt(struct ieee80211_sub_if_data *sdata, + struct ieee80211_bss_conf *bss_conf, + struct ieee802_11_elems *elems) +{ + struct sta_bss_param_ch_cnt_data data = { + .reporting_link_id = bss_conf->link_id, + .sdata = sdata, + }; + int bss_param_ch_cnt; + + if (!elems->ml_basic) + return; + + data.mld_id = ieee80211_mle_get_mld_id((const void *)elems->ml_basic); + + cfg80211_iter_rnr(elems->ie_start, elems->total_len, + ieee80211_sta_bss_param_ch_cnt_iter, &data); + + bss_param_ch_cnt = + ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic); + + /* + * Update bss_param_ch_cnt_link_id even if bss_param_ch_cnt + * didn't change to indicate that we got a beacon on our own + * link. + */ + if (bss_param_ch_cnt >= 0 && bss_param_ch_cnt != 255) { + bss_conf->bss_param_ch_cnt = bss_param_ch_cnt; + bss_conf->bss_param_ch_cnt_link_id = + bss_conf->link_id; + } +} + static bool ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata, struct ieee80211_channel *channel, @@ -4667,7 +4750,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, ret = false; goto out; } - link->u.mgd.bss_param_ch_cnt = bss_param_ch_cnt; + bss_conf->bss_param_ch_cnt = bss_param_ch_cnt; + bss_conf->bss_param_ch_cnt_link_id = link_id; } } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC || !elems->prof || @@ -4677,6 +4761,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, } else { const u8 *ptr = elems->prof->variable + elems->prof->sta_info_len - 1; + int bss_param_ch_cnt; /* * During parsing, we validated that these fields exist, @@ -4684,8 +4769,10 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, */ capab_info = get_unaligned_le16(ptr); assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2); - link->u.mgd.bss_param_ch_cnt = + bss_param_ch_cnt = ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof); + bss_conf->bss_param_ch_cnt = bss_param_ch_cnt; + bss_conf->bss_param_ch_cnt_link_id = link_id; if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) { link_info(link, "association response status code=%u\n", @@ -6913,6 +7000,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link, /* note that after this elems->ml_basic can no longer be used fully */ ieee80211_mgd_check_cross_link_csa(sdata, rx_status->link_id, elems); + ieee80211_mgd_update_bss_param_ch_cnt(sdata, bss_conf, elems); + if (!link->u.mgd.disable_wmm_tracking && ieee80211_sta_wmm_params(local, link, elems->wmm_param, elems->wmm_param_len, From eea3323c43540f5d21668704946ea13ef0e9b574 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 Oct 2024 15:00:49 +0300 Subject: [PATCH 084/126] wifi: mac80211: remove unneeded parameters ieee80211_find_80211h_pwr_constr and ieee80211_find_cisco_dtpc don't need the pointer to struct ieee80211_sub_if_data *sdata. Remove it and it'll be one step closer to handle the power constraints per-link. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.3ea505cd74e7.Id416127544afd80e4fe7b275b612aef511fc64ed@changeid Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 93a11a59339c..9b0a0091f93c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2727,8 +2727,7 @@ ieee80211_mgd_update_bss_param_ch_cnt(struct ieee80211_sub_if_data *sdata, } static bool -ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, +ieee80211_find_80211h_pwr_constr(struct ieee80211_channel *channel, const u8 *country_ie, u8 country_ie_len, const u8 *pwr_constr_elem, int *chan_pwr, int *pwr_reduction) @@ -2798,8 +2797,7 @@ ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata, return have_chan_pwr; } -static void ieee80211_find_cisco_dtpc(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, +static void ieee80211_find_cisco_dtpc(struct ieee80211_channel *channel, const u8 *cisco_dtpc_ie, int *pwr_level) { @@ -2833,7 +2831,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link, (capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) || capab & cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) { has_80211h_pwr = ieee80211_find_80211h_pwr_constr( - sdata, channel, country_ie, country_ie_len, + channel, country_ie, country_ie_len, pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h); pwr_level_80211h = max_t(int, 0, chan_pwr - pwr_reduction_80211h); @@ -2841,7 +2839,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link, if (cisco_dtpc_ie) { ieee80211_find_cisco_dtpc( - sdata, channel, cisco_dtpc_ie, &pwr_level_cisco); + channel, cisco_dtpc_ie, &pwr_level_cisco); has_cisco_pwr = true; } From 9925aa855d4b400346c123dcc0301289779331e3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 Oct 2024 15:00:50 +0300 Subject: [PATCH 085/126] wifi: mac80211: ieee80211_recalc_txpower receives a link Handle the tx power per-link. Don't change the behavior for now. Just change the signature of the function. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.705bbf953d0a.I8a429dede07bab5801f4c730a6abff7ce23b22d3@changeid Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 7 ++++--- net/mac80211/chan.c | 4 ++-- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/iface.c | 8 ++++---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 548b9bbdac04..27468a463d8b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3096,7 +3096,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, sdata->vif.bss_conf.txpower_type = txp_type; } - ieee80211_recalc_txpower(sdata, update_txp_type); + ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); return 0; } @@ -3127,7 +3127,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR) continue; - ieee80211_recalc_txpower(sdata, update_txp_type); + ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); } if (has_monitor) { @@ -3139,7 +3139,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, update_txp_type = true; sdata->vif.bss_conf.txpower_type = txp_type; - ieee80211_recalc_txpower(sdata, update_txp_type); + ieee80211_recalc_txpower(&sdata->deflink, + update_txp_type); } } diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 3f7df45b0431..426ae5c066c9 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -905,7 +905,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link, } if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { - ieee80211_recalc_txpower(sdata, false); + ieee80211_recalc_txpower(&sdata->deflink, false); ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false); } @@ -1712,7 +1712,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) link, changed); - ieee80211_recalc_txpower(sdata, false); + ieee80211_recalc_txpower(&sdata->deflink, false); } ieee80211_recalc_chanctx_chantype(local, ctx); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d884d05826d3..94d9ffcbe1f8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2034,7 +2034,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local); void ieee80211_del_virtual_monitor(struct ieee80211_local *local); bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); -void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, +void ieee80211_recalc_txpower(struct ieee80211_link_data *link, bool update_bss); void ieee80211_recalc_offload(struct ieee80211_local *local); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6ef0990d3d29..e4a8ed102736 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -74,12 +74,12 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) return false; } -void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, +void ieee80211_recalc_txpower(struct ieee80211_link_data *link, bool update_bss) { - if (__ieee80211_recalc_txpower(sdata) || - (update_bss && ieee80211_sdata_running(sdata))) - ieee80211_link_info_change_notify(sdata, &sdata->deflink, + if (__ieee80211_recalc_txpower(link->sdata) || + (update_bss && ieee80211_sdata_running(link->sdata))) + ieee80211_link_info_change_notify(link->sdata, link, BSS_CHANGED_TXPOWER); } From 0b7392ee3bcff6319a6f5c5ad51710c7033d29aa Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 Oct 2024 15:00:51 +0300 Subject: [PATCH 086/126] wifi: mac80211: __ieee80211_recalc_txpower receives a link Handle the tx power per-link. Don't change the behavior for now. Just change the signature of the function. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.3c9cd0731f5b.I6ebfd9d5084f3602b55c55e2669881fd92471c2f@changeid Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/iface.c | 5 +++-- net/mac80211/mlme.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 94d9ffcbe1f8..45987add530f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2033,7 +2033,7 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); int ieee80211_add_virtual_monitor(struct ieee80211_local *local); void ieee80211_del_virtual_monitor(struct ieee80211_local *local); -bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); +bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link); void ieee80211_recalc_txpower(struct ieee80211_link_data *link, bool update_bss); void ieee80211_recalc_offload(struct ieee80211_local *local); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e4a8ed102736..138ba30e23ba 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -44,8 +44,9 @@ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work); -bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) +bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) { + struct ieee80211_sub_if_data *sdata = link->sdata; struct ieee80211_chanctx_conf *chanctx_conf; int power; @@ -77,7 +78,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) void ieee80211_recalc_txpower(struct ieee80211_link_data *link, bool update_bss) { - if (__ieee80211_recalc_txpower(link->sdata) || + if (__ieee80211_recalc_txpower(link) || (update_bss && ieee80211_sdata_running(link->sdata))) ieee80211_link_info_change_notify(link->sdata, link, BSS_CHANGED_TXPOWER); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9b0a0091f93c..f8fe711e1028 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2872,7 +2872,7 @@ static u64 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link, } link->ap_power_level = new_ap_level; - if (__ieee80211_recalc_txpower(sdata)) + if (__ieee80211_recalc_txpower(link)) return BSS_CHANGED_TXPOWER; return 0; } From c4382d5ca1af75cf909463c7a707efd1a5f9a557 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 Oct 2024 15:00:52 +0300 Subject: [PATCH 087/126] wifi: mac80211: update the right link for tx power Stop looking at deflink and start using the actual link. Initialize the power settings upon link init. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.2685dab8e1ab.I1d82cbdb2dda020aee4a225bd9a134f7d82dd810@changeid Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 98 +++++++++++++++++++++++++++----------------- net/mac80211/chan.c | 4 +- net/mac80211/iface.c | 20 ++++----- net/mac80211/link.c | 3 ++ 4 files changed, 74 insertions(+), 51 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 27468a463d8b..ca4fd217be3e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3061,9 +3061,25 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting txp_type = type; bool update_txp_type = false; bool has_monitor = false; + int user_power_level; lockdep_assert_wiphy(local->hw.wiphy); + switch (type) { + case NL80211_TX_POWER_AUTOMATIC: + user_power_level = IEEE80211_UNSET_POWER_LEVEL; + txp_type = NL80211_TX_POWER_LIMITED; + break; + case NL80211_TX_POWER_LIMITED: + case NL80211_TX_POWER_FIXED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + user_power_level = MBM_TO_DBM(mbm); + break; + default: + return -EINVAL; + } + if (wdev) { sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -3077,57 +3093,65 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, return -EOPNOTSUPP; } - switch (type) { - case NL80211_TX_POWER_AUTOMATIC: - sdata->deflink.user_power_level = - IEEE80211_UNSET_POWER_LEVEL; - txp_type = NL80211_TX_POWER_LIMITED; - break; - case NL80211_TX_POWER_LIMITED: - case NL80211_TX_POWER_FIXED: - if (mbm < 0 || (mbm % 100)) - return -EOPNOTSUPP; - sdata->deflink.user_power_level = MBM_TO_DBM(mbm); - break; + for (int link_id = 0; + link_id < ARRAY_SIZE(sdata->link); + link_id++) { + struct ieee80211_link_data *link = + wiphy_dereference(wiphy, sdata->link[link_id]); + + if (!link) + continue; + + link->user_power_level = user_power_level; + + if (txp_type != link->conf->txpower_type) { + update_txp_type = true; + link->conf->txpower_type = txp_type; + } + + ieee80211_recalc_txpower(link, update_txp_type); } - - if (txp_type != sdata->vif.bss_conf.txpower_type) { - update_txp_type = true; - sdata->vif.bss_conf.txpower_type = txp_type; - } - - ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); - return 0; } - switch (type) { - case NL80211_TX_POWER_AUTOMATIC: - local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; - txp_type = NL80211_TX_POWER_LIMITED; - break; - case NL80211_TX_POWER_LIMITED: - case NL80211_TX_POWER_FIXED: - if (mbm < 0 || (mbm % 100)) - return -EOPNOTSUPP; - local->user_power_level = MBM_TO_DBM(mbm); - break; - } + local->user_power_level = user_power_level; list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { has_monitor = true; continue; } - sdata->deflink.user_power_level = local->user_power_level; - if (txp_type != sdata->vif.bss_conf.txpower_type) - update_txp_type = true; - sdata->vif.bss_conf.txpower_type = txp_type; + + for (int link_id = 0; + link_id < ARRAY_SIZE(sdata->link); + link_id++) { + struct ieee80211_link_data *link = + wiphy_dereference(wiphy, sdata->link[link_id]); + + if (!link) + continue; + + link->user_power_level = local->user_power_level; + if (txp_type != link->conf->txpower_type) + update_txp_type = true; + link->conf->txpower_type = txp_type; + } } list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR) continue; - ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); + + for (int link_id = 0; + link_id < ARRAY_SIZE(sdata->link); + link_id++) { + struct ieee80211_link_data *link = + wiphy_dereference(wiphy, sdata->link[link_id]); + + if (!link) + continue; + + ieee80211_recalc_txpower(link, update_txp_type); + } } if (has_monitor) { diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 426ae5c066c9..b355e9af268d 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -905,7 +905,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link, } if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { - ieee80211_recalc_txpower(&sdata->deflink, false); + ieee80211_recalc_txpower(link, false); ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false); } @@ -1712,7 +1712,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) link, changed); - ieee80211_recalc_txpower(&sdata->deflink, false); + ieee80211_recalc_txpower(link, false); } ieee80211_recalc_chanctx_chantype(local, ctx); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 138ba30e23ba..7a99fa057cd9 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -46,12 +46,11 @@ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work); bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) { - struct ieee80211_sub_if_data *sdata = link->sdata; struct ieee80211_chanctx_conf *chanctx_conf; int power; rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); + chanctx_conf = rcu_dereference(link->conf->chanctx_conf); if (!chanctx_conf) { rcu_read_unlock(); return false; @@ -60,15 +59,15 @@ bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) power = ieee80211_chandef_max_power(&chanctx_conf->def); rcu_read_unlock(); - if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL) - power = min(power, sdata->deflink.user_power_level); + if (link->user_power_level != IEEE80211_UNSET_POWER_LEVEL) + power = min(power, link->user_power_level); - if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL) - power = min(power, sdata->deflink.ap_power_level); + if (link->ap_power_level != IEEE80211_UNSET_POWER_LEVEL) + power = min(power, link->ap_power_level); - if (power != sdata->vif.bss_conf.txpower) { - sdata->vif.bss_conf.txpower = power; - ieee80211_hw_config(sdata->local, 0); + if (power != link->conf->txpower) { + link->conf->txpower = power; + ieee80211_hw_config(link->sdata->local, 0); return true; } @@ -2177,9 +2176,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ieee80211_set_default_queues(sdata); - sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL; - sdata->deflink.user_power_level = local->user_power_level; - /* setup type-dependent data */ ieee80211_setup_sdata(sdata, type); diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 0bbac64d5fa0..503bdea904bc 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -36,6 +36,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, link->conf = link_conf; link_conf->link_id = link_id; link_conf->vif = &sdata->vif; + link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; + link->user_power_level = sdata->local->user_power_level; + link_conf->txpower = INT_MIN; wiphy_work_init(&link->csa.finalize_work, ieee80211_csa_finalize_work); From f828deb70c96748eb3a7462d5dbc432a28adae5f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 15:00:53 +0300 Subject: [PATCH 088/126] wifi: mac80211: allow rate_control_rate_init() for links Andrei previously fixed an issue in the client where the NSS for links other than the primary/assoc/deflink isn't set. The same issue appears to exist on the AP side, because there's only a call to rate_control_rate_init() for the deflink, and not any other links. Rework the code a bit to do rate_control_rate_init() for links, even if it really doesn't work with software rate control yet, it does other things as well. Also add rate_control_rate_init_all_links() to actually do it properly when moving to ASSOC state in cfg80211. Change the explicit call to ieee80211_sta_init_nss() to instead be rate_control_rate_init() now in the client code, but also add a call to rate_control_rate_init() when a link is added in AP mode and the STA is already associated. This should fix the NSS initialization issue, and perhaps pave the way for actual software rate scaling a bit, in case anyone cares in the future, but that of course needs a lot more than just the init call. We still need to fix the rate control _update_ as well, and the sta_rc_update() driver method especially, but that will be in a different patch. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.c693274a908f.I0376da02e9f5a30eaa1b5d0d01371ff09506d453@changeid Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 11 +++++++++-- net/mac80211/ibss.c | 4 ++-- net/mac80211/mesh_plink.c | 2 +- net/mac80211/mlme.c | 2 +- net/mac80211/ocb.c | 4 ++-- net/mac80211/rate.c | 24 ++++++++++++++++++++++-- net/mac80211/rate.h | 5 +++-- 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ca4fd217be3e..ecc138869b4b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1720,7 +1720,7 @@ static int sta_apply_auth_flags(struct ieee80211_local *local, * before drv_sta_state() is called. */ if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) - rate_control_rate_init(sta); + rate_control_rate_init_all_links(sta); ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); if (ret) @@ -2149,7 +2149,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, */ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) && test_sta_flag(sta, WLAN_STA_ASSOC)) - rate_control_rate_init(sta); + rate_control_rate_init_all_links(sta); return sta_info_insert(sta); } @@ -5063,6 +5063,13 @@ ieee80211_add_link_station(struct wiphy *wiphy, struct net_device *dev, return ret; } + if (test_sta_flag(sta, WLAN_STA_ASSOC)) { + struct link_sta_info *link_sta; + + link_sta = sdata_dereference(sta->link[params->link_id], sdata); + rate_control_rate_init(link_sta); + } + /* ieee80211_sta_activate_link frees the link upon failure */ return ieee80211_sta_activate_link(sta, params->link_id); } diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 3f74bbceeca5..08fac295ad5b 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -569,7 +569,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) if (!sta->sdata->u.ibss.control_port) sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); - rate_control_rate_init(sta); + rate_control_rate_init(&sta->deflink); /* If it fails, maybe we raced another insertion? */ if (sta_info_insert_rcu(sta)) @@ -1068,7 +1068,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, /* Force rx_nss recalculation */ sta->sta.deflink.rx_nss = 0; - rate_control_rate_init(sta); + rate_control_rate_init(&sta->deflink); if (sta->sta.deflink.rx_nss != rx_nss) changed |= IEEE80211_RC_NSS_CHANGED; diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 42286aa3623c..be0700d64549 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -487,7 +487,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, } if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) - rate_control_rate_init(sta); + rate_control_rate_init(&sta->deflink); else rate_control_rate_update(local, sband, sta, 0, changed); out: diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f8fe711e1028..714f780cc0f5 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -5750,7 +5750,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, /* links might have changed due to rejected ones, set them again */ ieee80211_vif_set_links(sdata, valid_links, dormant_links); - rate_control_rate_init(sta); + rate_control_rate_init_all_links(sta); if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) { set_sta_flag(sta, WLAN_STA_MFP); diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index f4c51e4a1e29..6218abc3e441 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -4,7 +4,7 @@ * * Copyright: (c) 2014 Czech Technical University in Prague * (c) 2014 Volkswagen Group Research - * Copyright (C) 2022 - 2023 Intel Corporation + * Copyright (C) 2022 - 2024 Intel Corporation * Author: Rostislav Lisovy * Funded by: Volkswagen Group Research */ @@ -96,7 +96,7 @@ static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) sta_info_move_state(sta, IEEE80211_STA_ASSOC); sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); - rate_control_rate_init(sta); + rate_control_rate_init(&sta->deflink); /* If it fails, maybe we raced another insertion? */ if (sta_info_insert_rcu(sta)) diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 3dc9752188d5..23b4f1af37e0 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -28,8 +28,9 @@ module_param(ieee80211_default_rc_algo, charp, 0644); MODULE_PARM_DESC(ieee80211_default_rc_algo, "Default rate control algorithm for mac80211 to use"); -void rate_control_rate_init(struct sta_info *sta) +void rate_control_rate_init(struct link_sta_info *link_sta) { + struct sta_info *sta = link_sta->sta; struct ieee80211_local *local = sta->sdata->local; struct rate_control_ref *ref = sta->rate_ctrl; struct ieee80211_sta *ista = &sta->sta; @@ -37,11 +38,15 @@ void rate_control_rate_init(struct sta_info *sta) struct ieee80211_supported_band *sband; struct ieee80211_chanctx_conf *chanctx_conf; - ieee80211_sta_init_nss(&sta->deflink); + ieee80211_sta_init_nss(link_sta); if (!ref) return; + /* SW rate control isn't supported with MLO right now */ + if (WARN_ON(ieee80211_vif_is_mld(&sta->sdata->vif))) + return; + rcu_read_lock(); chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf); @@ -67,6 +72,21 @@ void rate_control_rate_init(struct sta_info *sta) set_sta_flag(sta, WLAN_STA_RATE_CONTROL); } +void rate_control_rate_init_all_links(struct sta_info *sta) +{ + int link_id; + + for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) { + struct link_sta_info *link_sta; + + link_sta = sdata_dereference(sta->link[link_id], sta->sdata); + if (!link_sta) + continue; + + rate_control_rate_init(link_sta); + } +} + void rate_control_tx_status(struct ieee80211_local *local, struct ieee80211_tx_status *st) { diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index d6190f10fe7c..8d3c8903b4ae 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h @@ -3,7 +3,7 @@ * Copyright 2002-2005, Instant802 Networks, Inc. * Copyright 2005, Devicescape Software, Inc. * Copyright (c) 2006 Jiri Benc - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022, 2024 Intel Corporation */ #ifndef IEEE80211_RATE_H @@ -29,7 +29,8 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, void rate_control_tx_status(struct ieee80211_local *local, struct ieee80211_tx_status *st); -void rate_control_rate_init(struct sta_info *sta); +void rate_control_rate_init(struct link_sta_info *link_sta); +void rate_control_rate_init_all_links(struct sta_info *sta); void rate_control_rate_update(struct ieee80211_local *local, struct ieee80211_supported_band *sband, struct sta_info *sta, From 88b67e91e2928c3311f3658d1270b40708b0de00 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 15:00:54 +0300 Subject: [PATCH 089/126] wifi: mac80211: call rate_control_rate_update() for link STA In order to update the right link information, call the update rate_control_rate_update() with the right link_sta, and then pass that through to the driver's sta_rc_update() method. The software rate control still doesn't support it, but that'll be skipped by not having a rate control ref. Since it now operates on a link sta, rename the driver method. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.5851b6b5fd41.Ibdf50d96afa4b761dd9b9dfd54a1147e77a75329@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath10k/mac.c | 5 +++-- drivers/net/wireless/ath/ath11k/mac.c | 5 +++-- drivers/net/wireless/ath/ath12k/mac.c | 5 +++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +++-- .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 5 +++-- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 5 +++-- drivers/net/wireless/realtek/rtw88/mac80211.c | 6 ++++-- drivers/net/wireless/realtek/rtw89/mac80211.c | 6 ++++-- drivers/net/wireless/ti/wlcore/main.c | 5 +++-- drivers/net/wireless/virtual/mac80211_hwsim.c | 8 ++++---- include/net/mac80211.h | 12 ++++++------ net/mac80211/chan.c | 2 +- net/mac80211/driver-ops.c | 15 ++++++++------- net/mac80211/driver-ops.h | 6 +++--- net/mac80211/ibss.c | 3 ++- net/mac80211/mesh_plink.c | 3 ++- net/mac80211/rate.c | 8 ++++---- net/mac80211/rate.h | 3 +-- net/mac80211/rx.c | 4 ++-- net/mac80211/tdls.c | 3 ++- net/mac80211/trace.h | 15 +++++++++------ net/mac80211/vht.c | 3 +-- 25 files changed, 80 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 646e1737d4c4..41ab83c3d3f7 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -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, diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index f8068d2e848c..e6acbff06749 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -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, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 137394c36460..acf5628adda5 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -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, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8a03bcc2789e..57094bd45d98 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -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, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 11cd1a8fdd9e..3721d6349cc5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4236,8 +4236,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 | @@ -6562,7 +6563,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, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index f2378e0fb2fb..7de6c96646ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -1401,7 +1401,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, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ef07cff203b0..6246ffce7cf8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2914,7 +2914,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); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index d75e8dea1fbd..c6f498fc81ff 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -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, diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 39f071ece35e..2b34ae5e0cb5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -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, diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index b39e90fb66b4..026fbf4ad9cc 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -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, diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 1ee63a85308f..3f33c3a2ae7d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -1290,8 +1290,10 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw, static void rtw89_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 rtw89_dev *rtwdev = hw->priv; rtw89_phy_ra_update_sta(rtwdev, sta, changed); @@ -1593,7 +1595,7 @@ const struct ieee80211_ops rtw89_ops = { .remain_on_channel = rtw89_ops_remain_on_channel, .cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel, .set_sar_specs = rtw89_ops_set_sar_specs, - .sta_rc_update = rtw89_ops_sta_rc_update, + .link_sta_rc_update = rtw89_ops_sta_rc_update, .set_tid_config = rtw89_ops_set_tid_config, #ifdef CONFIG_PM .suspend = rtw89_ops_suspend, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0c77b8524160..986b07bfa0ee 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5789,9 +5789,10 @@ static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw, static void wlcore_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 wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update"); @@ -6052,7 +6053,7 @@ static const struct ieee80211_ops wl1271_ops = { .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, - .sta_rc_update = wlcore_op_sta_rc_update, + .link_sta_rc_update = wlcore_op_sta_rc_update, .sta_statistics = wlcore_op_sta_statistics, .get_expected_throughput = wlcore_op_get_expected_throughput, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index f0e528abb1b4..fe3e2dc1626b 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -2594,10 +2594,11 @@ static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw, static void mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, + struct ieee80211_link_sta *link_sta, u32 changed) { struct mac80211_hwsim_data *data = hw->priv; + struct ieee80211_sta *sta = link_sta->sta; u32 bw = U32_MAX; int link_id; @@ -2607,7 +2608,6 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, link_id++) { enum nl80211_chan_width confbw = NL80211_CHAN_WIDTH_20_NOHT; struct ieee80211_bss_conf *vif_conf; - struct ieee80211_link_sta *link_sta; link_sta = rcu_dereference(sta->link[link_id]); @@ -2659,7 +2659,7 @@ static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, hwsim_check_magic(vif); hwsim_set_sta_magic(sta); - mac80211_hwsim_sta_rc_update(hw, vif, sta, 0); + mac80211_hwsim_sta_rc_update(hw, vif, &sta->deflink, 0); if (sta->valid_links) { WARN(hweight16(sta->valid_links) > 1, @@ -3961,7 +3961,7 @@ static int hwsim_pmsr_report_nl(struct sk_buff *msg, struct genl_info *info) .link_info_changed = mac80211_hwsim_link_info_changed, \ .tx_last_beacon = mac80211_hwsim_tx_last_beacon, \ .sta_notify = mac80211_hwsim_sta_notify, \ - .sta_rc_update = mac80211_hwsim_sta_rc_update, \ + .link_sta_rc_update = mac80211_hwsim_sta_rc_update, \ .conf_tx = mac80211_hwsim_conf_tx, \ .get_survey = mac80211_hwsim_get_survey, \ CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) \ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 20562676e9cd..7a6edc04e212 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4090,8 +4090,8 @@ struct ieee80211_prep_tx_info { * in @sta_state. * The callback can sleep. * - * @sta_rc_update: Notifies the driver of changes to the bitrates that can be - * used to transmit to the station. The changes are advertised with bits + * @link_sta_rc_update: Notifies the driver of changes to the bitrates that can + * be used to transmit to the station. The changes are advertised with bits * from &enum ieee80211_rate_control_changed and the values are reflected * in the station data. This callback should only be used when the driver * uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since @@ -4581,10 +4581,10 @@ struct ieee80211_ops { void (*sta_pre_rcu_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); - void (*sta_rc_update)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u32 changed); + void (*link_sta_rc_update)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed); void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index b355e9af268d..2d7ec557cbd6 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -467,7 +467,7 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local, continue; link_sta->pub->bandwidth = new_sta_bw; - rate_control_rate_update(local, sband, sta, link_id, + rate_control_rate_update(local, sband, link_sta, IEEE80211_RC_BW_CHANGED); } } diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index fe868b521622..84d048339113 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -181,9 +181,10 @@ int drv_sta_set_txpwr(struct ieee80211_local *local, return ret; } -void drv_sta_rc_update(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_sta *sta, u32 changed) +void drv_link_sta_rc_update(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_link_sta *link_sta, + u32 changed) { sdata = get_bss_sdata(sdata); if (!check_sdata_in_driver(sdata)) @@ -193,10 +194,10 @@ void drv_sta_rc_update(struct ieee80211_local *local, (sdata->vif.type != NL80211_IFTYPE_ADHOC && sdata->vif.type != NL80211_IFTYPE_MESH_POINT)); - trace_drv_sta_rc_update(local, sdata, sta, changed); - if (local->ops->sta_rc_update) - local->ops->sta_rc_update(&local->hw, &sdata->vif, - sta, changed); + trace_drv_link_sta_rc_update(local, sdata, link_sta, changed); + if (local->ops->link_sta_rc_update) + local->ops->link_sta_rc_update(&local->hw, &sdata->vif, + link_sta, changed); trace_drv_return_void(local); } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 48bc2da728c0..edd1e4d4ad9d 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -594,9 +594,9 @@ int drv_sta_set_txpwr(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct sta_info *sta); -void drv_sta_rc_update(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_sta *sta, u32 changed); +void drv_link_sta_rc_update(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_link_sta *link_sta, u32 changed); static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 08fac295ad5b..a1b4178deccf 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1072,7 +1072,8 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, if (sta->sta.deflink.rx_nss != rx_nss) changed |= IEEE80211_RC_NSS_CHANGED; - drv_sta_rc_update(local, sdata, &sta->sta, changed); + drv_link_sta_rc_update(local, sdata, &sta->sta.deflink, + changed); } rcu_read_unlock(); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index be0700d64549..6ea35c88dc48 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -486,10 +486,11 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20; } + /* FIXME: this check is wrong without SW rate control */ if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) rate_control_rate_init(&sta->deflink); else - rate_control_rate_update(local, sband, sta, 0, changed); + rate_control_rate_update(local, sband, &sta->deflink, changed); out: spin_unlock_bh(&sta->mesh->plink_lock); } diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 23b4f1af37e0..63fe58311a77 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -113,16 +113,15 @@ void rate_control_tx_status(struct ieee80211_local *local, void rate_control_rate_update(struct ieee80211_local *local, struct ieee80211_supported_band *sband, - struct sta_info *sta, unsigned int link_id, + struct link_sta_info *link_sta, u32 changed) { struct rate_control_ref *ref = local->rate_ctrl; + struct sta_info *sta = link_sta->sta; struct ieee80211_sta *ista = &sta->sta; void *priv_sta = sta->rate_ctrl_priv; struct ieee80211_chanctx_conf *chanctx_conf; - WARN_ON(link_id != 0); - if (ref && ref->ops->rate_update) { rcu_read_lock(); @@ -140,7 +139,8 @@ void rate_control_rate_update(struct ieee80211_local *local, } if (sta->uploaded) - drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); + drv_link_sta_rc_update(local, sta->sdata, link_sta->pub, + changed); } int ieee80211_rate_control_register(const struct rate_control_ops *ops) diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 8d3c8903b4ae..673aa9efe30b 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h @@ -33,8 +33,7 @@ void rate_control_rate_init(struct link_sta_info *link_sta); void rate_control_rate_init_all_links(struct sta_info *sta); void rate_control_rate_update(struct ieee80211_local *local, struct ieee80211_supported_band *sband, - struct sta_info *sta, - unsigned int link_id, + struct link_sta_info *link_sta, u32 changed); static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 694b43091fec..d7b294221d43 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3568,7 +3568,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) sband = rx->local->hw.wiphy->bands[status->band]; - rate_control_rate_update(local, sband, rx->sta, 0, + rate_control_rate_update(local, sband, rx->link_sta, IEEE80211_RC_SMPS_CHANGED); cfg80211_sta_opmode_change_notify(sdata->dev, rx->sta->addr, @@ -3605,7 +3605,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ieee80211_sta_rx_bw_to_chan_width(rx->link_sta); sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED; - rate_control_rate_update(local, sband, rx->sta, 0, + rate_control_rate_update(local, sband, rx->link_sta, IEEE80211_RC_BW_CHANGED); cfg80211_sta_opmode_change_notify(sdata->dev, rx->sta->addr, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index f07b40916485..2f92e7c7f203 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -1342,7 +1342,8 @@ static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata, bw = min(bw, ieee80211_sta_cap_rx_bw(&sta->deflink)); if (bw != sta->sta.deflink.bandwidth) { sta->sta.deflink.bandwidth = bw; - rate_control_rate_update(local, sband, sta, 0, + rate_control_rate_update(local, sband, + &sta->deflink, IEEE80211_RC_BW_CHANGED); /* * if a TDLS peer BW was updated, we need to diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index e6f0ce8e5d43..7a4985fc2b16 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -939,31 +939,34 @@ TRACE_EVENT(drv_sta_set_txpwr, ) ); -TRACE_EVENT(drv_sta_rc_update, +TRACE_EVENT(drv_link_sta_rc_update, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - struct ieee80211_sta *sta, + struct ieee80211_link_sta *link_sta, u32 changed), - TP_ARGS(local, sdata, sta, changed), + TP_ARGS(local, sdata, link_sta, changed), TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY STA_ENTRY __field(u32, changed) + __field(u32, link_id) ), TP_fast_assign( LOCAL_ASSIGN; VIF_ASSIGN; - STA_ASSIGN; + STA_NAMED_ASSIGN(link_sta->sta); __entry->changed = changed; + __entry->link_id = link_sta->link_id; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " changed: 0x%x", - LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->changed + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " (link %d) changed: 0x%x", + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id, + __entry->changed ) ); diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index eafe47bf201a..0d439cefb445 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -766,8 +766,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, if (changed > 0) { ieee80211_recalc_min_chandef(sdata, link_sta->link_id); - rate_control_rate_update(local, sband, link_sta->sta, - link_sta->link_id, changed); + rate_control_rate_update(local, sband, link_sta, changed); } } From cf007927972707d91fae3013ae27f165cebdf535 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Mon, 7 Oct 2024 15:00:55 +0300 Subject: [PATCH 090/126] wifi: mac80211: parse A-MSDU len from EHT capabilities On 2.4 GHz there's no VHT, so EHT defines its own bits for the maximum MPDU length. Parse and store them in the link_sta. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.e05da59c419a.I0b1c047639160d9a96f48ab013c18ea33f5473b0@changeid Signed-off-by: Johannes Berg --- net/mac80211/eht.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c index ddc7acc68335..7a3116c36df9 100644 --- a/net/mac80211/eht.c +++ b/net/mac80211/eht.c @@ -2,7 +2,7 @@ /* * EHT handling * - * Copyright(c) 2021-2023 Intel Corporation + * Copyright(c) 2021-2024 Intel Corporation */ #include "ieee80211_i.h" @@ -75,4 +75,23 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata, link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta); link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); + + switch (u8_get_bits(eht_cap->eht_cap_elem.mac_cap_info[0], + IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK)) { + case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454: + link_sta->pub->agg.max_amsdu_len = + IEEE80211_MAX_MPDU_LEN_VHT_11454; + break; + case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991: + link_sta->pub->agg.max_amsdu_len = + IEEE80211_MAX_MPDU_LEN_VHT_7991; + break; + case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895: + default: + link_sta->pub->agg.max_amsdu_len = + IEEE80211_MAX_MPDU_LEN_VHT_3895; + break; + } + + ieee80211_sta_recalc_aggregates(&link_sta->sta->sta); } From 41eba07636af6f95a9421af574a5a2fa9f3888ee Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Mon, 7 Oct 2024 15:00:56 +0300 Subject: [PATCH 091/126] wifi: mac80211: add an option to fake ieee80211_connection_loss This allows faking this function in KUnit tests. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.3b42e7547c65.I3bcbd51bec9ccfc7c08739450ec778722549c007@changeid Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 714f780cc0f5..480b664151c9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -31,6 +31,8 @@ #include "led.h" #include "fils_aead.h" +#include + #define IEEE80211_AUTH_TIMEOUT (HZ / 5) #define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2) #define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10) @@ -4182,8 +4184,13 @@ EXPORT_SYMBOL(ieee80211_beacon_loss); void ieee80211_connection_loss(struct ieee80211_vif *vif) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - struct ieee80211_hw *hw = &sdata->local->hw; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_hw *hw; + + KUNIT_STATIC_STUB_REDIRECT(ieee80211_connection_loss, vif); + + sdata = vif_to_sdata(vif); + hw = &sdata->local->hw; trace_api_connection_loss(sdata); From b23af47921a708e0008698eb373118bb5f20334c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 15:00:57 +0300 Subject: [PATCH 092/126] wifi: mac80211: chan: calculate min_def also for client mode In order to deal with (temporary) bandwidth reductions to/from the AP such as the upcoming RX OMI changes, modify the min_def calculation to also not take the chanreq width into account in client mode. This normally changes nothing as the AP bandwidth will be the same as the channel request's width. In the RX OMI changes, however, the code will reduce the bandwidth for only the AP STA, since the OMI is only to that, and TDLS STAs are unaffected. Using the min_def for this case simplifies RX OMI a lot. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.95a39c4f6f45.I2e7517fb1a7221dc6f60b0c752e4882042b4265d@changeid Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 2d7ec557cbd6..0e44f4e38099 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -323,19 +323,27 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, continue; switch (link->sdata->vif.type) { + case NL80211_IFTYPE_STATION: + if (!link->sdata->vif.cfg.assoc) { + /* + * The AP's sta->bandwidth may not yet be set + * at this point (pre-association), so simply + * take the width from the chandef. We cannot + * have TDLS peers yet (only after association). + */ + width = link->conf->chanreq.oper.width; + break; + } + /* + * otherwise just use min_def like in AP, depending on what + * we currently think the AP STA (and possibly TDLS peers) + * require(s) + */ + fallthrough; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: width = ieee80211_get_max_required_bw(link); break; - case NL80211_IFTYPE_STATION: - /* - * The ap's sta->bandwidth is not set yet at this - * point, so take the width from the chandef, but - * account also for TDLS peers - */ - width = max(link->conf->chanreq.oper.width, - ieee80211_get_max_required_bw(link)); - break; case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: continue; From 751e7489c1d74b94ffffbed619d8fd724eeff4ee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 7 Oct 2024 15:00:58 +0300 Subject: [PATCH 093/126] wifi: mac80211: expose ieee80211_chan_width_to_rx_bw() to drivers Drivers might need to also do this calculation, no point in them duplicating the code. Since it's so simple, just make it an inline. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241007144851.af003cb4a088.I8b5d29504b726caae24af6013c65b3daebe842a2@changeid Signed-off-by: Johannes Berg --- include/net/mac80211.h | 27 +++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 2 -- net/mac80211/vht.c | 22 ---------------------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7a6edc04e212..32bdda90a4ac 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -7704,6 +7704,33 @@ void ieee80211_set_active_links_async(struct ieee80211_vif *vif, */ void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif); +/** + * ieee80211_chan_width_to_rx_bw - convert channel width to STA RX bandwidth + * @width: the channel width value to convert + * Return: the STA RX bandwidth value for the channel width + */ +static inline enum ieee80211_sta_rx_bandwidth +ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) +{ + switch (width) { + default: + WARN_ON_ONCE(1); + fallthrough; + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + return IEEE80211_STA_RX_BW_20; + case NL80211_CHAN_WIDTH_40: + return IEEE80211_STA_RX_BW_40; + case NL80211_CHAN_WIDTH_80: + return IEEE80211_STA_RX_BW_80; + case NL80211_CHAN_WIDTH_160: + case NL80211_CHAN_WIDTH_80P80: + return IEEE80211_STA_RX_BW_160; + case NL80211_CHAN_WIDTH_320: + return IEEE80211_STA_RX_BW_320; + } +} + /* for older drivers - let's not document these ... */ int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 45987add530f..d20c2e796703 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2194,8 +2194,6 @@ ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta) return _ieee80211_sta_cur_vht_bw(link_sta, NULL); } void ieee80211_sta_init_nss(struct link_sta_info *link_sta); -enum ieee80211_sta_rx_bandwidth -ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width); enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct link_sta_info *link_sta); void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 0d439cefb445..6a20fa099190 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -479,28 +479,6 @@ ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *link_sta) } } -enum ieee80211_sta_rx_bandwidth -ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) -{ - switch (width) { - case NL80211_CHAN_WIDTH_20_NOHT: - case NL80211_CHAN_WIDTH_20: - return IEEE80211_STA_RX_BW_20; - case NL80211_CHAN_WIDTH_40: - return IEEE80211_STA_RX_BW_40; - case NL80211_CHAN_WIDTH_80: - return IEEE80211_STA_RX_BW_80; - case NL80211_CHAN_WIDTH_160: - case NL80211_CHAN_WIDTH_80P80: - return IEEE80211_STA_RX_BW_160; - case NL80211_CHAN_WIDTH_320: - return IEEE80211_STA_RX_BW_320; - default: - WARN_ON_ONCE(1); - return IEEE80211_STA_RX_BW_20; - } -} - /* FIXME: rename/move - this deals with everything not just VHT */ enum ieee80211_sta_rx_bandwidth _ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta, From 447c55e235f3641da0dd13b1414d90812db0f978 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Tue, 8 Oct 2024 07:25:15 +0300 Subject: [PATCH 094/126] wifi: iwlwifi: mvm: Add support for prep_add_interface() callback Implement the prep_add_interface() callback, so that in case EMLSR is active and an AP or a P2P interface is do to be added, EMLSR would be blocked. Add a delayed work, so that in case that the interface was not eventually added, EMLSR would be unblocked after 5 seconds. Signed-off-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.3baf282d0a01.Ife0a929455cb13a95ab197ca765d8db777ff9d89@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 1 + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 22 +++++++++++++ .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 31 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 +++++ 4 files changed, 61 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 2b0652168002..19ecd215f1dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -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) \ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3721d6349cc5..99e017f365e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1731,6 +1731,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 +1764,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 +1917,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); } @@ -4075,6 +4095,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) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 7de6c96646ca..3947f6a0e0cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -1376,6 +1376,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, @@ -1472,4 +1502,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, }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 6246ffce7cf8..3f7b6465130a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -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]; From 7953a1f57a8664501efba4d6cd63b39cf4a76759 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 8 Oct 2024 07:25:16 +0300 Subject: [PATCH 095/126] wifi: iwlwifi: mvm: exit EMLSR earlier if bss_param_ch_cnt is updated If we lose beacons and bss_param_ch_cnt gets updated on the other link, we need to exit EMLSR earlier. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.9c5ad120b937.Ibdde0b3770d0821e802009d4684b617220dd6e1a@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 3 ++- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index ddf484027d4f..fdccdea918bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -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) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index a7a10e716e65..9a43df49493f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -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)); From 108e80db1fd978b93dff1c4abaafb02ecfaf3aac Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 8 Oct 2024 07:25:17 +0300 Subject: [PATCH 096/126] wifi: iwlwifi: mvm: prepare the tx_power handling to be per-link We still need the firmware to align Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.317f44628eb9.I3f6a735181c6c20e805b61e4f9d2056b7f90d7ea@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 ++++++------ .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 99e017f365e0..3fefb0696248 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1466,15 +1466,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 +1488,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; } @@ -3323,7 +3323,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); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 3947f6a0e0cf..9aa08d289680 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -1038,7 +1038,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); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 3f7b6465130a..ff5d720b7314 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2989,7 +2989,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, From b958cb0b0a107b678f34fe3987b95b06a7882b20 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 8 Oct 2024 07:25:18 +0300 Subject: [PATCH 097/126] wifi: iwlwifi: mvm: log information about HW restart completion It can happen that more errors occur after a firmware assertion. In that case, having another log message after the restart has completed makes it easier to see which errors where still part of the restart flow. Signed-off-by: Benjamin Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.d205dd88fb9d.Ic43a1b399f59d2ab1018ff2f9e6e3a0324692660@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3fefb0696248..4db7c3ee6bf5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -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, From fac20611c2ab9c95f5a805d013cc1a7b7137f97c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 8 Oct 2024 07:25:19 +0300 Subject: [PATCH 098/126] wifi: iwlwifi: fw: api: update link context API version The flags_mask field is becoming reserved, and a new bandwidth request is being added for RX OMI purposes. Support the new API version as preparation. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.437c6573df3c.I03612cb6cf47b12038c1db11b95a554cdea714e9@changeid Signed-off-by: Johannes Berg --- .../wireless/intel/iwlwifi/fw/api/mac-cfg.h | 32 ++++++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 3 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index c46e24fc6a1e..b23d5fc4bbe6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -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. diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 19ecd215f1dc..628baf67b208 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -361,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); From 1bf5964efe9a58e6460232c3294609d686642528 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 8 Oct 2024 07:25:20 +0300 Subject: [PATCH 099/126] wifi: iwlwifi: bump FW API to 94 for BZ/SC devices Start supporting API version 94 for those devices. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.7ddabbd42131.Ib8bd35521a317c14b3a2a2e5983cf5bca5e8718b@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c index fa1be8c54d3c..ea40d402681d 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c @@ -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 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c index f1dd1c29f305..635fed641c19 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c @@ -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 From f6db1fd49f9b9a8c27caec32e65d26eb40cf8b64 Mon Sep 17 00:00:00 2001 From: Daniel Gabay Date: Tue, 8 Oct 2024 07:25:21 +0300 Subject: [PATCH 100/126] wifi: iwlwifi: mvm: Remove unused last_amsdu from reorder buffer The last_amsdu field is not used and appears to be a leftover from a previous implementation, remove it. Signed-off-by: Daniel Gabay Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.13ba0eeae0fd.I94985512596e5996f5ab199451ce851c59a5a72a@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 -- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ff5d720b7314..475e781e166a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -780,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 */ @@ -788,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; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 65f8933c34b4..fdbd63ff91ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -814,7 +814,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 +831,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 +840,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 From e5c6c41522201f0a58c61c6528f56afdfdb232e2 Mon Sep 17 00:00:00 2001 From: Daniel Gabay Date: Tue, 8 Oct 2024 07:25:22 +0300 Subject: [PATCH 101/126] wifi: iwlwifi: mvm: Remove redundant rcu_read_lock() in reorder buffer iwl_mvm_reorder() is already called within a rcu-read section. Signed-off-by: Daniel Gabay Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.8f229e1b08b7.I31a371f635d84db300ad16ce6170cc07a8b154fb@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index fdbd63ff91ef..a2f16bfaec44 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -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 || From f2e05b5d972e16bf399b58b38207ec4c479085fc Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 8 Oct 2024 07:25:23 +0300 Subject: [PATCH 102/126] wifi: iwlwifi: mvm: remove unneeded check When checking if extra LTF should be disabled, we don't need to check the the HW revision. sband_eht_cap will be NULL if eht_capa::has_eht is false, and that will be the case for the HWs that don't support EHT. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.78b0adbb7b50.I630a64f06ca86baecde6a2a238733b7df3cf70e4@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 05715e5af6ab..a0c088efd240 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -615,11 +615,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 && From b6ed795539d04139f8d715d9774aef869eb4377e Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 8 Oct 2024 07:25:24 +0300 Subject: [PATCH 103/126] wifi: iwlwifi: mvm: remove IWL_MVM_HW_CSUM_DISABLE This is always set to 0. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.e1b6ab87c969.Ic623ab87cb2a22285cdbed99325fdfcfe439c7d4@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index fdccdea918bf..795a166ed63a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -58,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 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 475e781e166a..5aa48c77b054 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1589,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) From 02ea0fb981f0fada9668fff223d185c953f3b755 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 8 Oct 2024 07:25:25 +0300 Subject: [PATCH 104/126] wifi: iwlwifi: do not warn about a flush with an empty TX queue When resuming it can happen that the TX queue is flushed even though it is entirely empty. This is completely fine and should not be causing an error level log message. Return early from reclaim in that case. Signed-off-by: Benjamin Berg Reviewed-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.7c152d0820be.I3ae39a9a470f47bfe4405f2e5c30327e157eb55f@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 9fe050f0ddc1..1ef14340953c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -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)) { From 43e0b2ada519e9b665135074c0da215f2e8b301a Mon Sep 17 00:00:00 2001 From: Yedidya Benshimol Date: Tue, 8 Oct 2024 07:25:26 +0300 Subject: [PATCH 105/126] wifi: iwlwifi: fw: add an error table status getter Add a function for getting the error status and error code for given error table. Remove a static function of same purpose from mvm/d3.c Signed-off-by: Yedidya Benshimol Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.610a38614ce6.Iab5f795bc30ce5d08550cff1772fe051527bcb95@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 3 +- drivers/net/wireless/intel/iwlwifi/fw/dump.c | 22 ++++++++++++- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 34 ++++++-------------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 98d56e778d99..9d8f89adc322 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -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,6 +327,7 @@ 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); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index 8f107ceec407..3cabdeb53e99 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -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); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 49a6aff42376..9f41b9af5269 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -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; From ab1eab765769da2f9950de27acad0494345cdfec Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 8 Oct 2024 07:25:27 +0300 Subject: [PATCH 106/126] wifi: iwlwifi: mvm: remove redundant check iwl_mvm_sta_from_mac80211 can't return NULL. Remove the check. Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.5d6bab61c75e.I2cfa1669d4534bce9e9cfdace45f797005b71b9b@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index a0c088efd240..de5ac000272e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -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]); From a834cd0c456523c48f0721d6a4d00f73e0a178de Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 8 Oct 2024 07:25:28 +0300 Subject: [PATCH 107/126] wifi: iwlwifi: allow IWL_FW_CHECK() with just a string We require a message, but the macros shouldn't require a formatted message, a constant one can be fine. Change the macros to support that. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20241008072037.96e8554cb7a2.I0e06d8fd49f86bd4e9e216fc2265c43d7e78a095@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 9d8f89adc322..f4803b55adb9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -331,15 +331,15 @@ 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); \ }) From 3607798ad9bdef35ad08489a8239390fccaac6b5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:42 +0200 Subject: [PATCH 108/126] wifi: cfg80211: add option for vif allowed radios This allows users to prevent a vif from affecting radios other than the configured ones. This can be useful in cases where e.g. an AP is running on one radio, and triggering a scan on another radio should not disturb it. Changing the allowed radios list for a vif is supported, but only while it is down. While it is possible to achieve the same by always explicitly specifying a frequency list for scan requests and ensuring that the wrong channel/band is never accidentally set on an unrelated interface, this change makes multi-radio wiphy setups a lot easier to deal with for CLI users. By itself, this patch only enforces the radio mask for scanning requests and remain-on-channel. Follow-up changes build on this to limit configured frequencies. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/eefcb218780f71a1549875d149f1196486762756.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 14 +++++++++ include/uapi/linux/nl80211.h | 5 +++ net/wireless/core.c | 2 ++ net/wireless/nl80211.c | 60 +++++++++++++++++++++++++++++++----- net/wireless/scan.c | 10 ++++-- net/wireless/util.c | 29 +++++++++++++++++ 6 files changed, 109 insertions(+), 11 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index c8ce5c2e14f4..95d05e67e69a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6221,6 +6221,7 @@ enum ieee80211_ap_reg_power { * entered. * @links.cac_time_ms: CAC time in ms * @valid_links: bitmap describing what elements of @links are valid + * @radio_mask: Bitmask of radios that this interface is allowed to operate on. */ struct wireless_dev { struct wiphy *wiphy; @@ -6333,6 +6334,8 @@ struct wireless_dev { unsigned int cac_time_ms; } links[IEEE80211_MLD_MAX_NUM_LINKS]; u16 valid_links; + + u32 radio_mask; }; static inline const u8 *wdev_address(struct wireless_dev *wdev) @@ -6518,6 +6521,17 @@ static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan) bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio, const struct cfg80211_chan_def *chandef); +/** + * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel + * + * @wdev: the wireless device + * @chan: channel to check + * + * Return: whether or not the wdev may use the channel + */ +bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev, + struct ieee80211_channel *chan); + /** * ieee80211_get_response_rate - get basic rate for a given rate * diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f97f5adc8d51..d31ccee99cc7 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2868,6 +2868,9 @@ enum nl80211_commands { * nested item, it contains attributes defined in * &enum nl80211_if_combination_attrs. * + * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32). + * A value of 0 means all radios. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3416,6 +3419,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_RADIOS, NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS, + NL80211_ATTR_VIF_RADIO_MASK, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/core.c b/net/wireless/core.c index 4c8d8f167409..93d62a1d3a45 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1430,6 +1430,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev) /* allow mac80211 to determine the timeout */ wdev->ps_timeout = -1; + wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1; + if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index fb35c03af34c..a330347dd7a3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -829,6 +829,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8), [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8), [NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG }, + [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -3996,7 +3997,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->devlist_generation ^ (cfg80211_rdev_list_generation << 2)) || - nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr)) + nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) || + nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask)) goto nla_put_failure; if (rdev->ops->get_channel && !wdev->valid_links) { @@ -4312,6 +4314,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, return -EOPNOTSUPP; } +static int nl80211_parse_vif_radio_mask(struct genl_info *info, + u32 *radio_mask) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK]; + u32 mask, allowed; + + if (!attr) { + *radio_mask = 0; + return 0; + } + + allowed = BIT(rdev->wiphy.n_radio) - 1; + mask = nla_get_u32(attr); + if (mask & ~allowed) + return -EINVAL; + if (!mask) + mask = allowed; + *radio_mask = mask; + + return 1; +} + static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -4319,6 +4344,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) int err; enum nl80211_iftype otype, ntype; struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + u32 radio_mask = 0; bool change = false; memset(¶ms, 0, sizeof(params)); @@ -4332,8 +4359,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_MESH_ID]) { - struct wireless_dev *wdev = dev->ieee80211_ptr; - if (ntype != NL80211_IFTYPE_MESH_POINT) return -EINVAL; if (otype != NL80211_IFTYPE_MESH_POINT) @@ -4364,6 +4389,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (err > 0) change = true; + err = nl80211_parse_vif_radio_mask(info, &radio_mask); + if (err < 0) + return err; + if (err && netif_running(dev)) + return -EBUSY; + if (change) err = cfg80211_change_iface(rdev, dev, ntype, ¶ms); else @@ -4372,11 +4403,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (!err && params.use_4addr != -1) dev->ieee80211_ptr->use_4addr = params.use_4addr; - if (change && !err) { - struct wireless_dev *wdev = dev->ieee80211_ptr; + if (radio_mask) + wdev->radio_mask = radio_mask; + if (change && !err) nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE); - } return err; } @@ -4387,6 +4418,7 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) struct vif_params params; struct wireless_dev *wdev; struct sk_buff *msg; + u32 radio_mask; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; @@ -4424,6 +4456,10 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) if (err < 0) return err; + err = nl80211_parse_vif_radio_mask(info, &radio_mask); + if (err < 0) + return err; + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -4465,6 +4501,9 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) break; } + if (radio_mask) + wdev->radio_mask = radio_mask; + if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) { nlmsg_free(msg); @@ -9156,6 +9195,9 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, lockdep_assert_wiphy(wdev->wiphy); + if (!cfg80211_wdev_channel_allowed(wdev, chan)) + return false; + if (!cfg80211_beaconing_iface_active(wdev)) return true; @@ -9368,7 +9410,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) } /* ignore disabled channels */ - if (chan->flags & IEEE80211_CHAN_DISABLED) + if (chan->flags & IEEE80211_CHAN_DISABLED || + !cfg80211_wdev_channel_allowed(wdev, chan)) continue; request->channels[i] = chan; @@ -9388,7 +9431,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) chan = &wiphy->bands[band]->channels[j]; - if (chan->flags & IEEE80211_CHAN_DISABLED) + if (chan->flags & IEEE80211_CHAN_DISABLED || + !cfg80211_wdev_channel_allowed(wdev, chan)) continue; request->channels[i] = chan; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 8ba618f4734f..8e3d46bf4836 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -956,7 +956,8 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) struct ieee80211_channel *chan = ieee80211_get_channel(&rdev->wiphy, ap->center_freq); - if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) + if (!chan || chan->flags & IEEE80211_CHAN_DISABLED || + !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan)) continue; for (i = 0; i < rdev_req->n_channels; i++) { @@ -3515,9 +3516,12 @@ int cfg80211_wext_siwscan(struct net_device *dev, continue; for (j = 0; j < wiphy->bands[band]->n_channels; j++) { + struct ieee80211_channel *chan; + /* ignore disabled channels */ - if (wiphy->bands[band]->channels[j].flags & - IEEE80211_CHAN_DISABLED) + chan = &wiphy->bands[band]->channels[j]; + if (chan->flags & IEEE80211_CHAN_DISABLED || + !cfg80211_wdev_channel_allowed(creq->wdev, chan)) continue; /* If we have a wireless request structure and the diff --git a/net/wireless/util.c b/net/wireless/util.c index 93a9c32418a6..040d62051eb9 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -2923,3 +2923,32 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio, return true; } EXPORT_SYMBOL(cfg80211_radio_chandef_valid); + +bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev, + struct ieee80211_channel *chan) +{ + struct wiphy *wiphy = wdev->wiphy; + const struct wiphy_radio *radio; + struct cfg80211_chan_def chandef; + u32 radio_mask; + int i; + + radio_mask = wdev->radio_mask; + if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1) + return true; + + cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); + for (i = 0; i < wiphy->n_radio; i++) { + if (!(radio_mask & BIT(i))) + continue; + + radio = &wiphy->radio[i]; + if (!cfg80211_radio_chandef_valid(radio, &chandef)) + continue; + + return true; + } + + return false; +} +EXPORT_SYMBOL(cfg80211_wdev_channel_allowed); From 32ee616a7f8c36fa3ab00985ebd038c3487e721f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:43 +0200 Subject: [PATCH 109/126] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Reject frequencies not supported by any radio that the vif is allowed to use. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/9d5c0b6b00a7ecef6a0ac6de765c0af00c8bb0e1.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/scan.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index adb88c06b598..cb7079071885 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -1176,14 +1176,14 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, unsigned int n_channels) { struct ieee80211_local *local = sdata->local; - int ret = -EBUSY, i, n_ch = 0; + int i, n_ch = 0; enum nl80211_band band; lockdep_assert_wiphy(local->hw.wiphy); /* busy scanning */ if (local->scan_req) - goto unlock; + return -EBUSY; /* fill internal scan request */ if (!channels) { @@ -1200,7 +1200,9 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, &local->hw.wiphy->bands[band]->channels[i]; if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR | - IEEE80211_CHAN_DISABLED)) + IEEE80211_CHAN_DISABLED) || + !cfg80211_wdev_channel_allowed(&sdata->wdev, + tmp_ch)) continue; local->int_scan_req->channels[n_ch] = tmp_ch; @@ -1209,21 +1211,23 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, } if (WARN_ON_ONCE(n_ch == 0)) - goto unlock; + return -EINVAL; local->int_scan_req->n_channels = n_ch; } else { for (i = 0; i < n_channels; i++) { if (channels[i]->flags & (IEEE80211_CHAN_NO_IR | - IEEE80211_CHAN_DISABLED)) + IEEE80211_CHAN_DISABLED) || + !cfg80211_wdev_channel_allowed(&sdata->wdev, + channels[i])) continue; local->int_scan_req->channels[n_ch] = channels[i]; n_ch++; } - if (WARN_ON_ONCE(n_ch == 0)) - goto unlock; + if (n_ch == 0) + return -EINVAL; local->int_scan_req->n_channels = n_ch; } @@ -1233,9 +1237,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); local->int_scan_req->ssids[0].ssid_len = ssid_len; - ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); - unlock: - return ret; + return __ieee80211_start_scan(sdata, sdata->local->int_scan_req); } void ieee80211_scan_cancel(struct ieee80211_local *local) From 7b68f63d5c00105f8b1f28017369f1da6dfe704c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:44 +0200 Subject: [PATCH 110/126] wifi: mac80211: use vif radio mask to limit creating chanctx Reject frequencies not supported by any radio that the vif is allowed to use. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/95ea1f6fc5bd1614a0c7952b6c67726e3fd635fb.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 0e44f4e38099..996965005d49 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1177,7 +1177,7 @@ ieee80211_replace_chanctx(struct ieee80211_local *local, static bool ieee80211_find_available_radio(struct ieee80211_local *local, const struct ieee80211_chan_req *chanreq, - int *radio_idx) + u32 radio_mask, int *radio_idx) { struct wiphy *wiphy = local->hw.wiphy; const struct wiphy_radio *radio; @@ -1188,6 +1188,9 @@ ieee80211_find_available_radio(struct ieee80211_local *local, return true; for (i = 0; i < wiphy->n_radio; i++) { + if (!(radio_mask & BIT(i))) + continue; + radio = &wiphy->radio[i]; if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) continue; @@ -1221,7 +1224,9 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); if (!new_ctx) { if (ieee80211_can_create_new_chanctx(local, -1) && - ieee80211_find_available_radio(local, chanreq, &radio_idx)) + ieee80211_find_available_radio(local, chanreq, + sdata->wdev.radio_mask, + &radio_idx)) new_ctx = ieee80211_new_chanctx(local, chanreq, mode, false, radio_idx); else @@ -1891,7 +1896,9 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, /* Note: context is now reserved */ if (ctx) reserved = true; - else if (!ieee80211_find_available_radio(local, chanreq, &radio_idx)) + else if (!ieee80211_find_available_radio(local, chanreq, + sdata->wdev.radio_mask, + &radio_idx)) ctx = ERR_PTR(-EBUSY); else ctx = ieee80211_new_chanctx(local, chanreq, mode, From ebda716ea4da03326ac4d0a71604d18aa8a2e695 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:45 +0200 Subject: [PATCH 111/126] wifi: cfg80211: report per wiphy radio antenna mask With multi-radio devices, each radio typically gets a fixed set of antennas. In order to be able to disable specific antennas for some radios, user space needs to know which antenna mask bits are assigned to which radio. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/e0a26afa2c88eaa188ec96ec6d17ecac4e827641.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 4 ++++ include/uapi/linux/nl80211.h | 3 +++ net/wireless/nl80211.c | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 95d05e67e69a..3100733f3e23 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5434,6 +5434,8 @@ struct wiphy_radio_freq_range { * @iface_combinations: Valid interface combinations array, should not * list single interface types. * @n_iface_combinations: number of entries in @iface_combinations array. + * + * @antenna_mask: bitmask of antennas connected to this radio. */ struct wiphy_radio { const struct wiphy_radio_freq_range *freq_range; @@ -5441,6 +5443,8 @@ struct wiphy_radio { const struct ieee80211_iface_combination *iface_combinations; int n_iface_combinations; + + u32 antenna_mask; }; #define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d31ccee99cc7..1b8827f920ff 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -8036,6 +8036,8 @@ enum nl80211_ap_settings_flags { * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface * combination for this radio. Attribute may be present multiple times * and contains attributes defined in &enum nl80211_if_combination_attrs. + * @NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK: bitmask (u32) of antennas + * connected to this radio. * * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute @@ -8046,6 +8048,7 @@ enum nl80211_wiphy_radio_attrs { NL80211_WIPHY_RADIO_ATTR_INDEX, NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE, NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, + NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK, /* keep last */ __NL80211_WIPHY_RADIO_ATTR_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a330347dd7a3..aa78f18dd454 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2431,6 +2431,11 @@ static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx) if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx)) goto nla_put_failure; + if (r->antenna_mask && + nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK, + r->antenna_mask)) + goto nla_put_failure; + for (i = 0; i < r->n_freq_range; i++) { const struct wiphy_radio_freq_range *range = &r->freq_range[i]; From 006a97ceb6732c861c0e2fa3b6a34512caac9354 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:46 +0200 Subject: [PATCH 112/126] wifi: mac80211: remove status->ampdu_delimiter_crc This was never used by any driver, so remove it to free up some space. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/e6fee6eed49b105261830db1c74f13841fb9616c.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 +----- net/mac80211/rx.c | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 32bdda90a4ac..d4f23224eff9 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1463,8 +1463,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU * @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected * on this subframe - * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC - * is stored in the @ampdu_delimiter_crc field) * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was * done by the hardware * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without @@ -1536,7 +1534,7 @@ enum mac80211_rx_flags { RX_FLAG_AMPDU_LAST_KNOWN = BIT(12), RX_FLAG_AMPDU_IS_LAST = BIT(13), RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(14), - RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15), + /* one free bit at 15 */ RX_FLAG_MACTIME = BIT(16) | BIT(17), RX_FLAG_MACTIME_PLCP_START = 1 << 16, RX_FLAG_MACTIME_START = 2 << 16, @@ -1633,7 +1631,6 @@ enum mac80211_rx_encoding { * @rx_flags: internal RX flags for mac80211 * @ampdu_reference: A-MPDU reference number, must be a different value for * each A-MPDU but the same for each subframe within one A-MPDU - * @ampdu_delimiter_crc: A-MPDU delimiter CRC * @zero_length_psdu_type: radiotap type of the 0-length PSDU * @link_valid: if the link which is identified by @link_id is valid. This flag * is set only when connection is MLO. @@ -1671,7 +1668,6 @@ struct ieee80211_rx_status { s8 signal; u8 chains; s8 chain_signal[IEEE80211_MAX_CHAINS]; - u8 ampdu_delimiter_crc; u8 zero_length_psdu_type; u8 link_valid:1, link_id:4; }; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d7b294221d43..a34523bbd156 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -508,18 +508,13 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST; if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR) flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR; - if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) - flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN) flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN; if (status->flag & RX_FLAG_AMPDU_EOF_BIT) flags |= IEEE80211_RADIOTAP_AMPDU_EOF; put_unaligned_le16(flags, pos); pos += 2; - if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) - *pos++ = status->ampdu_delimiter_crc; - else - *pos++ = 0; + *pos++ = 0; *pos++ = 0; } From 9c4f830927750a2bf9fd9426a5257f0fdce3b662 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:47 +0200 Subject: [PATCH 113/126] wifi: cfg80211: pass net_device to .set_monitor_channel Preparation for allowing multiple monitor interfaces with different channels on a multi-radio wiphy. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/35fa652dbfebf93343f8b9a08fdef0467a2a02dc.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/wil6210/cfg80211.c | 1 + drivers/net/wireless/marvell/libertas/cfg.c | 1 + drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++- include/net/cfg80211.h | 1 + net/mac80211/cfg.c | 1 + net/wireless/chan.c | 3 ++- net/wireless/core.h | 1 + net/wireless/nl80211.c | 2 +- net/wireless/rdev-ops.h | 5 +++-- net/wireless/trace.h | 10 ++++++---- net/wireless/wext-compat.c | 2 +- 11 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index e8f1d30a8d73..a1a0a9223e74 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -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); diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c index afe9bcd3ad46..2e2c193716d9 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c @@ -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); diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index b0dae6f7c633..e96736cc7259 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -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"); diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3100733f3e23..5feb93ba0400 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4694,6 +4694,7 @@ struct cfg80211_ops { struct ieee80211_channel *chan); int (*set_monitor_channel)(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_chan_def *chandef); int (*scan)(struct wiphy *wiphy, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ecc138869b4b..492349d6f7bb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -897,6 +897,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_set_monitor_channel(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_chan_def *chandef) { struct ieee80211_local *local = wiphy_priv(wiphy); diff --git a/net/wireless/chan.c b/net/wireless/chan.c index afd86f7c66ce..40b6375a5de4 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -1628,6 +1628,7 @@ bool cfg80211_reg_check_beaconing(struct wiphy *wiphy, EXPORT_SYMBOL(cfg80211_reg_check_beaconing); int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, + struct net_device *dev, struct cfg80211_chan_def *chandef) { if (!rdev->ops->set_monitor_channel) @@ -1635,7 +1636,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, if (!cfg80211_has_monitors_only(rdev)) return -EBUSY; - return rdev_set_monitor_channel(rdev, chandef); + return rdev_set_monitor_channel(rdev, dev, chandef); } bool cfg80211_any_usable_channels(struct wiphy *wiphy, diff --git a/net/wireless/core.h b/net/wireless/core.h index 3b3e3cd7027a..4c45f994a8c0 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -516,6 +516,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start) } int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, + struct net_device *dev, struct cfg80211_chan_def *chandef); int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index aa78f18dd454..84015f56e93a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3567,7 +3567,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_MESH_POINT: return cfg80211_set_mesh_channel(rdev, wdev, &chandef); case NL80211_IFTYPE_MONITOR: - return cfg80211_set_monitor_channel(rdev, &chandef); + return cfg80211_set_monitor_channel(rdev, dev, &chandef); default: break; } diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index f5adbf6b5c84..adb6105bbb7d 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -445,11 +445,12 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev, static inline int rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, + struct net_device *dev, struct cfg80211_chan_def *chandef) { int ret; - trace_rdev_set_monitor_channel(&rdev->wiphy, chandef); - ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef); + trace_rdev_set_monitor_channel(&rdev->wiphy, dev, chandef); + ret = rdev->ops->set_monitor_channel(&rdev->wiphy, dev, chandef); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 97c21b627791..d5c9bb614fa6 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -1318,19 +1318,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel, ); TRACE_EVENT(rdev_set_monitor_channel, - TP_PROTO(struct wiphy *wiphy, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_chan_def *chandef), - TP_ARGS(wiphy, chandef), + TP_ARGS(wiphy, netdev, chandef), TP_STRUCT__entry( WIPHY_ENTRY + NETDEV_ENTRY CHAN_DEF_ENTRY ), TP_fast_assign( WIPHY_ASSIGN; + NETDEV_ASSIGN; CHAN_DEF_ASSIGN(chandef); ), - TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, - WIPHY_PR_ARG, CHAN_DEF_PR_ARG) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) ); TRACE_EVENT(rdev_auth, diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 0c8d3797a02e..90d5c0592667 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -821,7 +821,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, ret = -EINVAL; break; } - ret = cfg80211_set_monitor_channel(rdev, &chandef); + ret = cfg80211_set_monitor_channel(rdev, dev, &chandef); break; case NL80211_IFTYPE_MESH_POINT: freq = cfg80211_wext_freq(wextfreq); From 9d40f7e32774279be7e5a7a278d7a290872b2f81 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:48 +0200 Subject: [PATCH 114/126] wifi: mac80211: add flag to opt out of virtual monitor support This is useful for multi-radio devices that are capable of monitoring on multiple channels simultanenously. When this flag is set, each monitor interface is passed to the driver individually and can have a configured channel. The vif mac address for non-active monitor interfaces is cleared, in order to allow the driver to tell them apart from active ones. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/3c55505ee0cf0a5f141fbcb30d1e8be8d9f40373.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 44 +++++++++++++++++++++++++-------------- net/mac80211/chan.c | 14 ++++++++++++- net/mac80211/debugfs.c | 1 + net/mac80211/driver-ops.c | 1 + net/mac80211/iface.c | 22 +++++++++++++++----- net/mac80211/rx.c | 3 +++ net/mac80211/tx.c | 6 ++++-- net/mac80211/util.c | 14 +++++++++---- 9 files changed, 83 insertions(+), 28 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d4f23224eff9..b4f246cdcca4 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2694,6 +2694,11 @@ struct ieee80211_txq { * a virtual monitor interface when monitor interfaces are the only * active interfaces. * + * @IEEE80211_HW_NO_VIRTUAL_MONITOR: The driver would like to be informed + * of any monitor interface, as well as their configured channel. + * This is useful for supporting multiple monitor interfaces on different + * channels. + * * @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to * be created. It is expected user-space will create vifs as * desired (and thus have them named as desired). @@ -2853,6 +2858,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_DYNAMIC_PS, IEEE80211_HW_MFP_CAPABLE, IEEE80211_HW_WANT_MONITOR_VIF, + IEEE80211_HW_NO_VIRTUAL_MONITOR, IEEE80211_HW_NO_AUTO_VIF, IEEE80211_HW_SW_CRYPTO_CONTROL, IEEE80211_HW_SUPPORT_FAST_XMIT, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 492349d6f7bb..6c0b228523cb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -105,8 +105,11 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata, } /* also validate MU-MIMO change */ - monitor_sdata = wiphy_dereference(local->hw.wiphy, - local->monitor_sdata); + if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + monitor_sdata = sdata; + else + monitor_sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata); if (!monitor_sdata && (params->vht_mumimo_groups || params->vht_mumimo_follow_addr)) @@ -114,7 +117,9 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata, /* apply all changes now - no failures allowed */ - if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) + if (monitor_sdata && + (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) || + ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))) ieee80211_set_mu_mimo_follow(monitor_sdata, params); if (params->flags) { @@ -907,22 +912,25 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, lockdep_assert_wiphy(local->hw.wiphy); - if (cfg80211_chandef_identical(&local->monitor_chanreq.oper, - &chanreq.oper)) - return 0; + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { + if (cfg80211_chandef_identical(&local->monitor_chanreq.oper, + &chanreq.oper)) + return 0; - sdata = wiphy_dereference(local->hw.wiphy, - local->monitor_sdata); - if (!sdata) - goto done; + sdata = wiphy_dereference(wiphy, local->monitor_sdata); + if (!sdata) + goto done; + } - if (cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper, + if (rcu_access_pointer(sdata->deflink.conf->chanctx_conf) && + cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper, &chanreq.oper)) return 0; ieee80211_link_release_channel(&sdata->deflink); ret = ieee80211_link_use_channel(&sdata->deflink, &chanreq, - IEEE80211_CHANCTX_EXCLUSIVE); + IEEE80211_CHANCTX_SHARED); if (ret) return ret; done: @@ -3084,7 +3092,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, if (wdev) { sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) return -EOPNOTSUPP; @@ -3118,7 +3127,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, local->user_power_level = user_power_level; list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { has_monitor = true; continue; } @@ -3139,7 +3149,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, } } list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_MONITOR) + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) continue; for (int link_id = 0; @@ -4342,7 +4353,8 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, if (chanctx_conf) { *chandef = link->conf->chanreq.oper; ret = 0; - } else if (local->open_count > 0 && + } else if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) && + local->open_count > 0 && local->open_count == local->monitors && sdata->vif.type == NL80211_IFTYPE_MONITOR) { *chandef = local->monitor_chanreq.oper; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 996965005d49..a442cb667520 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -347,6 +347,10 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: continue; + case NL80211_IFTYPE_MONITOR: + WARN_ON_ONCE(!ieee80211_hw_check(&local->hw, + NO_VIRTUAL_MONITOR)); + fallthrough; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_OCB: @@ -355,7 +359,6 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: WARN_ON_ONCE(1); @@ -964,6 +967,10 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, if (!link->sdata->u.mgd.associated) continue; break; + case NL80211_IFTYPE_MONITOR: + if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + continue; + break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: @@ -976,6 +983,11 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, if (rcu_access_pointer(link->conf->chanctx_conf) != &chanctx->conf) continue; + if (link->sdata->vif.type == NL80211_IFTYPE_MONITOR) { + rx_chains_dynamic = rx_chains_static = local->rx_chains; + break; + } + switch (link->smps_mode) { default: WARN_ONCE(1, "Invalid SMPS mode %d\n", diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 02b5476a4376..b777240c924e 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -456,6 +456,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_DYNAMIC_PS), FLAG(MFP_CAPABLE), FLAG(WANT_MONITOR_VIF), + FLAG(NO_VIRTUAL_MONITOR), FLAG(NO_AUTO_VIF), FLAG(SW_CRYPTO_CONTROL), FLAG(SUPPORT_FAST_XMIT), diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index 84d048339113..299d38e9e863 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -65,6 +65,7 @@ int drv_add_interface(struct ieee80211_local *local, if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || (sdata->vif.type == NL80211_IFTYPE_MONITOR && !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) && !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)))) return -EINVAL; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7a99fa057cd9..683cc50cc266 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -279,8 +279,13 @@ static int _ieee80211_change_mac(struct ieee80211_sub_if_data *sdata, ret = eth_mac_addr(sdata->dev, sa); if (ret == 0) { - memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); - ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); + if (check_dup) { + memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); + ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); + } else { + memset(sdata->vif.addr, 0, ETH_ALEN); + memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN); + } } /* Regardless of eth_mac_addr() return we still want to add the @@ -699,9 +704,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do ieee80211_recalc_idle(local); ieee80211_recalc_offload(local); - if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) + if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) break; + ieee80211_link_release_channel(&sdata->deflink); fallthrough; default: if (!going_down) @@ -1131,7 +1138,8 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); - if (local->monitor_sdata) + if (local->monitor_sdata || + ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) return 0; sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); @@ -1193,6 +1201,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; + if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + return; + ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); @@ -1328,7 +1339,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) break; } - if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { + if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) || + ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { res = drv_add_interface(local, sdata); if (res) goto err_stop; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a34523bbd156..d032bfb00ade 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -840,6 +840,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, bool last_monitor = list_is_last(&sdata->u.mntr.list, &local->mon_list); + if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space); + if (!monskb) monskb = ieee80211_make_monitor_skb(local, &origskb, rate, rtap_space, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f10379bef9fb..a24636bda679 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1763,7 +1763,8 @@ static bool __ieee80211_tx(struct ieee80211_local *local, switch (sdata->vif.type) { case NL80211_IFTYPE_MONITOR: - if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { + if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) || + ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { vif = &sdata->vif; break; } @@ -3952,7 +3953,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, switch (tx.sdata->vif.type) { case NL80211_IFTYPE_MONITOR: - if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { + if ((tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) || + ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { vif = &tx.sdata->vif; break; } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bd93de637f94..a4e1301cc999 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -756,7 +756,8 @@ static void __iterate_interfaces(struct ieee80211_local *local, lockdep_is_held(&local->hw.wiphy->mtx)) { switch (sdata->vif.type) { case NL80211_IFTYPE_MONITOR: - if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) + if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) continue; break; case NL80211_IFTYPE_AP_VLAN: @@ -1873,8 +1874,10 @@ int ieee80211_reconfig(struct ieee80211_local *local) } list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + continue; if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_MONITOR && ieee80211_sdata_running(sdata)) { res = drv_add_interface(local, sdata); if (WARN_ON(res)) @@ -1887,11 +1890,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) */ if (res) { list_for_each_entry_continue_reverse(sdata, &local->interfaces, - list) + list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + continue; if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_MONITOR && ieee80211_sdata_running(sdata)) drv_remove_interface(local, sdata); + } ieee80211_handle_reconfig_failure(local); return res; } From a77e527b470cc38754c730bce1483711f643bb60 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:49 +0200 Subject: [PATCH 115/126] wifi: cfg80211: add monitor SKIP_TX flag This can be used to indicate that the user is not interested in receiving locally sent packets on the monitor interface. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/f0c20f832eadd36c71fba9a2a16ba57d78389b6c.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 2 ++ include/uapi/linux/nl80211.h | 2 ++ net/wireless/nl80211.c | 1 + 3 files changed, 5 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5feb93ba0400..8f9853b1a5d1 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2267,6 +2267,7 @@ static inline int cfg80211_get_station(struct net_device *dev, * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering * @MONITOR_FLAG_COOK_FRAMES: report frames after processing * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address + * @MONITOR_FLAG_SKIP_TX: do not pass locally transmitted frames */ enum monitor_flags { MONITOR_FLAG_CHANGED = BIT(__NL80211_MNTR_FLAG_INVALID), @@ -2276,6 +2277,7 @@ enum monitor_flags { MONITOR_FLAG_OTHER_BSS = BIT(NL80211_MNTR_FLAG_OTHER_BSS), MONITOR_FLAG_COOK_FRAMES = BIT(NL80211_MNTR_FLAG_COOK_FRAMES), MONITOR_FLAG_ACTIVE = BIT(NL80211_MNTR_FLAG_ACTIVE), + MONITOR_FLAG_SKIP_TX = BIT(NL80211_MNTR_FLAG_SKIP_TX), }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 1b8827f920ff..6d11437596b9 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4703,6 +4703,7 @@ enum nl80211_survey_info { * overrides all other flags. * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address * and ACK incoming unicast packets. + * @NL80211_MNTR_FLAG_SKIP_TX: do not pass local tx packets * * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag @@ -4715,6 +4716,7 @@ enum nl80211_mntr_flags { NL80211_MNTR_FLAG_OTHER_BSS, NL80211_MNTR_FLAG_COOK_FRAMES, NL80211_MNTR_FLAG_ACTIVE, + NL80211_MNTR_FLAG_SKIP_TX, /* keep last */ __NL80211_MNTR_FLAG_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 84015f56e93a..4a8c3b6d49d1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4206,6 +4206,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG }, + [NL80211_MNTR_FLAG_SKIP_TX] = { .type = NLA_FLAG }, }; static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) From 754905ce1a327ee3297548e132367038cc62b3d8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:50 +0200 Subject: [PATCH 116/126] wifi: mac80211: add support for the monitor SKIP_TX flag Do not pass locally sent packets to monitor interfaces with this flag set. Skip processing tx packets on the status call entirely if no monitor interfaces without this flag are present. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/c327bb57ef8dadaa6a0e8e4dc2f5f99ae8123e6c.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/iface.c | 2 ++ net/mac80211/status.c | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d20c2e796703..7dcb46120abc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1368,7 +1368,7 @@ struct ieee80211_local { spinlock_t queue_stop_reason_lock; int open_count; - int monitors, cooked_mntrs; + int monitors, cooked_mntrs, tx_mntrs; /* number of interfaces with corresponding FIF_ flags */ int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, fif_probe_req; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 683cc50cc266..57f6fac343eb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1094,6 +1094,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, ADJUST(CONTROL, control); ADJUST(CONTROL, pspoll); ADJUST(OTHER_BSS, other_bss); + if (!(flags & MONITOR_FLAG_SKIP_TX)) + local->tx_mntrs += offset; #undef ADJUST } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index b41b867f43b2..5f28f3633fa0 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -927,6 +927,9 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb, if (!ieee80211_sdata_running(sdata)) continue; + if (sdata->u.mntr.flags & MONITOR_FLAG_SKIP_TX) + continue; + if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) && !send_to_cooked) continue; @@ -1099,7 +1102,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw, * This is a bit racy but we can avoid a lot of work * with this test... */ - if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) { + if (!local->tx_mntrs && (!send_to_cooked || !local->cooked_mntrs)) { if (status->free_list) list_add_tail(&skb->list, status->free_list); else From 342afe693ee765a215343fe1a1af0d6c8b8e10a3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:51 +0200 Subject: [PATCH 117/126] wifi: mac80211: refactor ieee80211_rx_monitor Rework the monitor mode interface iteration to get rid of the last_monitor condition. Preparation for further filtering received monitor packets. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/d57d82f109643894325beb9db6da8f001fc533eb.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 56 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d032bfb00ade..4849af232ee6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -762,8 +762,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, struct ieee80211_rate *rate) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); - struct ieee80211_sub_if_data *sdata; - struct sk_buff *monskb = NULL; + struct ieee80211_sub_if_data *sdata, *prev_sdata = NULL; + struct sk_buff *skb, *monskb = NULL; int present_fcs_len = 0; unsigned int rtap_space = 0; struct ieee80211_sub_if_data *monitor_sdata = @@ -837,8 +837,10 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space); list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) { - bool last_monitor = list_is_last(&sdata->u.mntr.list, - &local->mon_list); + if (!prev_sdata) { + prev_sdata = sdata; + continue; + } if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space); @@ -846,34 +848,34 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, if (!monskb) monskb = ieee80211_make_monitor_skb(local, &origskb, rate, rtap_space, - only_monitor && - last_monitor); + false); + if (!monskb) + continue; - if (monskb) { - struct sk_buff *skb; + skb = skb_clone(monskb, GFP_ATOMIC); + if (!skb) + continue; - if (last_monitor) { - skb = monskb; - monskb = NULL; - } else { - skb = skb_clone(monskb, GFP_ATOMIC); - } - - if (skb) { - skb->dev = sdata->dev; - dev_sw_netstats_rx_add(skb->dev, skb->len); - netif_receive_skb(skb); - } - } - - if (last_monitor) - break; + skb->dev = prev_sdata->dev; + dev_sw_netstats_rx_add(skb->dev, skb->len); + netif_receive_skb(skb); + prev_sdata = sdata; } - /* this happens if last_monitor was erroneously false */ - dev_kfree_skb(monskb); + if (prev_sdata) { + if (monskb) + skb = monskb; + else + skb = ieee80211_make_monitor_skb(local, &origskb, + rate, rtap_space, + only_monitor); + if (skb) { + skb->dev = prev_sdata->dev; + dev_sw_netstats_rx_add(skb->dev, skb->len); + netif_receive_skb(skb); + } + } - /* ditto */ if (!origskb) return NULL; From f92e0cf19ae0fd08e7b60f24d27a5819d8d949ba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Oct 2024 10:25:52 +0200 Subject: [PATCH 118/126] wifi: mac80211: filter on monitor interfaces based on configured channel When a monitor interface has an assigned channel (only happens with the NO_VIRTUAL_MONITOR feature), only pass packets received on that channel. This is useful for monitoring on multiple channels at the same time using multiple monitor interfaces. Signed-off-by: Felix Fietkau Link: https://patch.msgid.link/1bbe55107ba0f2e62ea90f305faeb7ba9247ef29.1728462320.git-series.nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 4849af232ee6..2bec18fc1b03 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -837,6 +837,13 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space); list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) { + struct cfg80211_chan_def *chandef; + + chandef = &sdata->vif.bss_conf.chanreq.oper; + if (chandef->chan && + chandef->chan->center_freq != status->freq) + continue; + if (!prev_sdata) { prev_sdata = sdata; continue; From 2d63e6530ec1f50f57c1cde598274d055fb7a36c Mon Sep 17 00:00:00 2001 From: Michael-CY Lee Date: Wed, 9 Oct 2024 20:18:12 +0800 Subject: [PATCH 119/126] wifi: mac80211: refactor BW limitation check for CSA parsing Refactor the BW limitation check to a more general format when parsing CSA. Also, the original BW check did not account for BW less than 160 MHz. Signed-off-by: Michael-CY Lee Link: https://patch.msgid.link/20241009121812.2419-1-michael-cy.lee@mediatek.com Signed-off-by: Johannes Berg --- net/mac80211/spectmgmt.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 073ff9e0f397..c6015cd00372 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -377,13 +377,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, /* capture the AP chandef before (potential) downgrading */ csa_ie->chanreq.ap = new_chandef; - if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_320 && - new_chandef.width == NL80211_CHAN_WIDTH_320) - ieee80211_chandef_downgrade(&new_chandef, NULL); - - if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_160 && - (new_chandef.width == NL80211_CHAN_WIDTH_80P80 || - new_chandef.width == NL80211_CHAN_WIDTH_160)) + while (conn->bw_limit < + ieee80211_min_bw_limit_from_chandef(&new_chandef)) ieee80211_chandef_downgrade(&new_chandef, NULL); if (!cfg80211_chandef_compatible(&new_chandef, From 6ee0270943b5af02fd6703d5b580d7ca96ff1176 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 11 Oct 2024 14:52:30 +0200 Subject: [PATCH 120/126] wifi: mac80211_hwsim: use hrtimer_active() Instead of hrtimer_is_queued(), use hrtimer_active() since it might be running concurrently, and then it's not queued at that point in time, as suggested by Thomas Gleixner in https://lore.kernel.org/87plqn5psu.ffs@tglx, I just never got to this for ages. I think the concurrency is otherwise fine since we'll get to cancel if we're actually removing things, and otherwise we just send a beacon at slightly the wrong time or so. Reported-by: syzbot+41e4341f493f1155aa3d@syzkaller.appspotmail.com Link: https://patch.msgid.link/20241011145230.5a4d38d4ff9b.Iac0ec316a0c9a7b2619abe52ddc8e04c25d8c7e1@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/virtual/mac80211_hwsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index fe3e2dc1626b..2a36b58f7a15 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -2442,7 +2442,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) if (!data->started || !link_data->beacon_int) { hrtimer_cancel(&link_data->beacon_timer); - } else if (!hrtimer_is_queued(&link_data->beacon_timer)) { + } else if (!hrtimer_active(&link_data->beacon_timer)) { u64 tsf = mac80211_hwsim_get_tsf(hw, NULL); u32 bcn_int = link_data->beacon_int; u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); @@ -2537,7 +2537,7 @@ static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw, info->enable_beacon, info->beacon_int); vp->bcn_en = info->enable_beacon; if (data->started && - !hrtimer_is_queued(&link_data->beacon_timer) && + !hrtimer_active(&link_data->beacon_timer) && info->enable_beacon) { u64 tsf, until_tbtt; u32 bcn_int; From b457d8713872a9aad89c8a57dd8fe471c7db158d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 21 Oct 2024 15:14:14 +0200 Subject: [PATCH 121/126] wifi: mac80211: remove misleading j_0 construction parts The GCM algorithm implementation in the kernel assumes that a 12-byte IV is passed, not the actual J_0 from the GCM spec. Don't rename, that'd be messy, but also don't fill the bytes beyond the IV that aren't used, since otherwise it looks as though j_0[12] is used uninitialized. Link: https://patch.msgid.link/20241021151414.798ceb7a5896.Ic57751edad228d56865ecf7433fef469e5e0a4aa@changeid Signed-off-by: Johannes Berg --- net/mac80211/wpa.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 293afa3f57c5..40d5d9e48479 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -598,9 +598,6 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad, memcpy(j_0, hdr->addr2, ETH_ALEN); memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN); - j_0[13] = 0; - j_0[14] = 0; - j_0[AES_BLOCK_SIZE - 1] = 0x01; ccmp_gcmp_aad(skb, aad, spp_amsdu); } From 8dc6d81c6b2acc434b00c4585f0594739031c4e4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 Oct 2024 15:18:34 +0200 Subject: [PATCH 122/126] debugfs: add small file operations for most files As struct file_operations is really big, but (most) debugfs files only use simple_open, read, write and perhaps seek, and don't need anything else, this wastes a lot of space for NULL pointers. Add a struct debugfs_short_fops and some bookkeeping code in debugfs so that users can use that with debugfs_create_file() using _Generic to figure out which function to use. Converting mac80211 to use it where possible saves quite a bit of space: 1010127 205064 1220 1216411 128f9b net/mac80211/mac80211.ko (before) 981199 205064 1220 1187483 121e9b net/mac80211/mac80211.ko (after) ------- -28928 = ~28KiB With a marginal space cost in debugfs: 8701 550 16 9267 2433 fs/debugfs/inode.o (before) 25233 325 32 25590 63f6 fs/debugfs/file.o (before) 8914 558 16 9488 2510 fs/debugfs/inode.o (after) 25380 325 32 25737 6489 fs/debugfs/file.o (after) --------------- +360 +8 (All on x86-64) A simple spatch suggests there are more than 300 instances, not even counting the ones hidden in macros like in mac80211, that could be trivially converted, for additional savings of about 240 bytes for each. Reviewed-by: Greg Kroah-Hartman Link: https://patch.msgid.link/20241022151838.26f9925fb959.Ia80b55e934bbfc45ce0df42a3233d34b35508046@changeid Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 100 ++++++++++++++++++++++++++++------------ fs/debugfs/inode.c | 63 +++++++++++-------------- fs/debugfs/internal.h | 6 +++ include/linux/debugfs.h | 62 +++++++++++++++++++++++-- 4 files changed, 160 insertions(+), 71 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 67299e8b734e..47dc96dfe386 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -100,8 +100,16 @@ int debugfs_file_get(struct dentry *dentry) if (!fsd) return -ENOMEM; - fsd->real_fops = (void *)((unsigned long)d_fsd & - ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); + if ((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT) { + fsd->real_fops = NULL; + fsd->short_fops = (void *)((unsigned long)d_fsd & + ~(DEBUGFS_FSDATA_IS_REAL_FOPS_BIT | + DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT)); + } else { + fsd->real_fops = (void *)((unsigned long)d_fsd & + ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); + fsd->short_fops = NULL; + } refcount_set(&fsd->active_users, 1); init_completion(&fsd->active_users_drained); INIT_LIST_HEAD(&fsd->cancellations); @@ -241,9 +249,10 @@ static int debugfs_locked_down(struct inode *inode, { if ((inode->i_mode & 07777 & ~0444) == 0 && !(filp->f_mode & FMODE_WRITE) && - !real_fops->unlocked_ioctl && - !real_fops->compat_ioctl && - !real_fops->mmap) + (!real_fops || + (!real_fops->unlocked_ioctl && + !real_fops->compat_ioctl && + !real_fops->mmap))) return 0; if (security_locked_down(LOCKDOWN_DEBUGFS)) @@ -316,19 +325,38 @@ static ret_type full_proxy_ ## name(proto) \ return r; \ } -FULL_PROXY_FUNC(llseek, loff_t, filp, - PROTO(struct file *filp, loff_t offset, int whence), - ARGS(filp, offset, whence)); +#define FULL_PROXY_FUNC_BOTH(name, ret_type, filp, proto, args) \ +static ret_type full_proxy_ ## name(proto) \ +{ \ + struct dentry *dentry = F_DENTRY(filp); \ + struct debugfs_fsdata *fsd; \ + ret_type r; \ + \ + r = debugfs_file_get(dentry); \ + if (unlikely(r)) \ + return r; \ + fsd = dentry->d_fsdata; \ + if (fsd->real_fops) \ + r = fsd->real_fops->name(args); \ + else \ + r = fsd->short_fops->name(args); \ + debugfs_file_put(dentry); \ + return r; \ +} -FULL_PROXY_FUNC(read, ssize_t, filp, - PROTO(struct file *filp, char __user *buf, size_t size, - loff_t *ppos), - ARGS(filp, buf, size, ppos)); +FULL_PROXY_FUNC_BOTH(llseek, loff_t, filp, + PROTO(struct file *filp, loff_t offset, int whence), + ARGS(filp, offset, whence)); -FULL_PROXY_FUNC(write, ssize_t, filp, - PROTO(struct file *filp, const char __user *buf, size_t size, - loff_t *ppos), - ARGS(filp, buf, size, ppos)); +FULL_PROXY_FUNC_BOTH(read, ssize_t, filp, + PROTO(struct file *filp, char __user *buf, size_t size, + loff_t *ppos), + ARGS(filp, buf, size, ppos)); + +FULL_PROXY_FUNC_BOTH(write, ssize_t, filp, + PROTO(struct file *filp, const char __user *buf, + size_t size, loff_t *ppos), + ARGS(filp, buf, size, ppos)); FULL_PROXY_FUNC(unlocked_ioctl, long, filp, PROTO(struct file *filp, unsigned int cmd, unsigned long arg), @@ -363,7 +391,7 @@ static int full_proxy_release(struct inode *inode, struct file *filp) * not to leak any resources. Releasers must not assume that * ->i_private is still being meaningful here. */ - if (real_fops->release) + if (real_fops && real_fops->release) r = real_fops->release(inode, filp); replace_fops(filp, d_inode(dentry)->i_fop); @@ -373,39 +401,48 @@ static int full_proxy_release(struct inode *inode, struct file *filp) } static void __full_proxy_fops_init(struct file_operations *proxy_fops, - const struct file_operations *real_fops) + struct debugfs_fsdata *fsd) { proxy_fops->release = full_proxy_release; - if (real_fops->llseek) + + if ((fsd->real_fops && fsd->real_fops->llseek) || + (fsd->short_fops && fsd->short_fops->llseek)) proxy_fops->llseek = full_proxy_llseek; - if (real_fops->read) + + if ((fsd->real_fops && fsd->real_fops->read) || + (fsd->short_fops && fsd->short_fops->read)) proxy_fops->read = full_proxy_read; - if (real_fops->write) + + if ((fsd->real_fops && fsd->real_fops->write) || + (fsd->short_fops && fsd->short_fops->write)) proxy_fops->write = full_proxy_write; - if (real_fops->poll) + + if (fsd->real_fops && fsd->real_fops->poll) proxy_fops->poll = full_proxy_poll; - if (real_fops->unlocked_ioctl) + + if (fsd->real_fops && fsd->real_fops->unlocked_ioctl) proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl; } static int full_proxy_open(struct inode *inode, struct file *filp) { struct dentry *dentry = F_DENTRY(filp); - const struct file_operations *real_fops = NULL; + const struct file_operations *real_fops; struct file_operations *proxy_fops = NULL; + struct debugfs_fsdata *fsd; int r; r = debugfs_file_get(dentry); if (r) return r == -EIO ? -ENOENT : r; - real_fops = debugfs_real_fops(filp); - + fsd = dentry->d_fsdata; + real_fops = fsd->real_fops; r = debugfs_locked_down(inode, filp, real_fops); if (r) goto out; - if (!fops_get(real_fops)) { + if (real_fops && !fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && real_fops->owner->state == MODULE_STATE_GOING) { @@ -426,11 +463,14 @@ static int full_proxy_open(struct inode *inode, struct file *filp) r = -ENOMEM; goto free_proxy; } - __full_proxy_fops_init(proxy_fops, real_fops); + __full_proxy_fops_init(proxy_fops, fsd); replace_fops(filp, proxy_fops); - if (real_fops->open) { - r = real_fops->open(inode, filp); + if (!real_fops || real_fops->open) { + if (real_fops) + r = real_fops->open(inode, filp); + else + r = simple_open(inode, filp); if (r) { replace_fops(filp, d_inode(dentry)->i_fop); goto free_proxy; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 66d9b3b4c588..38a9c7eb97e6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -412,7 +412,7 @@ static struct dentry *end_creating(struct dentry *dentry) static struct dentry *__debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *proxy_fops, - const struct file_operations *real_fops) + const void *real_fops) { struct dentry *dentry; struct inode *inode; @@ -450,49 +450,38 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, return end_creating(dentry); } -/** - * debugfs_create_file - create a file in the debugfs filesystem - * @name: a pointer to a string containing the name of the file to create. - * @mode: the permission that the file should have. - * @parent: a pointer to the parent dentry for this file. This should be a - * directory dentry if set. If this parameter is NULL, then the - * file will be created in the root of the debugfs filesystem. - * @data: a pointer to something that the caller will want to get to later - * on. The inode.i_private pointer will point to this value on - * the open() call. - * @fops: a pointer to a struct file_operations that should be used for - * this file. - * - * This is the basic "create a file" function for debugfs. It allows for a - * wide range of flexibility in creating a file, or a directory (if you want - * to create a directory, the debugfs_create_dir() function is - * recommended to be used instead.) - * - * This function will return a pointer to a dentry if it succeeds. This - * pointer must be passed to the debugfs_remove() function when the file is - * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be - * returned. - * - * If debugfs is not enabled in the kernel, the value -%ENODEV will be - * returned. - * - * NOTE: it's expected that most callers should _ignore_ the errors returned - * by this function. Other debugfs functions handle the fact that the "dentry" - * passed to them could be an error and they don't crash in that case. - * Drivers should generally work fine even if debugfs fails to init anyway. - */ -struct dentry *debugfs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops) +struct dentry *debugfs_create_file_full(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops) { + if (WARN_ON((unsigned long)fops & + (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT | + DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return ERR_PTR(-EINVAL); return __debugfs_create_file(name, mode, parent, data, fops ? &debugfs_full_proxy_file_operations : &debugfs_noop_file_operations, fops); } -EXPORT_SYMBOL_GPL(debugfs_create_file); +EXPORT_SYMBOL_GPL(debugfs_create_file_full); + +struct dentry *debugfs_create_file_short(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct debugfs_short_fops *fops) +{ + if (WARN_ON((unsigned long)fops & + (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT | + DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return ERR_PTR(-EINVAL); + + return __debugfs_create_file(name, mode, parent, data, + fops ? &debugfs_full_proxy_file_operations : + &debugfs_noop_file_operations, + (const void *)((unsigned long)fops | + DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT)); +} +EXPORT_SYMBOL_GPL(debugfs_create_file_short); /** * debugfs_create_file_unsafe - create a file in the debugfs filesystem diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index dae80c2a469e..a3edfa4f0d8e 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -18,6 +18,7 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; + const struct debugfs_short_fops *short_fops; union { /* automount_fn is used when real_fops is NULL */ debugfs_automount_t automount; @@ -39,6 +40,11 @@ struct debugfs_fsdata { * pointer gets its lowest bit set. */ #define DEBUGFS_FSDATA_IS_REAL_FOPS_BIT BIT(0) +/* + * A dentry's ->d_fsdata, when pointing to real fops, is with + * short fops instead of full fops. + */ +#define DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT BIT(1) /* Access BITS */ #define DEBUGFS_ALLOW_API BIT(0) diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 0928a6c8ae1e..59444b495d49 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -71,9 +71,63 @@ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); struct dentry *debugfs_lookup(const char *name, struct dentry *parent); -struct dentry *debugfs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops); +struct debugfs_short_fops { + ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); + loff_t (*llseek) (struct file *, loff_t, int); +}; + +struct dentry *debugfs_create_file_full(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops); +struct dentry *debugfs_create_file_short(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct debugfs_short_fops *fops); + +/** + * debugfs_create_file - create a file in the debugfs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the debugfs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fops: a pointer to a struct file_operations or struct debugfs_short_fops that + * should be used for this file. + * + * This is the basic "create a file" function for debugfs. It allows for a + * wide range of flexibility in creating a file, or a directory (if you want + * to create a directory, the debugfs_create_dir() function is + * recommended to be used instead.) + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the debugfs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be + * returned. + * + * If debugfs is not enabled in the kernel, the value -%ENODEV will be + * returned. + * + * If fops points to a struct debugfs_short_fops, then simple_open() will be + * used for the open, and only read/write/llseek are supported and are proxied, + * so no module reference or release are needed. + * + * NOTE: it's expected that most callers should _ignore_ the errors returned + * by this function. Other debugfs functions handle the fact that the "dentry" + * passed to them could be an error and they don't crash in that case. + * Drivers should generally work fine even if debugfs fails to init anyway. + */ +#define debugfs_create_file(name, mode, parent, data, fops) \ + _Generic(fops, \ + const struct file_operations *: debugfs_create_file_full, \ + const struct debugfs_short_fops *: debugfs_create_file_short, \ + struct file_operations *: debugfs_create_file_full, \ + struct debugfs_short_fops *: debugfs_create_file_short) \ + (name, mode, parent, data, fops) + struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); @@ -207,7 +261,7 @@ static inline struct dentry *debugfs_lookup(const char *name, static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, - const struct file_operations *fops) + const void *fops) { return ERR_PTR(-ENODEV); } From 31cb94f71c1ba126b9c684c5882cbf5032d0d1bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 Oct 2024 15:18:35 +0200 Subject: [PATCH 123/126] wifi: mac80211: convert debugfs files to short fops Given the large size of the regular struct file_operations, save a lot of space with the newly added short fops for debugfs. Link: https://patch.msgid.link/20241022151838.2f6de3ea3ecc.I45657e6a8415d796ec95c95becc9efb377ee3be6@changeid Signed-off-by: Johannes Berg --- net/mac80211/debugfs.c | 27 +++++++++------------------ net/mac80211/debugfs_key.c | 9 +++------ net/mac80211/debugfs_netdev.c | 3 +-- net/mac80211/debugfs_sta.c | 9 +++------ net/mac80211/rate.c | 3 +-- net/mac80211/rate.h | 2 +- 6 files changed, 18 insertions(+), 35 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index b777240c924e..be2e486907f9 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -42,9 +42,8 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ } #define DEBUGFS_READONLY_FILE_OPS(name) \ -static const struct file_operations name## _ops = { \ +static const struct debugfs_short_fops name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ }; @@ -142,10 +141,9 @@ static ssize_t aqm_write(struct file *file, return -EINVAL; } -static const struct file_operations aqm_ops = { +static const struct debugfs_short_fops aqm_ops = { .write = aqm_write, .read = aqm_read, - .open = simple_open, .llseek = default_llseek, }; @@ -194,10 +192,9 @@ static ssize_t airtime_flags_write(struct file *file, return count; } -static const struct file_operations airtime_flags_ops = { +static const struct debugfs_short_fops airtime_flags_ops = { .write = airtime_flags_write, .read = airtime_flags_read, - .open = simple_open, .llseek = default_llseek, }; @@ -225,9 +222,8 @@ static ssize_t aql_pending_read(struct file *file, buf, len); } -static const struct file_operations aql_pending_ops = { +static const struct debugfs_short_fops aql_pending_ops = { .read = aql_pending_read, - .open = simple_open, .llseek = default_llseek, }; @@ -305,10 +301,9 @@ static ssize_t aql_txq_limit_write(struct file *file, return count; } -static const struct file_operations aql_txq_limit_ops = { +static const struct debugfs_short_fops aql_txq_limit_ops = { .write = aql_txq_limit_write, .read = aql_txq_limit_read, - .open = simple_open, .llseek = default_llseek, }; @@ -355,10 +350,9 @@ static ssize_t aql_enable_write(struct file *file, const char __user *user_buf, return count; } -static const struct file_operations aql_enable_ops = { +static const struct debugfs_short_fops aql_enable_ops = { .write = aql_enable_write, .read = aql_enable_read, - .open = simple_open, .llseek = default_llseek, }; @@ -406,10 +400,9 @@ static ssize_t force_tx_status_write(struct file *file, return count; } -static const struct file_operations force_tx_status_ops = { +static const struct debugfs_short_fops force_tx_status_ops = { .write = force_tx_status_write, .read = force_tx_status_read, - .open = simple_open, .llseek = default_llseek, }; @@ -434,9 +427,8 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf, return count; } -static const struct file_operations reset_ops = { +static const struct debugfs_short_fops reset_ops = { .write = reset_write, - .open = simple_open, .llseek = noop_llseek, }; #endif @@ -624,9 +616,8 @@ static ssize_t stats_ ##name## _read(struct file *file, \ print_devstats_##name); \ } \ \ -static const struct file_operations stats_ ##name## _ops = { \ +static const struct debugfs_short_fops stats_ ##name## _ops = { \ .read = stats_ ##name## _read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ }; diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 7e54da508765..b3a64edea0f2 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -26,17 +26,15 @@ static ssize_t key_##name##_read(struct file *file, \ #define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n") #define KEY_OPS(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } #define KEY_OPS_W(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_##name##_read, \ .write = key_##name##_write, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -49,9 +47,8 @@ static const struct file_operations key_ ##name## _ops = { \ #define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n") #define KEY_CONF_OPS(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_conf_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 68596ef78b15..a9bc2fd59f55 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -221,10 +221,9 @@ static ssize_t ieee80211_if_fmt_##name( \ } #define _IEEE80211_IF_FILE_OPS(name, _read, _write) \ -static const struct file_operations name##_ops = { \ +static const struct debugfs_short_fops name##_ops = { \ .read = (_read), \ .write = (_write), \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 1e9389c49a57..a67a9d316008 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -30,17 +30,15 @@ static ssize_t sta_ ##name## _read(struct file *file, \ #define STA_READ_D(name, field) STA_READ(name, field, "%d\n") #define STA_OPS(name) \ -static const struct file_operations sta_ ##name## _ops = { \ +static const struct debugfs_short_fops sta_ ##name## _ops = { \ .read = sta_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } #define STA_OPS_RW(name) \ -static const struct file_operations sta_ ##name## _ops = { \ +static const struct debugfs_short_fops sta_ ##name## _ops = { \ .read = sta_##name##_read, \ .write = sta_##name##_write, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -450,9 +448,8 @@ STA_OPS_RW(agg_status); /* link sta attributes */ #define LINK_STA_OPS(name) \ -static const struct file_operations link_sta_ ##name## _ops = { \ +static const struct debugfs_short_fops link_sta_ ##name## _ops = { \ .read = link_sta_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 63fe58311a77..0d056db9f81e 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -249,9 +249,8 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf, ref->ops->name, len); } -const struct file_operations rcname_ops = { +const struct debugfs_short_fops rcname_ops = { .read = rcname_read, - .open = simple_open, .llseek = default_llseek, }; #endif diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 673aa9efe30b..5e4bde598212 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h @@ -62,7 +62,7 @@ static inline void rate_control_add_sta_debugfs(struct sta_info *sta) #endif } -extern const struct file_operations rcname_ops; +extern const struct debugfs_short_fops rcname_ops; static inline void rate_control_add_debugfs(struct ieee80211_local *local) { From 188a1bf894323bf3a90361676da8364c82ce6d32 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Tue, 1 Oct 2024 14:20:34 +0530 Subject: [PATCH 124/126] wifi: mac80211: re-order assigning channel in activate links The current flow in _ieee80211_set_active_links() does not align with the operational requirements of drivers that groups multiple hardware under a single wiphy. These drivers (e.g ath12k) rely on channel assignment to determine the appropriate hardware for each link. Without this, the drivers cannot correctly establish the link interface. Currently in _ieee80211_set_active_links(), after calling drv_change_vif_links() on the driver, the state of all connected stations is updated via drv_change_sta_links(). This is followed by handling keys in the links, and finally, assigning the channel to the links. Consequently, drv_change_sta_links() prompts drivers to create the station entry at their level and within their firmware. However, since channels have not yet been assigned to links at this stage, drivers have not created the necessary link interface for establishing link stations, leading to failures in activating the links. Therefore, re-order the logic so that after drv_change_vif_links() and removing the old links, channels are assigned to newly added links. Following this, the flow proceeds to station handling. Signed-off-by: Aditya Kumar Singh Link: https://patch.msgid.link/20241001085034.2745669-1-quic_adisi@quicinc.com [Johannes: fix iwlwifi to deal with the changes] Reviewed-by: Miriam Rachel Korenblit Signed-off-by: Johannes Berg --- .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 40 ++++++--------- .../net/wireless/intel/iwlwifi/mvm/mld-sta.c | 3 ++ net/mac80211/link.c | 51 +++++++++++-------- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 9aa08d289680..a5c38f389c69 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -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; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c index 28a9d90ad1cd..99eb1e1db1bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c @@ -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) { diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 503bdea904bc..e8def387d0f8 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -388,6 +388,37 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata, jiffies); } + for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { + struct ieee80211_link_data *link; + + link = sdata_dereference(sdata->link[link_id], sdata); + + /* + * This call really should not fail. Unfortunately, it appears + * that this may happen occasionally with some drivers. Should + * it happen, we are stuck in a bad place as going backwards is + * not really feasible. + * + * So lets just tell link_use_channel that it must not fail to + * assign the channel context (from mac80211's perspective) and + * assume the driver is going to trigger a recovery flow if it + * had a failure. + * That really is not great nor guaranteed to work. But at least + * the internal mac80211 state remains consistent and there is + * a chance that we can recover. + */ + ret = _ieee80211_link_use_channel(link, + &link->conf->chanreq, + IEEE80211_CHANCTX_SHARED, + true); + WARN_ON_ONCE(ret); + + /* + * inform about the link info changed parameters after all + * stations are also added + */ + } + list_for_each_entry(sta, &local->sta_list, list) { if (sdata != sta->sdata) continue; @@ -431,26 +462,6 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata, link = sdata_dereference(sdata->link[link_id], sdata); - /* - * This call really should not fail. Unfortunately, it appears - * that this may happen occasionally with some drivers. Should - * it happen, we are stuck in a bad place as going backwards is - * not really feasible. - * - * So lets just tell link_use_channel that it must not fail to - * assign the channel context (from mac80211's perspective) and - * assume the driver is going to trigger a recovery flow if it - * had a failure. - * That really is not great nor guaranteed to work. But at least - * the internal mac80211 state remains consistent and there is - * a chance that we can recover. - */ - ret = _ieee80211_link_use_channel(link, - &link->conf->chanreq, - IEEE80211_CHANCTX_SHARED, - true); - WARN_ON_ONCE(ret); - ieee80211_mgd_set_link_qos_params(link); ieee80211_link_info_change_notify(sdata, link, BSS_CHANGED_ERP_CTS_PROT | From cadae7ead4434d6c4ca15fb74cc729fb868fcca3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Oct 2024 15:18:34 +0000 Subject: [PATCH 125/126] wifi: iwlwifi: work around -Wenum-compare-conditional warning This is one of only three -Wenum-compare-conditional warnings we get in randconfig builds: drivers/net/wireless/intel/iwlwifi/mvm/sta.c:4331:17: error: conditional expression between different enumeration types ('enum iwl_fw_sta_type' and 'enum iwl_sta_type') [-Werror,-Wenum-compare-conditional] 4331 | u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK; | ^ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ This is a false positive since the code works as intended, but the warning is otherwise sensible, so slightly rewrite it in order to not trigger the warning. Signed-off-by: Arnd Bergmann Link: https://patch.msgid.link/20241018151841.3821671-1-arnd@kernel.org Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index b6c99cd6d9e5..9d05c344d967 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -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); From eaed5fc0c322d75cfcdbc7a16c0c5023d9e4f6fe Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 10 Oct 2024 13:40:36 -0700 Subject: [PATCH 126/126] mac80211: Remove NOP call to ieee80211_hw_config If changed is '0', then the ieee80211_hw_config takes no action, so just remove the call in __ieee809211_recalc_txpower() Signed-off-by: Ben Greear Link: https://patch.msgid.link/20241010204036.1219896-1-greearb@candelatech.com Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 57f6fac343eb..a8fbedd530f4 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -67,7 +67,6 @@ bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) if (power != link->conf->txpower) { link->conf->txpower = power; - ieee80211_hw_config(link->sdata->local, 0); return true; }