...
 
Commits (37)
variables:
DEPS: >
build-essential gcc-aarch64-linux-gnu make device-tree-compiler
bison flex bc libssl-dev
before_script:
- export DEBIAN_FRONTEND=noninteractive
- apt-get -y update
- apt-get -y install $DEPS
.tags: &tags
tags:
- librem5
build:aarch64:
<<: *tags
stage: build
variables:
CROSS_BUILD: "ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-"
script:
- cp arch/arm64/configs/librem5-devkit_defconfig .config
- make ${CROSS_BUILD} olddefconfig
- make -j 4 ${CROSS_BUILD} Image dtbs modules
- make -j 4 ${CROSS_BUILD} INSTALL_MOD_PATH=modules/ modules_install
artifacts:
paths:
- arch/arm64/boot/Image
- arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
- modules/
expire_in: 1 week
......@@ -23,6 +23,20 @@ Required properties:
Optional properties:
- clock-output-names : Should contain name for output clock.
- rohm,reset-snvs-powered : Transfer BD718x7 to SNVS state at reset.
The BD718x7 supports two different HW states as reset target states. States
are called as SNVS and READY. At READY state all the PMIC power outputs go
down and OTP is reload. At the SNVS state all other logic and external
devices apart from the SNVS power domain are shut off. Please refer to NXP
i.MX8 documentation for further information regarding SNVS state. When a
reset is done via SNVS state the PMIC OTP data is not reload. This causes
power outputs that have been under SW control to stay down when reset has
switched power state to SNVS. If reset is done via READY state the power
outputs will be returned to HW control by OTP loading. Thus the reset
target state is set to READY by default. If SNVS state is used the boot
crucial regulators must have the regulator-always-on and regulator-boot-on
properties set in regulator node.
Example:
......@@ -43,6 +57,7 @@ Example:
#clock-cells = <0>;
clocks = <&osc 0>;
clock-output-names = "bd71837-32k-out";
rohm,reset-snvs-powered;
regulators {
buck1: BUCK1 {
......@@ -50,8 +65,10 @@ Example:
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <1250>;
};
// [...]
};
};
......
......@@ -27,8 +27,38 @@ BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6
Optional properties:
- rohm,dvs-run-voltage : PMIC default "RUN" state voltage in uV.
See below table for bucks which support this.
- rohm,dvs-idle-voltage : PMIC default "IDLE" state voltage in uV.
See below table for bucks which support this.
- rohm,dvs-suspend-voltage : PMIC default "SUSPEND" state voltage in uV.
See below table for bucks which support this.
- Any optional property defined in bindings/regulator/regulator.txt
Supported default DVS states:
BD71837:
buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage
-----------------------------------------------------------------------------
1 | supported | supported | supported
----------------------------------------------------------------------------
2 | supported | supported | not supported
----------------------------------------------------------------------------
3 | supported | not supported | not supported
----------------------------------------------------------------------------
4 | supported | not supported | not supported
----------------------------------------------------------------------------
rest | not supported | not supported | not supported
BD71847:
buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage
-----------------------------------------------------------------------------
1 | supported | supported | supported
----------------------------------------------------------------------------
2 | supported | supported | not supported
----------------------------------------------------------------------------
rest | not supported | not supported | not supported
Example:
regulators {
buck1: BUCK1 {
......@@ -36,7 +66,11 @@ regulators {
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <1250>;
rohm,dvs-run-voltage = <900000>;
rohm,dvs-idle-voltage = <850000>;
rohm,dvs-suspend-voltage = <800000>;
};
buck2: BUCK2 {
regulator-name = "buck2";
......@@ -45,18 +79,22 @@ regulators {
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <1250>;
rohm,dvs-run-voltage = <1000000>;
rohm,dvs-idle-voltage = <900000>;
};
buck3: BUCK3 {
regulator-name = "buck3";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-boot-on;
rohm,dvs-run-voltage = <1000000>;
};
buck4: BUCK4 {
regulator-name = "buck4";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-boot-on;
rohm,dvs-run-voltage = <1000000>;
};
buck5: BUCK5 {
regulator-name = "buck5";
......
......@@ -20,3 +20,4 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include <dt-bindings/clock/imx8mq-clock.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/thermal.h>
#include "imx8mq-pinfunc.h"
/ {
......@@ -84,32 +85,45 @@
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0>;
clock-latency = <61036>; /* two CLK32 periods */
clocks = <&clk IMX8MQ_CLK_ARM>;
enable-method = "psci";
next-level-cache = <&A53_L2>;
operating-points-v2 = <&a53_0_opp_table>;
#cooling-cells = <2>;
};
A53_1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x1>;
clock-latency = <61036>; /* two CLK32 periods */
clocks = <&clk IMX8MQ_CLK_ARM>;
enable-method = "psci";
next-level-cache = <&A53_L2>;
operating-points-v2 = <&a53_0_opp_table>;
};
A53_2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x2>;
clock-latency = <61036>; /* two CLK32 periods */
clocks = <&clk IMX8MQ_CLK_ARM>;
enable-method = "psci";
next-level-cache = <&A53_L2>;
operating-points-v2 = <&a53_0_opp_table>;
};
A53_3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x3>;
clock-latency = <61036>; /* two CLK32 periods */
clocks = <&clk IMX8MQ_CLK_ARM>;
enable-method = "psci";
next-level-cache = <&A53_L2>;
operating-points-v2 = <&a53_0_opp_table>;
};
A53_L2: l2-cache0 {
......@@ -199,6 +213,88 @@
#interrupt-cells = <2>;
};
tmu: tmu@30260000 {
compatible = "fsl,imx8mq-tmu";
reg = <0x30260000 0x10000>;
interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
little-endian;
fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
fsl,tmu-calibration = <0x00000000 0x00000023
0x00000001 0x00000029
0x00000002 0x0000002f
0x00000003 0x00000035
0x00000004 0x0000003d
0x00000005 0x00000043
0x00000006 0x0000004b
0x00000007 0x00000051
0x00000008 0x00000057
0x00000009 0x0000005f
0x0000000a 0x00000067
0x0000000b 0x0000006f
0x00010000 0x0000001b
0x00010001 0x00000023
0x00010002 0x0000002b
0x00010003 0x00000033
0x00010004 0x0000003b
0x00010005 0x00000043
0x00010006 0x0000004b
0x00010007 0x00000055
0x00010008 0x0000005d
0x00010009 0x00000067
0x0001000a 0x00000070
0x00020000 0x00000017
0x00020001 0x00000023
0x00020002 0x0000002d
0x00020003 0x00000037
0x00020004 0x00000041
0x00020005 0x0000004b
0x00020006 0x00000057
0x00020007 0x00000063
0x00020008 0x0000006f
0x00030000 0x00000015
0x00030001 0x00000021
0x00030002 0x0000002d
0x00030003 0x00000039
0x00030004 0x00000045
0x00030005 0x00000053
0x00030006 0x0000005f
0x00030007 0x00000071>;
#thermal-sensor-cells = <0>;
};
thermal-zones {
cpu-thermal {
polling-delay-passive = <250>;
polling-delay = <2000>;
thermal-sensors = <&tmu>;
trips {
cpu_alert0: trip0 {
temperature = <85000>;
hysteresis = <2000>;
type = "passive";
};
cpu_crit0: trip1 {
temperature = <95000>;
hysteresis = <2000>;
type = "critical";
};
};
cooling-maps {
map0 {
trip = <&cpu_alert0>;
cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
iomuxc: iomuxc@30330000 {
compatible = "fsl,imx8mq-iomuxc";
reg = <0x30330000 0x10000>;
......@@ -400,17 +496,127 @@
};
};
a53_0_opp_table: opp-table {
compatible = "operating-points-v2";
opp-shared;
opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <900000>;
clock-latency-ns = <150000>;
};
opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1000000>;
clock-latency-ns = <150000>;
opp-suspend;
};
};
gic: interrupt-controller@38800000 {
compatible = "arm,gic-v3";
reg = <0x38800000 0x10000>, /* GIC Dist */
<0x38880000 0xc0000>, /* GICR */
<0x31000000 0x2000>, /* GICC */
<0x31010000 0x2000>, /* GICV */
<0x31020000 0x2000>; /* GICH */
<0x31020000 0x2000>, /* GICH */
<0x30340000 0x10000>; /* IOMUXC_GPR */
#interrupt-cells = <3>;
interrupt-controller;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
};
};
usb3_phy0: phy0@381f0040 {
compatible = "fsl,imx8mq-usb-phy";
#phy-cells = <1>;
reg = <0x0 0x381f0040 0x0 0x40>;
clocks = <&clk IMX8MQ_CLK_USB1_PHY_ROOT>;
clock-names = "phy";
assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>;
assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>;
assigned-clock-rates = <100000000>;
status = "disabled";
};
usb3_0: usb0@38100000 {
compatible = "fsl,imx8mq-dwc3";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x38100000 0x0 0x38100000 0x0 0x10000>;
clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>;
clock-names = "usb1_ctrl_root_clk";
assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
<&clk IMX8MQ_CLK_USB_CORE_REF>;
assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>,
<&clk IMX8MQ_SYS1_PLL_100M>;
assigned-clock-rates = <500000000>, <100000000>;
status = "disabled";
usb_dwc3_0: dwc3 {
compatible = "snps,dwc3";
reg = <0x0 0x38100000 0x0 0x10000>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
/* TODO: check these clock assignments */
clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>,
<&clk IMX8MQ_CLK_USB_BUS>,
<&clk IMX8MQ_CLK_USB_CORE_REF>;
clock-names = "ref", "bus_early", "suspend";
phys = <&usb3_phy0 0>, <&usb3_phy0 1>;
phy-names = "usb2-phy", "usb3-phy";
snps,power-down-scale = <2>;
usb3-resume-missing-cas;
usb3-lpm-capable;
status = "disabled";
};
};
usb3_phy1: phy1@382f0040 {
compatible = "fsl,imx8mq-usb-phy";
#phy-cells = <1>;
reg = <0x0 0x382f0040 0x0 0x40>;
clocks = <&clk IMX8MQ_CLK_USB2_PHY_ROOT>;
clock-names = "phy";
assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>;
assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>;
assigned-clock-rates = <100000000>;
status = "disabled";
};
usb3_1: usb1@38200000 {
compatible = "fsl,imx8mq-dwc3";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x38200000 0x0 0x38200000 0x0 0x10000>;
clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>;
clock-names = "usb2_ctrl_root_clk";
assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
<&clk IMX8MQ_CLK_USB_CORE_REF>;
assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>,
<&clk IMX8MQ_SYS1_PLL_100M>;
assigned-clock-rates = <500000000>, <100000000>;
status = "disabled";
usb_dwc3_1: dwc3 {
compatible = "snps,dwc3";
reg = <0x0 0x38200000 0x0 0x10000>;
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
/* TODO: check these clock assignments */
clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>,
<&clk IMX8MQ_CLK_USB_BUS>,
<&clk IMX8MQ_CLK_USB_CORE_REF>;
clock-names = "ref", "bus_early", "suspend";
phys = <&usb3_phy1 0>, <&usb3_phy1 1>;
phy-names = "usb2-phy", "usb3-phy";
snps,power-down-scale = <2>;
usb3-resume-missing-cas;
usb3-lpm-capable;
status = "disabled";
};
};
};
This diff is collapsed.
This diff is collapsed.
......@@ -340,7 +340,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
clks[IMX8MQ_DRAM_PLL2_DIV] = imx_clk_divider("dram_pll2_div", "dram_pll2", base + 0x68, 1, 6);
/* PLL bypass out */
clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels));
clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
......@@ -558,6 +558,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
clks[IMX8MQ_CLK_A53_DIV],
clks[IMX8MQ_CLK_A53_SRC],
clks[IMX8MQ_ARM_PLL_OUT],
clks[IMX8MQ_SYS1_PLL_800M]);
for (i = 0; i < IMX8MQ_CLK_END; i++)
if (IS_ERR(clks[i]))
pr_err("i.MX8mq clk %u register failed with %ld\n",
......
......@@ -66,6 +66,8 @@ struct gic_chip_data {
static struct gic_chip_data gic_data __read_mostly;
static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
static void __iomem *iomuxc_gpr_base;
static struct gic_kvm_info gic_v3_kvm_info;
static DEFINE_PER_CPU(bool, has_rss);
......@@ -746,6 +748,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq)
static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
int cpu;
u32 val;
if (WARN_ON(irq >= 16))
return;
......@@ -762,8 +765,18 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
tlist = gic_compute_target_list(&cpu, mask, cluster_id);
gic_send_sgi(cluster_id, tlist, irq);
}
if (iomuxc_gpr_base) {
/* pending the IRQ32 to wakeup the core */
val = readl_relaxed(iomuxc_gpr_base + 0x4);
val |= (1 << 12);
writel_relaxed(val, iomuxc_gpr_base + 0x4);
/* delay for a while to make sure cores wakeup done */
udelay(50);
val &= ~(1 << 12);
writel_relaxed(val, iomuxc_gpr_base + 0x4);
}
}
/* Force the above writes to ICC_SGI1R_EL1 to be executed */
isb();
}
......@@ -1340,6 +1353,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
rdist_regs[i].phys_base = res.start;
}
/* sw workaround for IPI can't wakeup CORE ERRATA(ERR011171) on i.MX8MQ */
iomuxc_gpr_base = of_iomap(node, 5);
if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
redist_stride = 0;
......
......@@ -5,15 +5,14 @@ config WLAN_VENDOR_RSI
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all the
questions about these cards. If you say Y, you will be asked for
kernel: saying N will just cause the configurator to skip all
the questions about cards. If you say Y, you will be asked for
your specific card in the following questions.
if WLAN_VENDOR_RSI
config RSI_91X
tristate "Redpine Signals Inc 91x WLAN driver support"
select BT_HCIRSI if RSI_COEX
depends on MAC80211
---help---
This option enabes support for RSI 1x1 devices.
......@@ -25,7 +24,7 @@ config RSI_DEBUGFS
default y
---help---
Say Y, if you would like to enable debug support. This option
creates debugfs entries
creates debugfs entries.
config RSI_SDIO
tristate "Redpine Signals SDIO bus support"
......@@ -43,14 +42,68 @@ config RSI_USB
This option enables the USB bus support in rsi drivers.
Select M (recommended), if you have a RSI 1x1 wireless module.
config RSI_COEX
bool "Redpine Signals WLAN BT Coexistence support"
depends on BT && RSI_91X
depends on !(BT=m && RSI_91X=y)
default y
config RSI_BT_ALONE
bool "Redpine Signals BT alone (classic/LE) mode support"
depends on RSI_91X
default n
---help---
This option enables the BT classic alone upport in rsi drivers.
Say Y, if you want to use this feature.
config RSI_COEX_MODE
bool "Redpine Signals Wi-Fi BT Coex support"
depends on RSI_91X
default n
---help---
This option enables the Wi-Fi BT coex support in rsi drivers.
Select Y, if you have to use this feature.
config RSI_WOW
bool "Redpine Signals WoWLAN support"
depends on RSI_91X
default n
---help---
This option enables the WoWLAN support.
Say Y if you want to use this feature.
config RSI_P2P
bool "Redpine Signals Wi-Fi Direct support"
depends on RSI_91X
default n
---help---
This option enables the Wi-Fi Direct support in rsi drivers.
Select Y, if you have to use this feature.
config HW_SCAN_OFFLOAD
bool "Redpine Signals Hardware scan offload feature"
depends on RSI_91X
default n
---help---
This option enables the hardware scan offload option in rsi drivers.
Select Y, if you have to use this feature.
config CARACALLA_BOARD
bool "Redpine device support on Caracalla board"
depends on RSI_91X
default n
---help---
This option is used to support Caracalla board with RSI driver.
Select Y, if you have to use this support.
config RSI_ZIGB
bool "Redpine device support on Zigbee"
depends on RSI_91X && RSI_COEX_MODE
default n
---help---
This option is used to support Zigbee with RSI driver.
Select Y, if you have to use this support.
config RSI_PURISM
bool "Redpine Signals PURISM FW support"
depends on RSI_91X && RSI_COEX_MODE
default n
---help---
This option enables the WLAN BT coex support in rsi drivers.
Select M (recommended), if you have want to use this feature
and you have RS9113 module.
This option enables the PURISM FW support.
Say Y if you want to use this feature.
endif # WLAN_VENDOR_RSI
# SPDX-License-Identifier: GPL-2.0
#/*
# Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#*/
rsi_91x-y += rsi_91x_main.o
rsi_91x-y += rsi_91x_core.o
rsi_91x-y += rsi_91x_mac80211.o
rsi_91x-y += rsi_91x_mgmt.o
rsi_91x-y += rsi_91x_hal.o
rsi_91x-y += rsi_91x_ps.o
rsi_91x-$(CONFIG_RSI_COEX) += rsi_91x_coex.o
rsi_91x-$(CONFIG_RSI_DEBUGFS) += rsi_91x_debugfs.o
rsi_91x-$(CONFIG_RSI_BT_ALONE) += rsi_91x_hci.o
rsi_91x-$(CONFIG_RSI_COEX_MODE) += rsi_91x_coex.o
rsi_91x-$(CONFIG_RSI_COEX_MODE) += rsi_91x_hci.o
rsi_91x-$(CONFIG_RSI_ZIGB) += rsi_91x_zigb.o
rsi_91x-$(CONFIG_RSI_11K) += rsi_91x_rrm.o
rsi_usb-y += rsi_91x_usb.o rsi_91x_usb_ops.o
rsi_sdio-y += rsi_91x_sdio.o rsi_91x_sdio_ops.o
rsi_usb-$(CONFIG_RSI_USB) += rsi_91x_usb.o rsi_91x_usb_ops.o
rsi_sdio-$(CONFIG_RSI_SDIO) += rsi_91x_sdio.o rsi_91x_sdio_ops.o
obj-$(CONFIG_RSI_91X) += rsi_91x.o
obj-$(CONFIG_RSI_SDIO) += rsi_sdio.o
obj-$(CONFIG_RSI_USB) += rsi_usb.o
/**
* Copyright (c) 2018 Redpine Signals Inc.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "rsi_main.h"
#include "rsi_coex.h"
#include "rsi_mgmt.h"
#include "rsi_hal.h"
#include "rsi_mgmt.h"
static enum rsi_coex_queues rsi_coex_determine_coex_q
(struct rsi_coex_ctrl_block *coex_cb)
static u8 rsi_coex_determine_coex_q(struct rsi_coex_ctrl_block *coex_cb)
{
enum rsi_coex_queues q_num = RSI_COEX_Q_INVALID;
if (skb_queue_len(&coex_cb->coex_tx_qs[RSI_COEX_Q_COMMON]) > 0)
q_num = RSI_COEX_Q_COMMON;
if (skb_queue_len(&coex_cb->coex_tx_qs[RSI_COEX_Q_BT]) > 0)
q_num = RSI_COEX_Q_BT;
if (skb_queue_len(&coex_cb->coex_tx_qs[RSI_COEX_Q_WLAN]) > 0)
q_num = RSI_COEX_Q_WLAN;
u8 q_num = INVALID_QUEUE;
if (skb_queue_len(&coex_cb->coex_tx_qs[VIP_Q]) > 0)
q_num = VIP_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[COEX_Q]) > 0)
q_num = COEX_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[BT_Q]) > 0)
q_num = BT_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[ZIGB_Q]) > 0)
q_num = ZIGB_Q;
if (skb_queue_len(&coex_cb->coex_tx_qs[WLAN_Q]) > 0)
q_num = WLAN_Q;
return q_num;
}
static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
{
enum rsi_coex_queues coex_q = RSI_COEX_Q_INVALID;
u8 coex_q;
struct sk_buff *skb;
do {
#ifdef CONFIG_RSI_ZIGB
struct rsi_common *common = coex_cb->priv;
#endif
while (1) {
coex_q = rsi_coex_determine_coex_q(coex_cb);
rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q);
if (coex_q == RSI_COEX_Q_BT) {
skb = skb_dequeue(&coex_cb->coex_tx_qs[RSI_COEX_Q_BT]);
rsi_send_bt_pkt(coex_cb->priv, skb);
if (coex_q == INVALID_QUEUE) {
rsi_dbg(DATA_TX_ZONE, "No more pkt\n");
break;
}
if ((coex_q == BT_Q) || (coex_q == ZIGB_Q)) {
skb = skb_dequeue(&coex_cb->coex_tx_qs[BT_Q]);
#ifdef CONFIG_RSI_ZIGB
if (common->zb_fsm_state == ZB_DEVICE_READY) {
rsi_dbg(DATA_TX_ZONE, "Sending zigbee pkt\n");
rsi_send_zb_pkt(coex_cb->priv, skb);
} else {
#endif
rsi_dbg(DATA_TX_ZONE, "Sending BT pkt\n");
rsi_send_bt_pkt(coex_cb->priv, skb);
#ifdef CONFIG_RSI_ZIGB
}
#endif
}
} while (coex_q != RSI_COEX_Q_INVALID);
}
}
/**
* rsi_coex_scheduler_thread() - This function is a kernel thread to schedule
* the coex packets to device
* @common: Pointer to the driver private structure.
*
* Return: None.
*/
static void rsi_coex_scheduler_thread(struct rsi_common *common)
{
int status = 0;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
u32 timeout = EVENT_WAIT_FOREVER;
do {
rsi_wait_event(&coex_cb->coex_tx_thread.event, timeout);
status = rsi_wait_event(&coex_cb->coex_tx_thread.event, timeout);
if (status < 0)
break;
rsi_reset_event(&coex_cb->coex_tx_thread.event);
rsi_coex_sched_tx_pkts(coex_cb);
......@@ -68,59 +113,38 @@ static void rsi_coex_scheduler_thread(struct rsi_common *common)
int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg)
{
u8 msg_type = msg[RSI_RX_DESC_MSG_TYPE_OFFSET];
u16 msg_type = msg[2];
switch (msg_type) {
case COMMON_CARD_READY_IND:
rsi_dbg(INFO_ZONE, "common card ready received\n");
if (msg_type == COMMON_CARD_READY_IND) {
common->hibernate_resume = false;
rsi_dbg(INFO_ZONE, "COMMON CARD READY RECEIVED\n");
rsi_handle_card_ready(common, msg);
break;
case SLEEP_NOTIFY_IND:
rsi_dbg(INFO_ZONE, "sleep notify received\n");
} else if (msg_type == SLEEP_NOTIFY_IND) {
rsi_dbg(INFO_ZONE, "\n\n sleep notify RECEIVED\n");
rsi_mgmt_pkt_recv(common, msg);
break;
}
return 0;
}
static inline int rsi_map_coex_q(u8 hal_queue)
{
switch (hal_queue) {
case RSI_COEX_Q:
return RSI_COEX_Q_COMMON;
case RSI_WLAN_Q:
return RSI_COEX_Q_WLAN;
case RSI_BT_Q:
return RSI_COEX_Q_BT;
}
return RSI_COEX_Q_INVALID;
}
int rsi_coex_send_pkt(void *priv, struct sk_buff *skb, u8 hal_queue)
int rsi_coex_send_pkt(void *priv,
struct sk_buff *skb,
u8 hal_queue)
{
struct rsi_common *common = (struct rsi_common *)priv;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
struct skb_info *tx_params = NULL;
enum rsi_coex_queues coex_q;
int status;
int status = 0;
coex_q = rsi_map_coex_q(hal_queue);
if (coex_q == RSI_COEX_Q_INVALID) {
rsi_dbg(ERR_ZONE, "Invalid coex queue\n");
return -EINVAL;
}
if (coex_q != RSI_COEX_Q_COMMON &&
coex_q != RSI_COEX_Q_WLAN) {
skb_queue_tail(&coex_cb->coex_tx_qs[coex_q], skb);
/* Add pkt to queue if not WLAN packet */
if (hal_queue != RSI_WLAN_Q) {
skb_queue_tail(&coex_cb->coex_tx_qs[hal_queue], skb);
rsi_set_event(&coex_cb->coex_tx_thread.event);
return 0;
return status;
}
if (common->iface_down) {
tx_params =
(struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
if (!(tx_params->flags & INTERNAL_MGMT_PKT)) {
rsi_indicate_tx_status(common->priv, skb, -EINVAL);
......@@ -134,12 +158,12 @@ int rsi_coex_send_pkt(void *priv, struct sk_buff *skb, u8 hal_queue)
else
status = rsi_send_data_pkt(common, skb);
return status;
return 0;
}
int rsi_coex_attach(struct rsi_common *common)
int rsi_coex_init(struct rsi_common *common)
{
struct rsi_coex_ctrl_block *coex_cb;
struct rsi_coex_ctrl_block *coex_cb = NULL;
int cnt;
coex_cb = kzalloc(sizeof(*coex_cb), GFP_KERNEL);
......@@ -148,6 +172,7 @@ int rsi_coex_attach(struct rsi_common *common)
common->coex_cb = (void *)coex_cb;
coex_cb->priv = common;
sema_init(&coex_cb->tx_bus_lock, 1);
/* Initialize co-ex queues */
for (cnt = 0; cnt < NUM_COEX_TX_QUEUES; cnt++)
......@@ -160,21 +185,28 @@ int rsi_coex_attach(struct rsi_common *common)
rsi_coex_scheduler_thread,
"Coex-Tx-Thread")) {
rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
return -EINVAL;
goto err;
}
return 0;
err:
return -EINVAL;
}
void rsi_coex_detach(struct rsi_common *common)
void rsi_coex_deinit(struct rsi_common *common)
{
int cnt;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
int cnt;
/* Stop the coex tx thread */
rsi_kill_thread(&coex_cb->coex_tx_thread);
/* Empty the coex queue */
for (cnt = 0; cnt < NUM_COEX_TX_QUEUES; cnt++)
skb_queue_purge(&coex_cb->coex_tx_qs[cnt]);
/* Free the coex control block */
kfree(coex_cb);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (c) 2014 Redpine Signals Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/etherdevice.h>
......@@ -22,6 +36,13 @@
#include "rsi_common.h"
#include "rsi_ps.h"
/**
* str_psstate() - return the ps state in string format.
*
* @state - PS state.
*
* return: PS state in string format.
*/
char *str_psstate(enum ps_state state)
{
switch (state) {
......@@ -36,8 +57,17 @@ char *str_psstate(enum ps_state state)
default:
return "INVALID_STATE";
}
return "INVALID_STATE";
}
/**
* rsi_modify_ps_state() - Modify PS state to a new state.
*
* @adapter: pointer to rsi_hw structure.
* @nstate: new PS state.
*
* return: new state.
*/
static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
enum ps_state nstate)
{
......@@ -48,34 +78,42 @@ static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
adapter->ps_state = nstate;
}
/**
* rsi_default_ps_params() - Initalization of default powersave parameters.
*
* @adapter: pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_default_ps_params(struct rsi_hw *adapter)
{
struct rsi_ps_info *ps_info = &adapter->ps_info;
ps_info->enabled = true;
ps_info->sleep_type = RSI_SLEEP_TYPE_LP;
ps_info->sleep_type = 1; /* LP */
ps_info->tx_threshold = 0;
ps_info->rx_threshold = 0;
ps_info->tx_hysterisis = 0;
ps_info->rx_hysterisis = 0;
ps_info->monitor_interval = 0;
ps_info->listen_interval = RSI_DEF_LISTEN_INTERVAL;
ps_info->listen_interval = 2 * 100;
ps_info->num_bcns_per_lis_int = 0;
ps_info->dtim_interval_duration = 0;
ps_info->num_dtims_per_sleep = 0;
ps_info->deep_sleep_wakeup_period = RSI_DEF_DS_WAKEUP_PERIOD;
ps_info->deep_sleep_wakeup_period = 0;
}
EXPORT_SYMBOL_GPL(rsi_default_ps_params);
void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
/**
* rsi_enable_ps() - enable power save
*
* @adapter: Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_enable_ps(struct rsi_hw *adapter)
{
if (adapter->ps_state != PS_NONE) {
rsi_dbg(ERR_ZONE,
"%s: Cannot accept enable PS in %s state\n",
__func__, str_psstate(adapter->ps_state));
return;
}
if (rsi_send_ps_request(adapter, true, vif)) {
if (rsi_send_ps_request(adapter, true)) {
rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
......@@ -85,17 +123,16 @@ void rsi_enable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
rsi_modify_ps_state(adapter, PS_ENABLE_REQ_SENT);
}
/* This function is used to disable power save */
void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
/**
* rsi_disable_ps() - disable power save
*
* @adapter: Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_disable_ps(struct rsi_hw *adapter)
{
if (adapter->ps_state != PS_ENABLED) {
rsi_dbg(ERR_ZONE,
"%s: Cannot accept disable PS in %s state\n",
__func__, str_psstate(adapter->ps_state));
return;
}
if (rsi_send_ps_request(adapter, false, vif)) {
if (rsi_send_ps_request(adapter, false)) {
rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
......@@ -105,32 +142,52 @@ void rsi_disable_ps(struct rsi_hw *adapter, struct ieee80211_vif *vif)
rsi_modify_ps_state(adapter, PS_DISABLE_REQ_SENT);
}
void rsi_conf_uapsd(struct rsi_hw *adapter, struct ieee80211_vif *vif)
/**
* rsi_conf_uapsd() - configures UAPSD powersave.
*
* @adapter - Pointer to rsi_hw structure.
*
* return: void.
*/
void rsi_conf_uapsd(struct rsi_hw *adapter)
{
int ret;
if (adapter->ps_state != PS_ENABLED)
return;
ret = rsi_send_ps_request(adapter, false, vif);
if (!ret)
ret = rsi_send_ps_request(adapter, true, vif);
if (ret)
if (rsi_send_ps_request(adapter, false)) {
rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
}
if (rsi_send_ps_request(adapter, true)) {
rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
}
}
/**
* rsi_handle_ps_confirm() - Processes powersave confirmation.
*
* @adapter - Pointer to rsi_hw structure.
* @msg - Recevied buffer.
*
* return: 0 on success.
*/
int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
{
u16 cfm_type = get_unaligned_le16(msg + PS_CONFIRM_INDEX);
u16 cfm_type = 0;
cfm_type = *(u16 *)&msg[PS_CONFIRM_INDEX];
switch (cfm_type) {
case RSI_SLEEP_REQUEST:
case SLEEP_REQUEST:
if (adapter->ps_state == PS_ENABLE_REQ_SENT)
rsi_modify_ps_state(adapter, PS_ENABLED);
break;
case RSI_WAKEUP_REQUEST:
case WAKEUP_REQUEST:
if (adapter->ps_state == PS_DISABLE_REQ_SENT)
rsi_modify_ps_state(adapter, PS_NONE);
break;
......@@ -143,4 +200,3 @@ int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (c) 2014 Redpine Signals Inc.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/firmware.h>
......@@ -29,33 +42,37 @@ void rsi_usb_rx_thread(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
int status;
struct sk_buff *skb;
int status, idx;
do {
rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER);
status = rsi_wait_event(&dev->rx_thread.event,
EVENT_WAIT_FOREVER);
if (status < 0)
break;
rsi_reset_event(&dev->rx_thread.event);
while (true) {
if (atomic_read(&dev->rx_thread.thread_done))
goto out;
skb = skb_dequeue(&dev->rx_q);
if (!skb)
break;
status = rsi_read_pkt(common, skb->data, 0);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed To read data",
__func__);
break;
if (atomic_read(&dev->rx_thread.thread_done))
break;
for (idx = 0; idx < MAX_RX_URBS; idx++) {
while (true) {
skb = skb_dequeue(&dev->rx_q[idx]);
if (!skb)
break;
status = rsi_read_pkt(common, skb->data, 0);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed To read data",
__func__);
}
dev_kfree_skb(skb);
}
dev_kfree_skb(skb);
}
} while (1);
out:
rsi_dbg(INFO_ZONE, "%s: Terminated thread\n", __func__);
skb_queue_purge(&dev->rx_q);
rsi_dbg(INFO_ZONE, "%s: Terminated USB RX thread\n", __func__);
atomic_inc(&dev->rx_thread.thread_done);
complete_and_exit(&dev->rx_thread.completion, 0);
}
This diff is collapsed.
This diff is collapsed.
/**
* Copyright (c) 2018 Redpine Signals Inc.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RSI_COEX_H__
......@@ -19,19 +33,35 @@
#include "rsi_common.h"
#ifdef CONFIG_RSI_COEX
#define RSI_COEX_TXQ_MAX_PKTS 64
#define RSI_COEX_TXQ_WATER_MARK 50
#define COMMON_CARD_READY_IND 0
#define NUM_COEX_TX_QUEUES 5
#define COEX_Q 0
#define BT_Q 1
#define WLAN_Q 2
#define VIP_Q 3
#define ZIGB_Q 4
#define NUM_COEX_TX_QUEUES 5
#include "rsi_main.h"
enum rsi_proto {
RSI_PROTO_WLAN = 0,
RSI_PROTO_BT
};
struct rsi_coex_ctrl_block {
struct rsi_common *priv;
struct sk_buff_head coex_tx_qs[NUM_COEX_TX_QUEUES];
struct semaphore tx_bus_lock;
struct rsi_thread coex_tx_thread;
};
int rsi_coex_attach(struct rsi_common *common);
void rsi_coex_detach(struct rsi_common *common);
int rsi_coex_send_pkt(void *priv, struct sk_buff *skb, u8 proto_type);
int rsi_coex_init(struct rsi_common *common);
int rsi_coex_send_pkt(void *priv,
struct sk_buff *skb,
u8 proto_type);
int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg);
#endif
void rsi_coex_deinit(struct rsi_common *common);
#endif
/**
* Copyright (c) 2014 Redpine Signals Inc.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RSI_COMMON_H__
#define __RSI_COMMON_H__
#include <linux/kthread.h>
#include "rsi_hci.h"
#define EVENT_WAIT_FOREVER 0
#define FIRMWARE_RSI9113 "rs9113_wlan_qspi.rps"
#define QUEUE_NOT_FULL 1
#define QUEUE_FULL 0
......@@ -37,10 +51,10 @@ static inline int rsi_wait_event(struct rsi_event *event, u32 timeout)
if (!timeout)
status = wait_event_interruptible(event->event_queue,
(atomic_read(&event->event_condition) == 0));
(!atomic_read(&event->event_condition)));
else
status = wait_event_interruptible_timeout(event->event_queue,
(atomic_read(&event->event_condition) == 0),
(!atomic_read(&event->event_condition)),
timeout);
return status;
}
......@@ -72,21 +86,53 @@ static inline int rsi_create_kthread(struct rsi_common *common,
static inline int rsi_kill_thread(struct rsi_thread *handle)
{
if (atomic_read(&handle->thread_done) > 0)
return 0;
atomic_inc(&handle->thread_done);
rsi_set_event(&handle->event);
return kthread_stop(handle->task);
}
static inline struct sk_buff *rsi_get_aligned_skb(struct sk_buff *skb) {
u8 *skb_data = skb->data;
int skb_len = skb->len;
skb_push(skb, RSI_DMA_ALIGN);
skb_pull(skb, PTR_ALIGN(skb->data,
RSI_DMA_ALIGN) - skb->data);
memmove(skb->data, skb_data, skb_len);
skb_trim(skb, skb_len);
return skb;
}
void rsi_mac80211_detach(struct rsi_hw *hw);
u16 rsi_get_connected_channel(struct ieee80211_vif *vif);
struct rsi_hw *rsi_91x_init(u16 oper_mode);
u16 rsi_get_connected_channel(struct rsi_hw *adapter);
struct rsi_hw *rsi_91x_init(void);
void rsi_91x_deinit(struct rsi_hw *adapter);
int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len);
#ifdef CONFIG_PM
int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan);
#endif
void rsi_indicate_bcnmiss(struct rsi_common *common);
void rsi_resume_conn_channel(struct rsi_hw *adapter, struct ieee80211_vif *vif);
char *dot11_pkt_type(__le16 frame_control);
struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac);
void rsi_init_bcn_timer(struct rsi_common *common);
void rsi_del_bcn_timer(struct rsi_common *common);
void rsi_bcn_scheduler_thread(struct rsi_common *common);
#ifdef CONFIG_SDIO_INTR_POLL
void init_sdio_intr_status_poll_thread(struct rsi_common *common);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION (4, 15, 0)
void rsi_roc_timeout(unsigned long data);
#else
void rsi_roc_timeout(struct timer_list *t);
#endif
struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac);
#ifdef CONFIG_HW_SCAN_OFFLOAD
void rsi_mac80211_hw_scan_cancel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
#endif
#ifdef CONFIG_RSI_WOW
int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan);
#endif
#endif
/**
* Copyright (c) 2014 Redpine Signals Inc.
/*
* Copyright (c) 2017 Redpine Signals Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* Redistribution and use in source and binary forms, with or without