diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-06-09 11:10:05 -0600 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2016-06-09 11:10:06 -0600 |
| commit | 9876c3c76af89f339ffff05d37507ee72685b794 (patch) | |
| tree | 1688216fbfb7d09bc878f4ea242115c9f3b5c05d | |
| parent | bb9837e5470b84149ece8812ee894c5ea08b99c1 (diff) | |
| parent | 31bcecd1a2ab7e15d804ffaf3a7589c9cd91b1a9 (diff) | |
Promotion of kernel.lnx.4.4-160607.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
1015627 I570b66886edf949c3d77027d0dc8baf820c5cf0f wil6210: change RX_HTRSH interrupt print level to debug
1023892 I0d2442c7b3d156ad919626a6015f0fbbf2116c3f ASoC: msm: enable HDMI audio for 8996
1021086 Ieae3c1f9fce6a753821c898bcda7cd67a6b04c20 defconfig: arm64: enable dummy CoreSight source driver
1023377 Ifa797703da0ac846167651c7ed03a6710ba41867 ARM: dts: msm: Correct the offset for AD blocks on msmco
1024957 Ibc0b0506b2090f4c090d649f6e3ae7d42b102c93 usb: dwc3: Fix extcon notification for non-type-c usb ca
1024406 I68c32ef3d08b2cf943b52a7269785d0a00146953 usb: gadget: f_mtp: Make RX buffer size aligned to EP's
1025380 I02fc72583fcd9bc27156ce717b52ef17e16313d5 msm: mdss: fix solidfill config for multi-rect pipes
1015627 Ib7ff8f1debd6873069df42efd7d832db64701258 wil6210: add function name to wil log macros
1024406 I74d5da09437c25e9f1772f7cd49aecb8e4fedcf2 USB: gadget: mtp: Add module parameter for Rx transfer l
1023830 I96345f025e0da99d595e60b37f34bf581927c153 msm: wlan: Regulatory updates
1015627 If1cdfdb2086ff7e3dbf02e9a5920ef3ed0a31280 wil6210: support regular scan on P2P_DEVICE interface
1024406 I2cd9780f8b3e0ce541472c4d25c8294f11a45d76 USB: f_mtp: Handle corner cases on reception of Cancel r
999360 I2cd27481cc0fb189e35ea44709fe27ad0884fcfd ARM: dts: msm: Increase snapshot size for msm8996 and ms
1025592 I67fef3fc65b24febef070ca9f896036f38a87fb9 ARM: dts: msm: Set alignment to 4 MB for msmcobalt
1011072 Ib357ee3c3a461613bfd1268ec8f98973c2982c10 drivers: thermal: Add ftrace events for LMH DCVSh mitiga
993338 I85cb0223ce45de2712c20a3a0edffe2a84b80f01 soc: rpm-smd: Support new format of rpm messaging
1025294 I768a9c4886aa3fe2e827aba682f67bac2dba6f71 mm/page_alloc: prevent merging between isolated and othe
1024406 I675fc3303be2aba081d2ab59a9efb94aa478f849 USB: gadget: mtp: Add module parameters for Tx transfer
1015627 Ic6bbe8b2aee53d019013159cd21597c2fa0f298f wil6210: prevent deep sleep of 60G device in critical pa
1024406 I2eedf829f267150ff7a303824e95963219a1f555 USB: gadget: mtp: Fix OUT endpoint request length usage
1023830 I3c450ceae589ec8758eb0f0323140faab0cbc43b msm: wlan: Change Tx Power for ETSI1 regulatory domain
1024948 I562bb546f49b1605f20fb7d705f40584d190230b clk: msm: clock: Add support for programming the GCC_GPU
1024406 Ie95cbfc9444c56c8268b70e2916713190699c71a USB: Add super speed descriptors for gadget functions
1024406 I0e706d5280a2460baf6ab05dbf97a09c59b642fb USB: f_mtp: Check if the ep is not disabled before queui
973565 I4b52c7bfb3713ffd4a5bcb2aacd134d69d1dbcd4 ARM: dts: msm8998: Temporary disable GPU Turbo on A540
1019910 If6fdebb36d7108b2ac9b5f3c8a787d305505545c ARM: dts: msm: Update the LMH interrupt information for
1015627 I41eecc91730c60a1851969f8fecf7c201b8b2050 wil6210: print debug message when transmitting while dis
1015627 I3b7770b0cbaec634ca566a82ccc648b6835d75a0 wil6210: add support for device led configuration
1021086 I5d08f4f4db00affd5f7a9e6709714d862d42c6ef ARM: dts: msm: add dummy WCSS tpdm device for msmcobalt
1021964 I191c4709e79d1b13e3f6fd31c5e738d3c2094bc7 msm: ipa3: fix dereferencing of offset_entry without che
1015627 I9fa0e28d91d0962fc7f05b2cf92c99c2431a2295 wil6210: unmask RX_HTRSH interrupt only when connected
987939 I1b1f1801eb0578644b2e954a3a3ade17b3f2a1fd msm: camera: Setting actuator to initial position
1006333 If72eed62e28ccaafa2e0fb6186ec88571b4e657a ARM: dts: msm: Enable QoS settings for fabs for msmcobal
1024406 Ia8cbd1cd8c81b90389900b83744b2bed89068db5 USB: f_mtp: Fix corner cases in MTP driver while syncing
Change-Id: I8692b7ea10e8fc42a4cfdfecbc68fb5feb853f0c
CRs-Fixed: 987939, 1015627, 1021964, 1011072, 1023377, 1021086, 993338, 1023830, 999360, 973565, 1024406, 1025592, 1019910, 1024957, 1006333, 1025380, 1025294, 1023892, 1024948
41 files changed, 1672 insertions, 512 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt b/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt index 128bd0f799d2..4cba3ecaeb90 100644 --- a/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt +++ b/Documentation/devicetree/bindings/arm/msm/rpm-smd.txt @@ -26,11 +26,14 @@ Required properties Optional properties - rpm-standalone: Allow RPM driver to run in standalone mode irrespective of RPM channel presence. +- reg: Contains the memory address at which rpm messaging format version is + stored. If this field is not present, the target only supports v0 format. Example: - qcom,rpm-smd { + qcom,rpm-smd@68150 { compatible = "qcom,rpm-smd", "qcom,rpm-glink"; + reg = <0x68150 0x3200>; qcom,rpm-channel-name = "rpm_requests"; qcom,rpm-channel-type = 15; /* SMD_APPS_RPM */ qcom,glink-edge = "rpm"; diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt index e55e64eea1ea..dedf13c2dc3d 100644 --- a/Documentation/devicetree/bindings/gpu/adreno.txt +++ b/Documentation/devicetree/bindings/gpu/adreno.txt @@ -130,6 +130,10 @@ Optional Properties: rendering thread is running on masked CPUs. Bit 0 is for CPU-0, bit 1 is for CPU-1... +- qcom,snapshot-size: + Specify the size of snapshot in bytes. This will override + snapshot size defined in the driver code. + GPU Quirks: - qcom,gpu-quirk-two-pass-use-wfi: Signal the GPU to set Set TWOPASSUSEWFI bit in diff --git a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi index 81f4fa8dda73..25e0d99987db 100644 --- a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi @@ -77,6 +77,8 @@ qcom,highest-bank-bit = <15>; + qcom,snapshot-size = <1048576>; //bytes + /* Trace bus */ coresight-id = <300>; coresight-name = "coresight-gfx"; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi index 45eee0caaac9..e73d6f896aa8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi @@ -35,13 +35,24 @@ label = "fab-a1noc"; qcom,fab-dev; qcom,base-name = "a1noc-base"; - qcom,bypass-qos-prg; qcom,bus-type = <1>; qcom,qos-off = <4096>; qcom,base-offset = <36864>; clock-names = "bus_clk", "bus_a_clk"; clocks = <&clock_gcc clk_aggre1_noc_clk>, <&clock_gcc clk_aggre1_noc_a_clk>; + qcom,node-qos-clks { + clock-names = + "clk-ufs-axi-clk", + "clk-aggre1-ufs-axi-no-rate", + "clk-aggre1-usb3-axi-cfg-no-rate", + "clk-blsp2-ahb-no-rate"; + clocks = + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_aggre1_ufs_axi_clk>, + <&clock_gcc clk_gcc_aggre1_usb3_axi_clk>, + <&clock_gcc clk_gcc_blsp2_ahb_clk>; + }; }; fab_a2noc: fab-a2noc { @@ -49,13 +60,24 @@ label = "fab-a2noc"; qcom,fab-dev; qcom,base-name = "a2noc-base"; - qcom,bypass-qos-prg; qcom,bus-type = <1>; qcom,qos-off = <4096>; qcom,base-offset = <20480>; clock-names = "bus_clk", "bus_a_clk"; clocks = <&clock_gcc clk_aggre2_noc_clk>, <&clock_gcc clk_aggre2_noc_a_clk>; + qcom,node-qos-clks { + clock-names = + "clk-ipa-clk", + "clk-sdcc2-ahb-no-rate", + "clk-sdcc4-ahb-no-rate", + "clk-blsp1-ahb-no-rate"; + clocks = + <&clock_gcc clk_ipa_clk>, + <&clock_gcc clk_gcc_sdcc2_ahb_clk>, + <&clock_gcc clk_gcc_sdcc4_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; }; fab_bimc: fab-bimc { @@ -64,7 +86,6 @@ qcom,fab-dev; qcom,base-name = "bimc-base"; qcom,bus-type = <2>; - qcom,bypass-qos-prg; qcom,util-fact = <153>; clock-names = "bus_clk", "bus_a_clk"; clocks = <&clock_gcc clk_bimc_msmbus_clk>, @@ -76,7 +97,6 @@ label = "fab-cnoc"; qcom,fab-dev; qcom,base-name = "cnoc-base"; - qcom,bypass-qos-prg; qcom,bus-type = <1>; clock-names = "bus_clk", "bus_a_clk"; clocks = <&clock_gcc clk_cnoc_clk>, @@ -108,7 +128,6 @@ label = "fab-mnoc"; qcom,fab-dev; qcom,base-name = "mnoc-base"; - qcom,bypass-qos-prg; qcom,bus-type = <1>; qcom,qos-off = <4096>; qcom,base-offset = <16384>; @@ -116,6 +135,25 @@ clock-names = "bus_clk", "bus_a_clk"; clocks = <&clock_gcc clk_mmssnoc_axi_clk>, <&clock_gcc clk_mmssnoc_axi_a_clk>; + qcom,node-qos-clks { + clock-names = + "clk-noc-cfg-ahb-no-rate", + "clk-mnoc-ahb-no-rate", + "clk-mdss-ahb-no-rate", + "clk-mdss-axi-no-rate", + "clk-camss-ahb-no-rate", + "clk-video-ahb-no-rate", + "clk-video-axi-no-rate"; + clocks = + <&clock_gcc clk_gcc_mmss_noc_cfg_ahb_clk>, + <&clock_mmss clk_mmss_mnoc_ahb_clk>, + <&clock_mmss clk_mmss_mdss_ahb_clk>, + <&clock_mmss clk_mmss_mdss_axi_clk>, + <&clock_mmss clk_mmss_camss_ahb_clk>, + <&clock_mmss clk_mmss_video_ahb_clk>, + <&clock_mmss clk_mmss_video_axi_clk>; + }; + }; fab_snoc: fab-snoc { @@ -123,7 +161,6 @@ label = "fab-snoc"; qcom,fab-dev; qcom,base-name = "snoc-base"; - qcom,bypass-qos-prg; qcom,bus-type = <1>; qcom,qos-off = <4096>; qcom,base-offset = <20480>; @@ -169,7 +206,7 @@ qcom,buswidth = <16>; qcom,agg-ports = <1>; qcom,ap-owned; - qcom,qport = <3>; + qcom,qport = <2>; qcom,qos-mode = "fixed"; qcom,connections = <&slv_a1noc_snoc>; qcom,prio1 = <1>; @@ -198,7 +235,7 @@ label = "mas-blsp-2"; qcom,buswidth = <16>; qcom,agg-ports = <1>; - qcom,qport = <3>; + qcom,qport = <4>; qcom,qos-mode = "fixed"; qcom,connections = <&slv_a1noc_snoc>; qcom,bus-dev = <&fab_a1noc>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi index 53f415153a21..733d36aa43b8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi @@ -920,6 +920,14 @@ <&tpda_out_funnel_qatb>; }; }; + port@2 { + reg = <3>; + funnel_qatb_in_funnel_dlet_qatb: endpoint { + slave-mode; + remote-endpoint = + <&funnel_dlet_qatb_out_funnel_qatb>; + }; + }; }; }; @@ -1473,4 +1481,52 @@ }; }; }; + + funnel_dlet_qatb: funnel@7225000 { + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b908>; + + reg = <0x7225000 0x1000>; + reg-names = "funnel-base"; + + coresight-name = "coresight-funnel-dlet-qatb"; + + clocks = <&clock_gcc clk_qdss_clk>, + <&clock_gcc clk_qdss_a_clk>; + clock-names = "apb_pclk", "core_a_clk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + funnel_dlet_qatb_out_funnel_qatb: endpoint { + remote-endpoint = + <&funnel_qatb_in_funnel_dlet_qatb>; + }; + }; + port@1 { + reg = <1>; + funnel_dlet_qatb_in_tpdm_wcss: endpoint { + slave-mode; + remote-endpoint = + <&tpdm_wcss_out_funnel_dlet_qatb>; + }; + }; + }; + }; + + dummy-tpdm-wcss { + compatible = "qcom,coresight-dummy"; + + coresight-name = "coresight-tpdm-wcss"; + + port{ + tpdm_wcss_out_funnel_dlet_qatb: endpoint { + remote-endpoint = + <&funnel_dlet_qatb_in_tpdm_wcss>; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi index fd7e0404691c..370abc8085aa 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi @@ -77,6 +77,8 @@ qcom,highest-bank-bit = <15>; + qcom,snapshot-size = <1048576>; //bytes + clocks = <&clock_gfx clk_gpucc_gfx3d_clk>, <&clock_gcc clk_gcc_gpu_cfg_ahb_clk>, <&clock_gpu clk_gpucc_rbbmtimer_clk>, @@ -125,9 +127,9 @@ qcom,gpu-pwrlevel@0 { reg = <0>; - qcom,gpu-freq = <650000000>; - qcom,bus-freq = <12>; - qcom,bus-min = <11>; + qcom,gpu-freq = <504000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; qcom,bus-max = <12>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi index 6c644ac95af0..bb82d37de626 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi @@ -103,7 +103,7 @@ qcom,mdss-has-pingpong-split; qcom,mdss-has-separate-rotator; - qcom,mdss-ad-off = <0x0079000 0x00079800 0x0007a000>; + qcom,mdss-ad-off = <0x0079000 0x00079800>; qcom,mdss-cdm-off = <0x0007a200>; qcom,mdss-dsc-off = <0x00081000 0x00081400>; qcom,mdss-wfd-mode = "intf"; diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi index b666f535a664..d4b8d8481a32 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi @@ -283,7 +283,7 @@ compatible = "shared-dma-pool"; alloc-ranges = <0 0x00000000 0 0xffffffff>; reusable; - alignment = <0 0x100000>; + alignment = <0 0x400000>; size = <0 0x400000>; }; @@ -2313,7 +2313,7 @@ qcom,lmh { compatible = "qcom,lmh_v1"; - interrupts = <0 6 4>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; }; qcom,msm-thermal { diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 80a57bb16719..3b223b5996bc 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -607,6 +607,7 @@ CONFIG_CORESIGHT_CTI=y CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_QPDI=y +CONFIG_CORESIGHT_SOURCE_DUMMY=y CONFIG_KEYS=y CONFIG_SECURITY=y CONFIG_SECURITY_SELINUX=y diff --git a/drivers/clk/msm/clock-gcc-cobalt.c b/drivers/clk/msm/clock-gcc-cobalt.c index d225e710560b..56b1c2c73dda 100644 --- a/drivers/clk/msm/clock-gcc-cobalt.c +++ b/drivers/clk/msm/clock-gcc-cobalt.c @@ -1683,6 +1683,17 @@ static struct branch_clk gcc_gpu_snoc_dvm_gfx_clk = { }, }; +static struct branch_clk gcc_gpu_iref_clk = { + .cbcr_reg = GCC_GPU_IREF_EN, + .has_sibling = 1, + .base = &virt_base, + .c = { + .dbg_name = "gcc_gpu_iref_clk", + .ops = &clk_ops_branch, + CLK_INIT(gcc_gpu_iref_clk.c), + }, +}; + static struct local_vote_clk gcc_bimc_hmss_axi_clk = { .cbcr_reg = GCC_BIMC_HMSS_AXI_CBCR, .vote_reg = GCC_APCS_CLOCK_BRANCH_ENA_VOTE, @@ -2645,6 +2656,7 @@ static struct clk_lookup msm_clocks_gcc_cobalt[] = { CLK_LIST(gcc_gpu_bimc_gfx_src_clk), CLK_LIST(gcc_gpu_cfg_ahb_clk), CLK_LIST(gcc_gpu_snoc_dvm_gfx_clk), + CLK_LIST(gcc_gpu_iref_clk), CLK_LIST(gcc_bimc_hmss_axi_clk), CLK_LIST(gcc_hmss_ahb_clk), CLK_LIST(gcc_hmss_dvm_bus_clk), diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 1344af239dd6..0b3e4e1fcf04 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1165,6 +1165,7 @@ static int32_t msm_actuator_set_position( } a_ctrl->i2c_tbl_index = 0; + hw_params = set_pos->hw_params; for (index = 0; index < set_pos->number_of_steps; index++) { next_lens_position = set_pos->pos[index]; delay = set_pos->delay[index]; diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 12cae3c005fb..49eb2e27b11b 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -375,8 +375,9 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, return -EBUSY; } - /* scan on P2P_DEVICE is handled as p2p search */ - if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { + /* social scan on P2P_DEVICE is handled as p2p search */ + if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE && + wil_p2p_is_social_scan(request)) { wil->scan_request = request; wil->radio_wdev = wdev; rc = wil_p2p_search(wil, request); diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c index 3249562d93b4..c312a667c12a 100644 --- a/drivers/net/wireless/ath/wil6210/debug.c +++ b/drivers/net/wireless/ath/wil6210/debug.c @@ -17,7 +17,7 @@ #include "wil6210.h" #include "trace.h" -void wil_err(struct wil6210_priv *wil, const char *fmt, ...) +void __wil_err(struct wil6210_priv *wil, const char *fmt, ...) { struct net_device *ndev = wil_to_ndev(wil); struct va_format vaf = { @@ -32,7 +32,7 @@ void wil_err(struct wil6210_priv *wil, const char *fmt, ...) va_end(args); } -void wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...) +void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...) { if (net_ratelimit()) { struct net_device *ndev = wil_to_ndev(wil); @@ -49,7 +49,23 @@ void wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...) } } -void wil_info(struct wil6210_priv *wil, const char *fmt, ...) +void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (!net_ratelimit()) + return; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + netdev_dbg(wil_to_ndev(wil), "%pV", &vaf); + trace_wil6210_log_dbg(&vaf); + va_end(args); +} + +void __wil_info(struct wil6210_priv *wil, const char *fmt, ...) { struct net_device *ndev = wil_to_ndev(wil); struct va_format vaf = { diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index f3de1759a86a..f8e36ba47ac7 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -171,6 +171,8 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, int rsize; uint i; + wil_halp_vote(wil); + wil_memcpy_fromio_32(&r, off, sizeof(r)); wil_mbox_ring_le2cpus(&r); /* @@ -236,6 +238,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, } out: seq_puts(s, "}\n"); + wil_halp_unvote(wil); } static int wil_mbox_debugfs_show(struct seq_file *s, void *data) @@ -500,9 +503,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { enum { max_count = 4096 }; - struct debugfs_blob_wrapper *blob = file->private_data; + struct wil_blob_wrapper *wil_blob = file->private_data; loff_t pos = *ppos; - size_t available = blob->size; + size_t available = wil_blob->blob.size; void *buf; size_t ret; @@ -521,8 +524,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; - wil_memcpy_fromio_32(buf, (const volatile void __iomem *)blob->data + - pos, count); + wil_memcpy_fromio_halp_vote(wil_blob->wil, buf, + (const volatile void __iomem *) + wil_blob->blob.data + pos, count); ret = copy_to_user(user_buf, buf, count); kfree(buf); @@ -545,9 +549,9 @@ static struct dentry *wil_debugfs_create_ioblob(const char *name, umode_t mode, struct dentry *parent, - struct debugfs_blob_wrapper *blob) + struct wil_blob_wrapper *wil_blob) { - return debugfs_create_file(name, mode, parent, blob, &fops_ioblob); + return debugfs_create_file(name, mode, parent, wil_blob, &fops_ioblob); } /*---reset---*/ @@ -1443,6 +1447,118 @@ static const struct file_operations fops_sta = { .llseek = seq_lseek, }; +static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + char buf[80]; + int n; + + n = snprintf(buf, sizeof(buf), + "led_id is set to %d, echo 1 to enable, 0 to disable\n", + led_id); + + n = min_t(int, n, sizeof(buf)); + + return simple_read_from_buffer(user_buf, count, ppos, + buf, n); +} + +static ssize_t wil_write_file_led_cfg(struct file *file, + const char __user *buf_, + size_t count, loff_t *ppos) +{ + struct wil6210_priv *wil = file->private_data; + int val; + int rc; + + rc = kstrtoint_from_user(buf_, count, 0, &val); + if (rc) { + wil_err(wil, "Invalid argument\n"); + return rc; + } + + wil_info(wil, "%s led %d\n", val ? "Enabling" : "Disabling", led_id); + rc = wmi_led_cfg(wil, val); + if (rc) { + wil_info(wil, "%s led %d failed\n", + val ? "Enabling" : "Disabling", led_id); + return rc; + } + + return count; +} + +static const struct file_operations fops_led_cfg = { + .read = wil_read_file_led_cfg, + .write = wil_write_file_led_cfg, + .open = simple_open, +}; + +/* led_blink_time, write: + * "<blink_on_slow> <blink_off_slow> <blink_on_med> <blink_off_med> <blink_on_fast> <blink_off_fast> + */ +static ssize_t wil_write_led_blink_time(struct file *file, + const char __user *buf, + size_t len, loff_t *ppos) +{ + int rc; + char *kbuf = kmalloc(len + 1, GFP_KERNEL); + + if (!kbuf) + return -ENOMEM; + + rc = simple_write_to_buffer(kbuf, len, ppos, buf, len); + if (rc != len) { + kfree(kbuf); + return rc >= 0 ? -EIO : rc; + } + + kbuf[len] = '\0'; + rc = sscanf(kbuf, "%d %d %d %d %d %d", + &led_blink_time[WIL_LED_TIME_SLOW].on_ms, + &led_blink_time[WIL_LED_TIME_SLOW].off_ms, + &led_blink_time[WIL_LED_TIME_MED].on_ms, + &led_blink_time[WIL_LED_TIME_MED].off_ms, + &led_blink_time[WIL_LED_TIME_FAST].on_ms, + &led_blink_time[WIL_LED_TIME_FAST].off_ms); + kfree(kbuf); + + if (rc < 0) + return rc; + if (rc < 6) + return -EINVAL; + + return len; +} + +static ssize_t wil_read_led_blink_time(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + static char text[400]; + + snprintf(text, sizeof(text), + "To set led blink on/off time variables write:\n" + "<blink_on_slow> <blink_off_slow> <blink_on_med> " + "<blink_off_med> <blink_on_fast> <blink_off_fast>\n" + "The current values are:\n" + "%d %d %d %d %d %d\n", + led_blink_time[WIL_LED_TIME_SLOW].on_ms, + led_blink_time[WIL_LED_TIME_SLOW].off_ms, + led_blink_time[WIL_LED_TIME_MED].on_ms, + led_blink_time[WIL_LED_TIME_MED].off_ms, + led_blink_time[WIL_LED_TIME_FAST].on_ms, + led_blink_time[WIL_LED_TIME_FAST].off_ms); + + return simple_read_from_buffer(user_buf, count, ppos, text, + sizeof(text)); +} + +static const struct file_operations fops_led_blink_time = { + .read = wil_read_led_blink_time, + .write = wil_write_led_blink_time, + .open = simple_open, +}; + /*----------------*/ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, struct dentry *dbg) @@ -1451,16 +1567,18 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, char name[32]; for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { - struct debugfs_blob_wrapper *blob = &wil->blobs[i]; + struct wil_blob_wrapper *wil_blob = &wil->blobs[i]; + struct debugfs_blob_wrapper *blob = &wil_blob->blob; const struct fw_map *map = &fw_mapping[i]; if (!map->name) continue; + wil_blob->wil = wil; blob->data = (void * __force)wil->csr + HOSTADDR(map->host); blob->size = map->to - map->from; snprintf(name, sizeof(name), "blob_%s", map->name); - wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob); + wil_debugfs_create_ioblob(name, S_IRUGO, dbg, wil_blob); } } @@ -1489,6 +1607,8 @@ static const struct { {"link", S_IRUGO, &fops_link}, {"info", S_IRUGO, &fops_info}, {"recovery", S_IRUGO | S_IWUSR, &fops_recovery}, + {"led_cfg", S_IRUGO | S_IWUSR, &fops_led_cfg}, + {"led_blink_time", S_IRUGO | S_IWUSR, &fops_led_blink_time}, }; static void wil6210_debugfs_init_files(struct wil6210_priv *wil, @@ -1551,6 +1671,7 @@ static const struct dbg_off dbg_statics[] = { {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, {"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh, doff_u32}, + {"led_polarity", S_IRUGO | S_IWUSR, (ulong)&led_polarity, doff_u8}, {}, }; diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index fe66b2b646f0..011e7412dcc0 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -35,15 +35,19 @@ * */ -#define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL) +#define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL) +#define WIL6210_IRQ_DISABLE_NO_HALP (0xF7FFFFFFUL) #define WIL6210_IMC_RX (BIT_DMA_EP_RX_ICR_RX_DONE | \ BIT_DMA_EP_RX_ICR_RX_HTRSH) +#define WIL6210_IMC_RX_NO_RX_HTRSH (WIL6210_IMC_RX & \ + (~(BIT_DMA_EP_RX_ICR_RX_HTRSH))) #define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \ BIT_DMA_EP_TX_ICR_TX_DONE_N(0)) -#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | \ - ISR_MISC_MBOX_EVT | \ - ISR_MISC_FW_ERROR) - +#define WIL6210_IMC_MISC_NO_HALP (ISR_MISC_FW_READY | \ + ISR_MISC_MBOX_EVT | \ + ISR_MISC_FW_ERROR) +#define WIL6210_IMC_MISC (WIL6210_IMC_MISC_NO_HALP | \ + BIT_DMA_EP_MISC_ICR_HALP) #define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \ BIT_DMA_PSEUDO_CAUSE_TX | \ BIT_DMA_PSEUDO_CAUSE_MISC)) @@ -51,6 +55,7 @@ #if defined(CONFIG_WIL6210_ISR_COR) /* configure to Clear-On-Read mode */ #define WIL_ICR_ICC_VALUE (0xFFFFFFFFUL) +#define WIL_ICR_ICC_MISC_VALUE (0xF7FFFFFFUL) static inline void wil_icr_clear(u32 x, void __iomem *addr) { @@ -58,6 +63,7 @@ static inline void wil_icr_clear(u32 x, void __iomem *addr) #else /* defined(CONFIG_WIL6210_ISR_COR) */ /* configure to Write-1-to-Clear mode */ #define WIL_ICR_ICC_VALUE (0UL) +#define WIL_ICR_ICC_MISC_VALUE (0UL) static inline void wil_icr_clear(u32 x, void __iomem *addr) { @@ -86,10 +92,21 @@ static void wil6210_mask_irq_rx(struct wil6210_priv *wil) WIL6210_IRQ_DISABLE); } -static void wil6210_mask_irq_misc(struct wil6210_priv *wil) +static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp) { + wil_dbg_irq(wil, "%s: mask_halp(%s)\n", __func__, + mask_halp ? "true" : "false"); + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS), - WIL6210_IRQ_DISABLE); + mask_halp ? WIL6210_IRQ_DISABLE : WIL6210_IRQ_DISABLE_NO_HALP); +} + +static void wil6210_mask_halp(struct wil6210_priv *wil) +{ + wil_dbg_irq(wil, "%s()\n", __func__); + + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS), + BIT_DMA_EP_MISC_ICR_HALP); } static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) @@ -109,14 +126,27 @@ void wil6210_unmask_irq_tx(struct wil6210_priv *wil) void wil6210_unmask_irq_rx(struct wil6210_priv *wil) { + bool unmask_rx_htrsh = test_bit(wil_status_fwconnected, wil->status); + wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC), - WIL6210_IMC_RX); + unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH); } -static void wil6210_unmask_irq_misc(struct wil6210_priv *wil) +static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp) { + wil_dbg_irq(wil, "%s: unmask_halp(%s)\n", __func__, + unmask_halp ? "true" : "false"); + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC), - WIL6210_IMC_MISC); + unmask_halp ? WIL6210_IMC_MISC : WIL6210_IMC_MISC_NO_HALP); +} + +static void wil6210_unmask_halp(struct wil6210_priv *wil) +{ + wil_dbg_irq(wil, "%s()\n", __func__); + + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC), + BIT_DMA_EP_MISC_ICR_HALP); } static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) @@ -134,7 +164,7 @@ void wil_mask_irq(struct wil6210_priv *wil) wil6210_mask_irq_tx(wil); wil6210_mask_irq_rx(wil); - wil6210_mask_irq_misc(wil); + wil6210_mask_irq_misc(wil, true); wil6210_mask_irq_pseudo(wil); } @@ -147,12 +177,12 @@ void wil_unmask_irq(struct wil6210_priv *wil) wil_w(wil, RGF_DMA_EP_TX_ICR + offsetof(struct RGF_ICR, ICC), WIL_ICR_ICC_VALUE); wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICC), - WIL_ICR_ICC_VALUE); + WIL_ICR_ICC_MISC_VALUE); wil6210_unmask_irq_pseudo(wil); wil6210_unmask_irq_tx(wil); wil6210_unmask_irq_rx(wil); - wil6210_unmask_irq_misc(wil); + wil6210_unmask_irq_misc(wil, true); } void wil_configure_interrupt_moderation(struct wil6210_priv *wil) @@ -228,11 +258,8 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) */ if (likely(isr & (BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH))) { - wil_dbg_irq(wil, "RX done\n"); - - if (unlikely(isr & BIT_DMA_EP_RX_ICR_RX_HTRSH)) - wil_err_ratelimited(wil, - "Received \"Rx buffer is in risk of overflow\" interrupt\n"); + wil_dbg_irq(wil, "RX done / RX_HTRSH received, ISR (0x%x)\n", + isr); isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); @@ -344,7 +371,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) return IRQ_NONE; } - wil6210_mask_irq_misc(wil); + wil6210_mask_irq_misc(wil, false); if (isr & ISR_MISC_FW_ERROR) { u32 fw_assert_code = wil_r(wil, RGF_FW_ASSERT_CODE); @@ -372,12 +399,19 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) isr &= ~ISR_MISC_FW_READY; } + if (isr & BIT_DMA_EP_MISC_ICR_HALP) { + wil_dbg_irq(wil, "%s: HALP IRQ invoked\n", __func__); + wil6210_mask_halp(wil); + isr &= ~BIT_DMA_EP_MISC_ICR_HALP; + complete(&wil->halp.comp); + } + wil->isr_misc = isr; if (isr) { return IRQ_WAKE_THREAD; } else { - wil6210_unmask_irq_misc(wil); + wil6210_unmask_irq_misc(wil, false); return IRQ_HANDLED; } } @@ -414,7 +448,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie) wil->isr_misc = 0; - wil6210_unmask_irq_misc(wil); + wil6210_unmask_irq_misc(wil, false); return IRQ_HANDLED; } @@ -556,6 +590,23 @@ void wil6210_clear_irq(struct wil6210_priv *wil) wmb(); /* make sure write completed */ } +void wil6210_set_halp(struct wil6210_priv *wil) +{ + wil_dbg_misc(wil, "%s()\n", __func__); + + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS), + BIT_DMA_EP_MISC_ICR_HALP); +} + +void wil6210_clear_halp(struct wil6210_priv *wil) +{ + wil_dbg_misc(wil, "%s()\n", __func__); + + wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR), + BIT_DMA_EP_MISC_ICR_HALP); + wil6210_unmask_halp(wil); +} + int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi) { int rc; diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 8cae68e2afa0..bd8f481da44c 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -23,6 +23,8 @@ #include "wmi.h" #include "boot_loader.h" +#define WAIT_FOR_HALP_VOTE_MS 100 + bool debug_fw; /* = false; */ module_param(debug_fw, bool, S_IRUGO); MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug"); @@ -132,6 +134,14 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, *d++ = __raw_readl(s++); } +void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst, + const volatile void __iomem *src, size_t count) +{ + wil_halp_vote(wil); + wil_memcpy_fromio_32(dst, src, count); + wil_halp_unvote(wil); +} + void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count) { @@ -142,6 +152,15 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, __raw_writel(*s++, d++); } +void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil, + volatile void __iomem *dst, + const void *src, size_t count) +{ + wil_halp_vote(wil); + wil_memcpy_toio_32(dst, src, count); + wil_halp_unvote(wil); +} + static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, u16 reason_code, bool from_event) __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) @@ -194,6 +213,18 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) memset(&sta->stats, 0, sizeof(sta->stats)); } +static bool wil_ap_is_connected(struct wil6210_priv *wil) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { + if (wil->sta[i].status == wil_sta_connected) + return true; + } + + return false; +} + static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, u16 reason_code, bool from_event) { @@ -247,6 +278,11 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, } clear_bit(wil_status_fwconnecting, wil->status); break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + if (!wil_ap_is_connected(wil)) + clear_bit(wil_status_fwconnected, wil->status); + break; default: break; } @@ -457,9 +493,11 @@ int wil_priv_init(struct wil6210_priv *wil) mutex_init(&wil->wmi_mutex); mutex_init(&wil->probe_client_mutex); mutex_init(&wil->p2p_wdev_mutex); + mutex_init(&wil->halp.lock); init_completion(&wil->wmi_ready); init_completion(&wil->wmi_call); + init_completion(&wil->halp.comp); wil->bcast_vring = -1; setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); @@ -555,11 +593,10 @@ static inline void wil_release_cpu(struct wil6210_priv *wil) static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable) { wil_info(wil, "%s: enable=%d\n", __func__, enable); - if (enable) { + if (enable) wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE); - } else { + else wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE); - } } static int wil_target_reset(struct wil6210_priv *wil) @@ -807,6 +844,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); wil_bcast_fini(wil); + /* Disable device led before reset*/ + wmi_led_cfg(wil, false); + /* prevent NAPI from being scheduled and prevent wmi commands */ mutex_lock(&wil->wmi_mutex); bitmap_zero(wil->status, wil_status_last); @@ -874,6 +914,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil->ap_isolate = 0; reinit_completion(&wil->wmi_ready); reinit_completion(&wil->wmi_call); + reinit_completion(&wil->halp.comp); if (load_fw) { wil_configure_interrupt_moderation(wil); @@ -1064,3 +1105,51 @@ int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) return rc; } + +void wil_halp_vote(struct wil6210_priv *wil) +{ + unsigned long rc; + unsigned long to_jiffies = msecs_to_jiffies(WAIT_FOR_HALP_VOTE_MS); + + mutex_lock(&wil->halp.lock); + + wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__, + wil->halp.ref_cnt); + + if (++wil->halp.ref_cnt == 1) { + wil6210_set_halp(wil); + rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies); + if (!rc) + wil_err(wil, "%s: HALP vote timed out\n", __func__); + else + wil_dbg_misc(wil, + "%s: HALP vote completed after %d ms\n", + __func__, + jiffies_to_msecs(to_jiffies - rc)); + } + + wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__, + wil->halp.ref_cnt); + + mutex_unlock(&wil->halp.lock); +} + +void wil_halp_unvote(struct wil6210_priv *wil) +{ + WARN_ON(wil->halp.ref_cnt == 0); + + mutex_lock(&wil->halp.lock); + + wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__, + wil->halp.ref_cnt); + + if (--wil->halp.ref_cnt == 0) { + wil6210_clear_halp(wil); + wil_dbg_misc(wil, "%s: HALP unvote\n", __func__); + } + + wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__, + wil->halp.ref_cnt); + + mutex_unlock(&wil->halp.lock); +} diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c index 2c1b8958180e..1c9153894dca 100644 --- a/drivers/net/wireless/ath/wil6210/p2p.c +++ b/drivers/net/wireless/ath/wil6210/p2p.c @@ -22,6 +22,12 @@ #define P2P_SEARCH_DURATION_MS 500 #define P2P_DEFAULT_BI 100 +bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request) +{ + return (request->n_channels == 1) && + (request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL); +} + void wil_p2p_discovery_timer_fn(ulong x) { struct wil6210_priv *wil = (void *)x; diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index f260b232fd57..a4e43796addb 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -1759,7 +1759,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) goto drop; } if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) { - wil_err_ratelimited(wil, "FW not connected\n"); + wil_dbg_ratelimited(wil, "FW not connected, packet dropped\n"); goto drop; } if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) { diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index a43e484ebf9c..7dbd274e1cd1 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -171,6 +171,7 @@ struct RGF_ICR { #define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */ #define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0) #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1) + #define BIT_DMA_EP_MISC_ICR_HALP BIT(27) #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */ /* Legacy interrupt moderation control (before Sparrow v2)*/ @@ -537,6 +538,41 @@ struct pmc_ctx { int descriptor_size; }; +struct wil_halp { + struct mutex lock; /* protect halp ref_cnt */ + unsigned int ref_cnt; + struct completion comp; +}; + +struct wil_blob_wrapper { + struct wil6210_priv *wil; + struct debugfs_blob_wrapper blob; +}; + +#define WIL_LED_MAX_ID (2) +#define WIL_LED_INVALID_ID (0xF) +#define WIL_LED_BLINK_ON_SLOW_MS (300) +#define WIL_LED_BLINK_OFF_SLOW_MS (300) +#define WIL_LED_BLINK_ON_MED_MS (200) +#define WIL_LED_BLINK_OFF_MED_MS (200) +#define WIL_LED_BLINK_ON_FAST_MS (100) +#define WIL_LED_BLINK_OFF_FAST_MS (100) +enum { + WIL_LED_TIME_SLOW = 0, + WIL_LED_TIME_MED, + WIL_LED_TIME_FAST, + WIL_LED_TIME_LAST, +}; + +struct blink_on_off_time { + u32 on_ms; + u32 off_ms; +}; + +extern struct blink_on_off_time led_blink_time[WIL_LED_TIME_LAST]; +extern u8 led_id; +extern u8 led_polarity; + struct wil6210_priv { struct pci_dev *pdev; struct wireless_dev *wdev; @@ -609,7 +645,7 @@ struct wil6210_priv { atomic_t isr_count_rx, isr_count_tx; /* debugfs */ struct dentry *debug; - struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)]; + struct wil_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)]; u8 discovery_mode; void *platform_handle; @@ -625,6 +661,10 @@ struct wil6210_priv { struct wireless_dev *p2p_wdev; struct mutex p2p_wdev_mutex; /* protect @p2p_wdev */ struct wireless_dev *radio_wdev; + + /* High Access Latency Policy voting */ + struct wil_halp halp; + }; #define wil_to_wiphy(i) (i->wdev->wiphy) @@ -638,11 +678,13 @@ struct wil6210_priv { __printf(2, 3) void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); __printf(2, 3) -void wil_err(struct wil6210_priv *wil, const char *fmt, ...); +void __wil_err(struct wil6210_priv *wil, const char *fmt, ...); +__printf(2, 3) +void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...); __printf(2, 3) -void wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...); +void __wil_info(struct wil6210_priv *wil, const char *fmt, ...); __printf(2, 3) -void wil_info(struct wil6210_priv *wil, const char *fmt, ...); +void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...); #define wil_dbg(wil, fmt, arg...) do { \ netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ wil_dbg_trace(wil, fmt, ##arg); \ @@ -653,6 +695,10 @@ void wil_info(struct wil6210_priv *wil, const char *fmt, ...); #define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) #define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg) #define wil_dbg_pm(wil, fmt, arg...) wil_dbg(wil, "DBG[ PM ]" fmt, ##arg) +#define wil_err(wil, fmt, arg...) __wil_err(wil, "%s: " fmt, __func__, ##arg) +#define wil_info(wil, fmt, arg...) __wil_info(wil, "%s: " fmt, __func__, ##arg) +#define wil_err_ratelimited(wil, fmt, arg...) \ + __wil_err_ratelimited(wil, "%s: " fmt, __func__, ##arg) /* target operations */ /* register read */ @@ -710,6 +756,12 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, size_t count); void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count); +void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst, + const volatile void __iomem *src, + size_t count); +void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil, + volatile void __iomem *dst, + const void *src, size_t count); void *wil_if_alloc(struct device *dev); void wil_if_free(struct wil6210_priv *wil); @@ -775,6 +827,7 @@ void wil_disable_irq(struct wil6210_priv *wil); void wil_enable_irq(struct wil6210_priv *wil); /* P2P */ +bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); void wil_p2p_discovery_timer_fn(ulong x); int wil_p2p_search(struct wil6210_priv *wil, struct cfg80211_scan_request *request); @@ -808,6 +861,7 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go); int wmi_pcp_stop(struct wil6210_priv *wil); +int wmi_led_cfg(struct wil6210_priv *wil, bool enable); void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, u16 reason_code, bool from_event); void wil_probe_client_flush(struct wil6210_priv *wil); @@ -845,4 +899,9 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime); int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size); void wil_fw_core_dump(struct wil6210_priv *wil); +void wil_halp_vote(struct wil6210_priv *wil); +void wil_halp_unvote(struct wil6210_priv *wil); +void wil6210_set_halp(struct wil6210_priv *wil); +void wil6210_clear_halp(struct wil6210_priv *wil); + #endif /* __WIL6210_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 3cc4462aec1a..c9fef36977ca 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -32,6 +32,11 @@ module_param(agg_wsize, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;" " 0 - use default; < 0 - don't auto-establish"); +u8 led_id = WIL_LED_INVALID_ID; +module_param(led_id, byte, S_IRUGO); +MODULE_PARM_DESC(led_id, + " 60G device led enablement. Set the led ID (0-2) to enable"); + /** * WMI event receiving - theory of operations * @@ -94,6 +99,14 @@ const struct fw_map fw_mapping[] = { */ }; +struct blink_on_off_time led_blink_time[] = { + {WIL_LED_BLINK_ON_SLOW_MS, WIL_LED_BLINK_OFF_SLOW_MS}, + {WIL_LED_BLINK_ON_MED_MS, WIL_LED_BLINK_OFF_MED_MS}, + {WIL_LED_BLINK_ON_FAST_MS, WIL_LED_BLINK_OFF_FAST_MS}, +}; + +u8 led_polarity = LED_POLARITY_LOW_ACTIVE; + /** * return AHB address for given firmware/ucode internal (linker) address * @x - internal address @@ -194,6 +207,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) void __iomem *dst; void __iomem *head = wmi_addr(wil, r->head); uint retry; + int rc = 0; if (sizeof(cmd) + len > r->entry_size) { wil_err(wil, "WMI size too large: %d bytes, max is %d\n", @@ -212,6 +226,9 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head); return -EINVAL; } + + wil_halp_vote(wil); + /* read Tx head till it is not busy */ for (retry = 5; retry > 0; retry--) { wil_memcpy_fromio_32(&d_head, head, sizeof(d_head)); @@ -221,7 +238,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) } if (d_head.sync != 0) { wil_err(wil, "WMI head busy\n"); - return -EBUSY; + rc = -EBUSY; + goto out; } /* next head */ next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size); @@ -230,7 +248,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) for (retry = 5; retry > 0; retry--) { if (!test_bit(wil_status_fwready, wil->status)) { wil_err(wil, "WMI: cannot send command while FW not ready\n"); - return -EAGAIN; + rc = -EAGAIN; + goto out; } r->tail = wil_r(wil, RGF_MBOX + offsetof(struct wil6210_mbox_ctl, tx.tail)); @@ -240,13 +259,15 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) } if (next_head == r->tail) { wil_err(wil, "WMI ring full\n"); - return -EBUSY; + rc = -EBUSY; + goto out; } dst = wmi_buffer(wil, d_head.addr); if (!dst) { wil_err(wil, "invalid WMI buffer: 0x%08x\n", le32_to_cpu(d_head.addr)); - return -EINVAL; + rc = -EAGAIN; + goto out; } cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); /* set command */ @@ -269,7 +290,9 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) wil_w(wil, RGF_USER_USER_ICR + offsetof(struct RGF_ICR, ICS), SW_INT_MBOX); - return 0; +out: + wil_halp_unvote(wil); + return rc; } int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) @@ -961,6 +984,60 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); } +int wmi_led_cfg(struct wil6210_priv *wil, bool enable) +{ + int rc = 0; + struct wmi_led_cfg_cmd cmd = { + .led_mode = enable, + .id = led_id, + .slow_blink_cfg.blink_on = + cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].on_ms), + .slow_blink_cfg.blink_off = + cpu_to_le32(led_blink_time[WIL_LED_TIME_SLOW].off_ms), + .medium_blink_cfg.blink_on = + cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].on_ms), + .medium_blink_cfg.blink_off = + cpu_to_le32(led_blink_time[WIL_LED_TIME_MED].off_ms), + .fast_blink_cfg.blink_on = + cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].on_ms), + .fast_blink_cfg.blink_off = + cpu_to_le32(led_blink_time[WIL_LED_TIME_FAST].off_ms), + .led_polarity = led_polarity, + }; + struct { + struct wmi_cmd_hdr wmi; + struct wmi_led_cfg_done_event evt; + } __packed reply; + + if (led_id == WIL_LED_INVALID_ID) + goto out; + + if (led_id > WIL_LED_MAX_ID) { + wil_err(wil, "Invalid led id %d\n", led_id); + rc = -EINVAL; + goto out; + } + + wil_dbg_wmi(wil, + "%s led %d\n", + enable ? "enabling" : "disabling", led_id); + + rc = wmi_call(wil, WMI_LED_CFG_CMDID, &cmd, sizeof(cmd), + WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), + 100); + if (rc) + goto out; + + if (reply.evt.status) { + wil_err(wil, "led %d cfg failed with status %d\n", + led_id, le32_to_cpu(reply.evt.status)); + rc = -EINVAL; + } + +out: + return rc; +} + int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go) { @@ -1003,11 +1080,21 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, if (reply.evt.status != WMI_FW_STATUS_SUCCESS) rc = -EINVAL; + if (wmi_nettype != WMI_NETTYPE_P2P) + /* Don't fail due to error in the led configuration */ + wmi_led_cfg(wil, true); + return rc; } int wmi_pcp_stop(struct wil6210_priv *wil) { + int rc; + + rc = wmi_led_cfg(wil, false); + if (rc) + return rc; + return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0, WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); } diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 29865e0b5203..685fe0ddea26 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -129,6 +129,7 @@ enum wmi_command_id { WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855, WMI_OTP_READ_CMDID = 0x856, WMI_OTP_WRITE_CMDID = 0x857, + WMI_LED_CFG_CMDID = 0x858, /* Performance monitoring commands */ WMI_BF_CTRL_CMDID = 0x862, WMI_NOTIFY_REQ_CMDID = 0x863, @@ -868,6 +869,7 @@ enum wmi_event_id { WMI_RX_MGMT_PACKET_EVENTID = 0x1840, WMI_TX_MGMT_PACKET_EVENTID = 0x1841, WMI_OTP_READ_RESULT_EVENTID = 0x1856, + WMI_LED_CFG_DONE_EVENTID = 0x1858, /* Performance monitoring events */ WMI_DATA_PORT_OPEN_EVENTID = 0x1860, WMI_WBE_LINK_DOWN_EVENTID = 0x1861, @@ -1349,4 +1351,63 @@ enum wmi_hidden_ssid { WMI_HIDDEN_SSID_CLEAR = 0xFE, }; +/* WMI_LED_CFG_CMDID + * + * Configure LED On\Off\Blinking operation + * + * Returned events: + * - WMI_LED_CFG_DONE_EVENTID + */ +enum led_mode { + LED_DISABLE = 0x00, + LED_ENABLE = 0x01, +}; + +/* The names of the led as + * described on HW schemes. + */ +enum wmi_led_id { + WMI_LED_WLAN = 0x00, + WMI_LED_WPAN = 0x01, + WMI_LED_WWAN = 0x02, +}; + +/* Led polarity mode. */ +enum wmi_led_polarity { + LED_POLARITY_HIGH_ACTIVE = 0x00, + LED_POLARITY_LOW_ACTIVE = 0x01, +}; + +/* Combination of on and off + * creates the blinking period + */ +struct wmi_led_blink_mode { + __le32 blink_on; + __le32 blink_off; +} __packed; + +/* WMI_LED_CFG_CMDID */ +struct wmi_led_cfg_cmd { + /* enum led_mode_e */ + u8 led_mode; + /* enum wmi_led_id_e */ + u8 id; + /* slow speed blinking combination */ + struct wmi_led_blink_mode slow_blink_cfg; + /* medium speed blinking combination */ + struct wmi_led_blink_mode medium_blink_cfg; + /* high speed blinking combination */ + struct wmi_led_blink_mode fast_blink_cfg; + /* polarity of the led */ + u8 led_polarity; + /* reserved */ + u8 reserved; +} __packed; + +/* WMI_LED_CFG_DONE_EVENTID */ +struct wmi_led_cfg_done_event { + /* led config status */ + __le32 status; +} __packed; + #endif /* __WILOCITY_WMI_H__ */ diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h index b7e291c6da63..55aa1993d30e 100644 --- a/drivers/platform/msm/ipa/ipa_common_i.h +++ b/drivers/platform/msm/ipa/ipa_common_i.h @@ -16,6 +16,7 @@ #ifndef _IPA_COMMON_I_H_ #define _IPA_COMMON_I_H_ #include <linux/ipc_logging.h> +#include <linux/ipa.h> #define __FILENAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) @@ -267,6 +268,18 @@ struct ipa_mhi_connect_params_internal { struct start_mhi_channel start; }; +/** + * struct ipa_hdr_offset_entry - IPA header offset entry + * @link: entry's link in global header offset entries list + * @offset: the offset + * @bin: bin + */ +struct ipa_hdr_offset_entry { + struct list_head link; + u32 offset; + u32 bin; +}; + extern const char *ipa_clients_strings[]; #define IPA_IPC_LOGGING(buf, fmt, args...) \ diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index 1c4468d23718..cb41f8429771 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -269,18 +269,6 @@ struct ipa_hdr_entry { }; /** - * struct ipa_hdr_offset_entry - IPA header offset entry - * @link: entry's link in global header offset entries list - * @offset: the offset - * @bin: bin - */ -struct ipa_hdr_offset_entry { - struct list_head link; - u32 offset; - u32 bin; -}; - -/** * struct ipa_hdr_tbl - IPA header table * @head_hdr_entry_list: header entries list * @head_offset_list: header offset list diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 2af4e19e02fa..8578417477bb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -4200,7 +4200,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, } ipa3_ctx->hdr_offset_cache = kmem_cache_create("IPA_HDR_OFFSET", - sizeof(struct ipa3_hdr_offset_entry), 0, 0, NULL); + sizeof(struct ipa_hdr_offset_entry), 0, 0, NULL); if (!ipa3_ctx->hdr_offset_cache) { IPAERR(":ipa hdr off cache create failed\n"); result = -ENOMEM; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index 6a14d75a795f..851e71777c32 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -78,7 +78,7 @@ static int ipa3_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, entry->hdr->is_hdr_proc_ctx, entry->hdr->phys_base, hdr_base_addr, - entry->hdr->offset_entry->offset); + entry->hdr->offset_entry); if (ret) return ret; } @@ -419,7 +419,7 @@ bad_len: static int __ipa_add_hdr(struct ipa_hdr_add *hdr) { struct ipa3_hdr_entry *entry; - struct ipa3_hdr_offset_entry *offset; + struct ipa_hdr_offset_entry *offset; u32 bin; struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl; int id; @@ -500,7 +500,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr) /* get the first free slot */ offset = list_first_entry(&htbl->head_free_offset_list[bin], - struct ipa3_hdr_offset_entry, link); + struct ipa_hdr_offset_entry, link); list_move(&offset->link, &htbl->head_offset_list[bin]); } @@ -863,8 +863,8 @@ int ipa3_reset_hdr(void) struct ipa3_hdr_entry *next; struct ipa3_hdr_proc_ctx_entry *ctx_entry; struct ipa3_hdr_proc_ctx_entry *ctx_next; - struct ipa3_hdr_offset_entry *off_entry; - struct ipa3_hdr_offset_entry *off_next; + struct ipa_hdr_offset_entry *off_entry; + struct ipa_hdr_offset_entry *off_next; struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_entry; struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_next; int i; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index b6e6664f209b..d50a25aa84f4 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -329,7 +329,7 @@ struct ipa3_hdr_entry { bool is_hdr_proc_ctx; dma_addr_t phys_base; struct ipa3_hdr_proc_ctx_entry *proc_ctx; - struct ipa3_hdr_offset_entry *offset_entry; + struct ipa_hdr_offset_entry *offset_entry; u32 cookie; u32 ref_cnt; int id; @@ -338,18 +338,6 @@ struct ipa3_hdr_entry { }; /** - * struct ipa3_hdr_offset_entry - IPA header offset entry - * @link: entry's link in global header offset entries list - * @offset: the offset - * @bin: bin - */ -struct ipa3_hdr_offset_entry { - struct list_head link; - u32 offset; - u32 bin; -}; - -/** * struct ipa3_hdr_tbl - IPA header table * @head_hdr_entry_list: header entries list * @head_offset_list: header offset list diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index 7fd8fcbffc9b..7c6318ce121e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -1043,13 +1043,13 @@ static void ipahal_cp_hdr_to_hw_buff_v3(void *const base, u32 offset, * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr * @phys_base: memory location in DDR * @hdr_base_addr: base address in table - * @hdr_offset_entry: offset from hdr_base_addr in table + * @offset_entry: offset from hdr_base_addr in table */ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, void *const base, u32 offset, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, u32 hdr_base_addr, - u32 hdr_offset_entry){ + struct ipa_hdr_offset_entry *offset_entry){ if (type == IPA_HDR_PROC_NONE) { struct ipa_hw_hdr_proc_ctx_add_hdr_seq *ctx; @@ -1059,7 +1059,7 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, ctx->hdr_add.tlv.length = 1; ctx->hdr_add.tlv.value = hdr_len; ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base : - hdr_base_addr + hdr_offset_entry; + hdr_base_addr + offset_entry->offset; IPAHAL_DBG("header address 0x%x\n", ctx->hdr_add.hdr_addr); ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; @@ -1074,7 +1074,7 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, ctx->hdr_add.tlv.length = 1; ctx->hdr_add.tlv.value = hdr_len; ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base : - hdr_base_addr + hdr_offset_entry; + hdr_base_addr + offset_entry->offset; IPAHAL_DBG("header address 0x%x\n", ctx->hdr_add.hdr_addr); ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD; @@ -1132,7 +1132,8 @@ struct ipahal_hdr_funcs { int (*ipahal_cp_proc_ctx_to_hw_buff)(enum ipa_hdr_proc_type type, void *const base, u32 offset, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, - u32 hdr_base_addr, u32 hdr_offset_entry); + u32 hdr_base_addr, + struct ipa_hdr_offset_entry *offset_entry); int (*ipahal_get_proc_ctx_needed_len)(enum ipa_hdr_proc_type type); }; @@ -1196,29 +1197,29 @@ void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *const hdr, * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr * @phys_base: memory location in DDR * @hdr_base_addr: base address in table - * @hdr_offset_entry: offset from hdr_base_addr in table + * @offset_entry: offset from hdr_base_addr in table */ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, void *const base, u32 offset, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, - u32 hdr_base_addr, u32 hdr_offset_entry) + u32 hdr_base_addr, struct ipa_hdr_offset_entry *offset_entry) { IPAHAL_DBG( - "type %d, base %p, offset %d, hdr_len %d, is_hdr_proc_ctx %d, hdr_base_addr %d, hdr_offset_entry %d\n" + "type %d, base %p, offset %d, hdr_len %d, is_hdr_proc_ctx %d, hdr_base_addr %d, offset_entry %p\n" , type, base, offset, hdr_len, is_hdr_proc_ctx, - hdr_base_addr, hdr_offset_entry); + hdr_base_addr, offset_entry); if (!base || !hdr_len || (!phys_base && !hdr_base_addr) || - !hdr_base_addr) { + !hdr_base_addr || offset_entry) { IPAHAL_ERR("failed on validating params"); return -EINVAL; } return hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff(type, base, offset, hdr_len, is_hdr_proc_ctx, phys_base, - hdr_base_addr, hdr_offset_entry); + hdr_base_addr, offset_entry); } /* diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h index 13812585ff6f..ec7eec5ba963 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h @@ -14,6 +14,7 @@ #define _IPAHAL_H_ #include <linux/msm_ipa.h> +#include "../../ipa_common_i.h" /* * Immediate command names @@ -617,12 +618,13 @@ void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *hdr, u32 hdr_len); * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr * @phys_base: memory location in DDR * @hdr_base_addr: base address in table - * @hdr_offset_entry: offset from hdr_base_addr in table + * @offset_entry: offset from hdr_base_addr in table */ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, void *base, u32 offset, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, - u32 hdr_base_addr, u32 hdr_offset_entry); + u32 hdr_base_addr, + struct ipa_hdr_offset_entry *offset_entry); /* * ipahal_get_proc_ctx_needed_len() - calculates the needed length for addition diff --git a/drivers/soc/qcom/rpm-smd.c b/drivers/soc/qcom/rpm-smd.c index b1fa57da7241..fdff6f2140a3 100644 --- a/drivers/soc/qcom/rpm-smd.c +++ b/drivers/soc/qcom/rpm-smd.c @@ -25,6 +25,7 @@ #include <linux/irq.h> #include <linux/list.h> #include <linux/mutex.h> +#include <linux/of_address.h> #include <linux/spinlock.h> #include <linux/string.h> #include <linux/device.h> @@ -88,6 +89,28 @@ static struct glink_apps_rpm_data *glink_data; #define MAX_ERR_BUFFER_SIZE 128 #define MAX_WAIT_ON_ACK 24 #define INIT_ERROR 1 +#define V1_PROTOCOL_VERSION 0x31726576 /* rev1 */ +#define V0_PROTOCOL_VERSION 0 /* rev0 */ +#define RPM_MSG_TYPE_OFFSET 16 +#define RPM_MSG_TYPE_SIZE 8 +#define RPM_SET_TYPE_OFFSET 28 +#define RPM_SET_TYPE_SIZE 4 +#define RPM_REQ_LEN_OFFSET 0 +#define RPM_REQ_LEN_SIZE 16 +#define RPM_MSG_VERSION_OFFSET 24 +#define RPM_MSG_VERSION_SIZE 8 +#define RPM_MSG_VERSION 1 +#define RPM_MSG_SET_OFFSET 28 +#define RPM_MSG_SET_SIZE 4 +#define RPM_RSC_ID_OFFSET 16 +#define RPM_RSC_ID_SIZE 12 +#define RPM_DATA_LEN_OFFSET 0 +#define RPM_DATA_LEN_SIZE 16 +#define RPM_HDR_SIZE ((rpm_msg_fmt_ver == RPM_MSG_V0_FMT) ?\ + sizeof(struct rpm_v0_hdr) : sizeof(struct rpm_v1_hdr)) +#define GET_FIELD(offset, size) (((1U << (offset + size)) - 1) - \ + ((1U << offset) - 1)) +#define CLEAR_FIELD(offset, size) (~GET_FIELD(offset, size)) static ATOMIC_NOTIFIER_HEAD(msm_rpm_sleep_notifier); static bool standalone; @@ -111,17 +134,29 @@ enum { MSM_RPM_MSG_TYPE_NR, }; -static const uint32_t msm_rpm_request_service[MSM_RPM_MSG_TYPE_NR] = { +static const uint32_t msm_rpm_request_service_v1[MSM_RPM_MSG_TYPE_NR] = { 0x716572, /* 'req\0' */ }; -/*the order of fields matter and reflect the order expected by the RPM*/ -struct rpm_request_header { +enum { + RPM_V1_REQUEST_SERVICE, + RPM_V1_SYSTEMDB_SERVICE, + RPM_V1_COMMAND_SERVICE, + RPM_V1_ACK_SERVICE, + RPM_V1_NACK_SERVICE, +} msm_rpm_request_service_v2; + +struct rpm_v0_hdr { uint32_t service_type; uint32_t request_len; }; -struct rpm_message_header { +struct rpm_v1_hdr { + uint32_t request_hdr; +}; + +struct rpm_message_header_v0 { + struct rpm_v0_hdr hdr; uint32_t msg_id; enum msm_rpm_set set; uint32_t resource_type; @@ -129,6 +164,26 @@ struct rpm_message_header { uint32_t data_len; }; +struct rpm_message_header_v1 { + struct rpm_v1_hdr hdr; + uint32_t msg_id; + uint32_t resource_type; + uint32_t request_details; +}; + +struct msm_rpm_ack_msg_v0 { + uint32_t req; + uint32_t req_len; + uint32_t rsc_id; + uint32_t msg_len; + uint32_t id_ack; +}; + +struct msm_rpm_ack_msg_v1 { + uint32_t request_hdr; + uint32_t id_ack; +}; + struct kvp { unsigned int k; unsigned int s; @@ -147,49 +202,252 @@ struct slp_buf { char *buf; bool valid; }; + +enum rpm_msg_fmts { + RPM_MSG_V0_FMT, + RPM_MSG_V1_FMT +}; + +static uint32_t rpm_msg_fmt_ver; +module_param_named( + rpm_msg_fmt_ver, rpm_msg_fmt_ver, uint, S_IRUGO +); + static struct rb_root tr_root = RB_ROOT; static int (*msm_rpm_send_buffer)(char *buf, uint32_t size, bool noirq); static int msm_rpm_send_smd_buffer(char *buf, uint32_t size, bool noirq); static int msm_rpm_glink_send_buffer(char *buf, uint32_t size, bool noirq); static uint32_t msm_rpm_get_next_msg_id(void); -static inline unsigned int get_rsc_type(char *buf) +static inline uint32_t get_offset_value(uint32_t val, uint32_t offset, + uint32_t size) { - struct rpm_message_header *h; - h = (struct rpm_message_header *) - (buf + sizeof(struct rpm_request_header)); - return h->resource_type; + return (((val) & GET_FIELD(offset, size)) + >> offset); } -static inline unsigned int get_rsc_id(char *buf) +static inline void change_offset_value(uint32_t *val, uint32_t offset, + uint32_t size, int32_t val1) { - struct rpm_message_header *h; - h = (struct rpm_message_header *) - (buf + sizeof(struct rpm_request_header)); - return h->resource_id; + uint32_t member = *val; + uint32_t offset_val = get_offset_value(member, offset, size); + uint32_t mask = (1 << size) - 1; + + offset_val += val1; + *val &= CLEAR_FIELD(offset, size); + *val |= ((offset_val & mask) << offset); } -#define get_data_len(buf) \ - (((struct rpm_message_header *) \ - (buf + sizeof(struct rpm_request_header)))->data_len) +static inline void set_offset_value(uint32_t *val, uint32_t offset, + uint32_t size, uint32_t val1) +{ + uint32_t mask = (1 << size) - 1; -#define get_req_len(buf) \ - (((struct rpm_request_header *)(buf))->request_len) + *val &= CLEAR_FIELD(offset, size); + *val |= ((val1 & mask) << offset); +} +static uint32_t get_msg_id(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->msg_id; -#define get_msg_id(buf) \ - (((struct rpm_message_header *) \ - (buf + sizeof(struct rpm_request_header)))->msg_id) + return ((struct rpm_message_header_v1 *)buf)->msg_id; +} + +static uint32_t get_ack_msg_id(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct msm_rpm_ack_msg_v0 *)buf)->id_ack; + + return ((struct msm_rpm_ack_msg_v1 *)buf)->id_ack; + +} + +static uint32_t get_rsc_type(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->resource_type; + + return ((struct rpm_message_header_v1 *)buf)->resource_type; + +} + +static uint32_t get_set_type(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->set; + + return get_offset_value(((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_SET_TYPE_OFFSET, + RPM_SET_TYPE_SIZE); +} + +static uint32_t get_data_len(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->data_len; + + return get_offset_value(((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_DATA_LEN_OFFSET, + RPM_DATA_LEN_SIZE); +} + +static uint32_t get_rsc_id(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->resource_id; + + return get_offset_value(((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_RSC_ID_OFFSET, + RPM_RSC_ID_SIZE); +} + +static uint32_t get_ack_req_len(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct msm_rpm_ack_msg_v0 *)buf)->req_len; + + return get_offset_value(((struct msm_rpm_ack_msg_v1 *)buf)-> + request_hdr, RPM_REQ_LEN_OFFSET, + RPM_REQ_LEN_SIZE); +} + +static uint32_t get_ack_msg_type(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct msm_rpm_ack_msg_v0 *)buf)->req; + + return get_offset_value(((struct msm_rpm_ack_msg_v1 *)buf)-> + request_hdr, RPM_MSG_TYPE_OFFSET, + RPM_MSG_TYPE_SIZE); +} + +static uint32_t get_req_len(char *buf) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return ((struct rpm_message_header_v0 *)buf)->hdr.request_len; + + return get_offset_value(((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_REQ_LEN_OFFSET, + RPM_REQ_LEN_SIZE); +} + +static void set_msg_ver(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver) { + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_MSG_VERSION_OFFSET, + RPM_MSG_VERSION_SIZE, val); + } else { + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_MSG_VERSION_OFFSET, + RPM_MSG_VERSION_SIZE, 0); + } +} + +static void set_req_len(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) { + ((struct rpm_message_header_v0 *)buf)->hdr.request_len = val; + } else { + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_REQ_LEN_OFFSET, + RPM_REQ_LEN_SIZE, val); + } +} + +static void change_req_len(char *buf, int32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) { + ((struct rpm_message_header_v0 *)buf)->hdr.request_len += val; + } else { + change_offset_value(&((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_REQ_LEN_OFFSET, + RPM_REQ_LEN_SIZE, val); + } +} + +static void set_msg_type(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) { + ((struct rpm_message_header_v0 *)buf)->hdr.service_type = + msm_rpm_request_service_v1[val]; + } else { + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + hdr.request_hdr, RPM_MSG_TYPE_OFFSET, + RPM_MSG_TYPE_SIZE, RPM_V1_REQUEST_SERVICE); + } +} + +static void set_rsc_id(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->resource_id = val; + else + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_RSC_ID_OFFSET, + RPM_RSC_ID_SIZE, val); +} + +static void set_data_len(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->data_len = val; + else + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_DATA_LEN_OFFSET, + RPM_DATA_LEN_SIZE, val); +} +static void change_data_len(char *buf, int32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->data_len += val; + else + change_offset_value(&((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_DATA_LEN_OFFSET, + RPM_DATA_LEN_SIZE, val); +} + +static void set_set_type(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->set = val; + else + set_offset_value(&((struct rpm_message_header_v1 *)buf)-> + request_details, RPM_SET_TYPE_OFFSET, + RPM_SET_TYPE_SIZE, val); +} +static void set_msg_id(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->msg_id = val; + else + ((struct rpm_message_header_v1 *)buf)->msg_id = val; + +} + +static void set_rsc_type(char *buf, uint32_t val) +{ + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + ((struct rpm_message_header_v0 *)buf)->resource_type = val; + else + ((struct rpm_message_header_v1 *)buf)->resource_type = val; +} static inline int get_buf_len(char *buf) { - return get_req_len(buf) + sizeof(struct rpm_request_header); + return get_req_len(buf) + RPM_HDR_SIZE; } static inline struct kvp *get_first_kvp(char *buf) { - return (struct kvp *)(buf + sizeof(struct rpm_request_header) - + sizeof(struct rpm_message_header)); + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + return (struct kvp *)(buf + + sizeof(struct rpm_message_header_v0)); + else + return (struct kvp *)(buf + + sizeof(struct rpm_message_header_v1)); } static inline struct kvp *get_next_kvp(struct kvp *k) @@ -203,7 +461,7 @@ static inline void *get_data(struct kvp *k) } -static void delete_kvp(char *msg, struct kvp *d) +static void delete_kvp(char *buf, struct kvp *d) { struct kvp *n; int dec; @@ -211,12 +469,13 @@ static void delete_kvp(char *msg, struct kvp *d) n = get_next_kvp(d); dec = (void *)n - (void *)d; - size = get_data_len(msg) - ((void *)n - (void *)get_first_kvp(msg)); + size = get_data_len(buf) - + ((void *)n - (void *)get_first_kvp(buf)); memcpy((void *)d, (void *)n, size); - get_data_len(msg) -= dec; - get_req_len(msg) -= dec; + change_data_len(buf, -dec); + change_req_len(buf, -dec); } static inline void update_kvp_data(struct kvp *dest, struct kvp *src) @@ -226,20 +485,23 @@ static inline void update_kvp_data(struct kvp *dest, struct kvp *src) static void add_kvp(char *buf, struct kvp *n) { - uint32_t inc = sizeof(*n) + n->s; - BUG_ON((get_req_len(buf) + inc) > MAX_SLEEP_BUFFER); + int32_t inc = sizeof(*n) + n->s; + + if (get_req_len(buf) + inc > MAX_SLEEP_BUFFER) { + WARN_ON(get_req_len(buf) + inc > MAX_SLEEP_BUFFER); + return; + } memcpy(buf + get_buf_len(buf), n, inc); - get_data_len(buf) += inc; - get_req_len(buf) += inc; + change_data_len(buf, inc); + change_req_len(buf, inc); } static struct slp_buf *tr_search(struct rb_root *root, char *slp) { unsigned int type = get_rsc_type(slp); unsigned int id = get_rsc_id(slp); - struct rb_node *node = root->rb_node; while (node) { @@ -265,7 +527,6 @@ static int tr_insert(struct rb_root *root, struct slp_buf *slp) { unsigned int type = get_rsc_type(slp->buf); unsigned int id = get_rsc_id(slp->buf); - struct rb_node **node = &(root->rb_node), *parent = NULL; while (*node) { @@ -295,7 +556,8 @@ static int tr_insert(struct rb_root *root, struct slp_buf *slp) #define for_each_kvp(buf, k) \ for (k = (struct kvp *)get_first_kvp(buf); \ - ((void *)k - (void *)get_first_kvp(buf)) < get_data_len(buf);\ + ((void *)k - (void *)get_first_kvp(buf)) < \ + get_data_len(buf);\ k = get_next_kvp(k)) @@ -333,8 +595,7 @@ static void tr_update(struct slp_buf *s, char *buf) static atomic_t msm_rpm_msg_id = ATOMIC_INIT(0); struct msm_rpm_request { - struct rpm_request_header req_hdr; - struct rpm_message_header msg_hdr; + uint8_t *client_buf; struct msm_rpm_kvp_data *kvp; uint32_t num_elements; uint32_t write_idx; @@ -357,13 +618,7 @@ struct msm_rpm_wait_data { }; DEFINE_SPINLOCK(msm_rpm_list_lock); -struct msm_rpm_ack_msg { - uint32_t req; - uint32_t req_len; - uint32_t rsc_id; - uint32_t msg_len; - uint32_t id_ack; -}; + LIST_HEAD(msm_rpm_ack_list); @@ -371,26 +626,37 @@ static struct tasklet_struct data_tasklet; static inline uint32_t msm_rpm_get_msg_id_from_ack(uint8_t *buf) { - return ((struct msm_rpm_ack_msg *)buf)->id_ack; + return get_ack_msg_id(buf); } static inline int msm_rpm_get_error_from_ack(uint8_t *buf) { uint8_t *tmp; - uint32_t req_len = ((struct msm_rpm_ack_msg *)buf)->req_len; - - struct msm_rpm_ack_msg *tmp_buf = (struct msm_rpm_ack_msg *)buf; + uint32_t req_len = get_ack_req_len(buf); + uint32_t msg_type = get_ack_msg_type(buf); int rc = -ENODEV; + uint32_t err; + uint32_t ack_msg_size = rpm_msg_fmt_ver ? + sizeof(struct msm_rpm_ack_msg_v1) : + sizeof(struct msm_rpm_ack_msg_v0); + + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT && + msg_type == RPM_V1_ACK_SERVICE) { + return 0; + } else if (rpm_msg_fmt_ver && msg_type == RPM_V1_NACK_SERVICE) { + err = *(uint32_t *)(buf + sizeof(struct msm_rpm_ack_msg_v1)); + return err; + } - req_len -= sizeof(struct msm_rpm_ack_msg); + req_len -= ack_msg_size; req_len += 2 * sizeof(uint32_t); if (!req_len) return 0; pr_err("%s:rpm returned error or nack req_len: %d id_ack: %d\n", - __func__, tmp_buf->req_len, tmp_buf->id_ack); + __func__, req_len, get_ack_msg_id(buf)); - tmp = buf + sizeof(struct msm_rpm_ack_msg); + tmp = buf + ack_msg_size; if (memcmp(tmp, ERR, sizeof(uint32_t))) { pr_err("%s rpm returned error\n", __func__); @@ -440,9 +706,9 @@ int msm_rpm_smd_buffer_request(struct msm_rpm_request *cdata, /* handle unsent requests */ tr_update(slp, buf); } - trace_rpm_smd_sleep_set(cdata->msg_hdr.msg_id, - cdata->msg_hdr.resource_type, - cdata->msg_hdr.resource_id); + trace_rpm_smd_sleep_set(get_msg_id(cdata->client_buf), + get_rsc_type(cdata->client_buf), + get_req_len(cdata->client_buf)); spin_unlock_irqrestore(&slp_buffer_lock, flags); @@ -454,8 +720,9 @@ static void msm_rpm_print_sleep_buffer(struct slp_buf *s) int pos; int buflen = DEBUG_PRINT_BUFFER_SIZE; char ch[5] = {0}; - u32 type; struct kvp *e; + uint32_t type; + unsigned int id; if (!s) return; @@ -464,13 +731,15 @@ static void msm_rpm_print_sleep_buffer(struct slp_buf *s) return; type = get_rsc_type(s->buf); + id = get_rsc_id(s->buf); + memcpy(ch, &type, sizeof(u32)); pos = scnprintf(buf, buflen, "Sleep request type = 0x%08x(%s)", - get_rsc_type(s->buf), ch); + type, ch); pos += scnprintf(buf + pos, buflen - pos, " id = 0%x", - get_rsc_id(s->buf)); + id); for_each_kvp(s->buf, e) { uint32_t i; char *data = get_data(e); @@ -544,6 +813,8 @@ static int msm_rpm_flush_requests(bool print) for (t = rb_first(&tr_root); t; t = rb_next(t)) { struct slp_buf *s = rb_entry(t, struct slp_buf, node); + unsigned int type = get_rsc_type(s->buf); + unsigned int id = get_rsc_id(s->buf); if (!s->valid) continue; @@ -551,7 +822,7 @@ static int msm_rpm_flush_requests(bool print) if (print) msm_rpm_print_sleep_buffer(s); - get_msg_id(s->buf) = msm_rpm_get_next_msg_id(); + set_msg_id(s->buf, msm_rpm_get_next_msg_id()); if (!glink_enabled) ret = msm_rpm_send_smd_buffer(s->buf, @@ -561,9 +832,7 @@ static int msm_rpm_flush_requests(bool print) get_buf_len(s->buf), true); WARN_ON(ret != get_buf_len(s->buf)); - trace_rpm_smd_send_sleep_set(get_msg_id(s->buf), - get_rsc_type(s->buf), - get_rsc_id(s->buf)); + trace_rpm_smd_send_sleep_set(get_msg_id(s->buf), type, id); s->valid = false; count++; @@ -587,13 +856,13 @@ static int msm_rpm_flush_requests(bool print) return 0; } -static void msm_rpm_notify_sleep_chain(struct rpm_message_header *hdr, +static void msm_rpm_notify_sleep_chain(char *buf, struct msm_rpm_kvp_data *kvp) { struct msm_rpm_notifier_data notif; - notif.rsc_type = hdr->resource_type; - notif.rsc_id = hdr->resource_id; + notif.rsc_type = get_rsc_type(buf); + notif.rsc_id = get_req_len(buf); notif.key = kvp->key; notif.size = kvp->nbytes; notif.value = kvp->value; @@ -618,7 +887,7 @@ static int msm_rpm_add_kvp_data_common(struct msm_rpm_request *handle, return -EINVAL; data_size = ALIGN(size, SZ_4); - msg_size = data_size + sizeof(struct rpm_request_header); + msg_size = data_size + 8; for (i = 0; i < handle->write_idx; i++) { if (handle->kvp[i].key != key) @@ -657,9 +926,10 @@ static int msm_rpm_add_kvp_data_common(struct msm_rpm_request *handle, } if (!handle->kvp[i].valid) - handle->msg_hdr.data_len += msg_size; + change_data_len(handle->client_buf, msg_size); else - handle->msg_hdr.data_len += (data_size - handle->kvp[i].nbytes); + change_data_len(handle->client_buf, + (data_size - handle->kvp[i].nbytes)); handle->kvp[i].nbytes = data_size; handle->kvp[i].key = key; @@ -675,6 +945,7 @@ static struct msm_rpm_request *msm_rpm_create_request_common( int num_elements, bool noirq) { struct msm_rpm_request *cdata; + uint32_t buf_size; if (probe_status) return ERR_PTR(probe_status); @@ -687,10 +958,19 @@ static struct msm_rpm_request *msm_rpm_create_request_common( goto cdata_alloc_fail; } - cdata->msg_hdr.set = set; - cdata->msg_hdr.resource_type = rsc_type; - cdata->msg_hdr.resource_id = rsc_id; - cdata->msg_hdr.data_len = 0; + if (rpm_msg_fmt_ver == RPM_MSG_V0_FMT) + buf_size = sizeof(struct rpm_message_header_v0); + else + buf_size = sizeof(struct rpm_message_header_v1); + + cdata->client_buf = kzalloc(buf_size, GFP_FLAG(noirq)); + + if (!cdata->client_buf) + goto cdata_alloc_fail; + + set_set_type(cdata->client_buf, set); + set_rsc_type(cdata->client_buf, rsc_type); + set_rsc_id(cdata->client_buf, rsc_id); cdata->num_elements = num_elements; cdata->write_idx = 0; @@ -730,6 +1010,7 @@ void msm_rpm_free_request(struct msm_rpm_request *handle) for (i = 0; i < handle->num_elements; i++) kfree(handle->kvp[i].value); kfree(handle->kvp); + kfree(handle->client_buf); kfree(handle->buf); kfree(handle); } @@ -973,6 +1254,7 @@ static void msm_rpm_log_request(struct msm_rpm_request *cdata) int j, prev_valid; int valid_count = 0; int pos = 0; + uint32_t res_type, rsc_id; name[4] = 0; @@ -983,18 +1265,20 @@ static void msm_rpm_log_request(struct msm_rpm_request *cdata) pos += scnprintf(buf + pos, buflen - pos, "%sRPM req: ", KERN_INFO); if (msm_rpm_debug_mask & MSM_RPM_LOG_REQUEST_SHOW_MSG_ID) pos += scnprintf(buf + pos, buflen - pos, "msg_id=%u, ", - cdata->msg_hdr.msg_id); + get_msg_id(cdata->client_buf)); pos += scnprintf(buf + pos, buflen - pos, "s=%s", - (cdata->msg_hdr.set == MSM_RPM_CTX_ACTIVE_SET ? "act" : "slp")); + (get_set_type(cdata->client_buf) == + MSM_RPM_CTX_ACTIVE_SET ? "act" : "slp")); + res_type = get_rsc_type(cdata->client_buf); + rsc_id = get_rsc_id(cdata->client_buf); if ((msm_rpm_debug_mask & MSM_RPM_LOG_REQUEST_PRETTY) && (msm_rpm_debug_mask & MSM_RPM_LOG_REQUEST_RAW)) { /* Both pretty and raw formatting */ - memcpy(name, &cdata->msg_hdr.resource_type, sizeof(uint32_t)); + memcpy(name, &res_type, sizeof(uint32_t)); pos += scnprintf(buf + pos, buflen - pos, ", rsc_type=0x%08X (%s), rsc_id=%u; ", - cdata->msg_hdr.resource_type, name, - cdata->msg_hdr.resource_id); + res_type, name, rsc_id); for (i = 0, prev_valid = 0; i < cdata->write_idx; i++) { if (!cdata->kvp[i].valid) @@ -1034,9 +1318,9 @@ static void msm_rpm_log_request(struct msm_rpm_request *cdata) } } else if (msm_rpm_debug_mask & MSM_RPM_LOG_REQUEST_PRETTY) { /* Pretty formatting only */ - memcpy(name, &cdata->msg_hdr.resource_type, sizeof(uint32_t)); + memcpy(name, &res_type, sizeof(uint32_t)); pos += scnprintf(buf + pos, buflen - pos, " %s %u; ", name, - cdata->msg_hdr.resource_id); + rsc_id); for (i = 0, prev_valid = 0; i < cdata->write_idx; i++) { if (!cdata->kvp[i].valid) @@ -1065,9 +1349,7 @@ static void msm_rpm_log_request(struct msm_rpm_request *cdata) } else { /* Raw formatting only */ pos += scnprintf(buf + pos, buflen - pos, - ", rsc_type=0x%08X, rsc_id=%u; ", - cdata->msg_hdr.resource_type, - cdata->msg_hdr.resource_id); + ", rsc_type=0x%08X, rsc_id=%u; ", res_type, rsc_id); for (i = 0, prev_valid = 0; i < cdata->write_idx; i++) { if (!cdata->kvp[i].valid) @@ -1169,21 +1451,25 @@ static int msm_rpm_send_data(struct msm_rpm_request *cdata, int ret; uint32_t i; uint32_t msg_size; - int req_hdr_sz, msg_hdr_sz; + int msg_hdr_sz, req_hdr_sz; + uint32_t data_len = get_data_len(cdata->client_buf); + uint32_t set = get_set_type(cdata->client_buf); + uint32_t msg_id; if (probe_status) return probe_status; - if (!cdata->msg_hdr.data_len) + if (!data_len) return 1; - req_hdr_sz = sizeof(cdata->req_hdr); - msg_hdr_sz = sizeof(cdata->msg_hdr); + msg_hdr_sz = rpm_msg_fmt_ver ? sizeof(struct rpm_message_header_v1) : + sizeof(struct rpm_message_header_v0); - cdata->req_hdr.service_type = msm_rpm_request_service[msg_type]; + req_hdr_sz = RPM_HDR_SIZE; + set_msg_type(cdata->client_buf, msg_type); - cdata->req_hdr.request_len = cdata->msg_hdr.data_len + msg_hdr_sz; - msg_size = cdata->req_hdr.request_len + req_hdr_sz; + set_req_len(cdata->client_buf, data_len + msg_hdr_sz - req_hdr_sz); + msg_size = get_req_len(cdata->client_buf) + req_hdr_sz; /* populate data_len */ if (msg_size > cdata->numbytes) { @@ -1199,8 +1485,7 @@ static int msm_rpm_send_data(struct msm_rpm_request *cdata, tmpbuff = cdata->buf; - tmpbuff += req_hdr_sz + msg_hdr_sz; - + tmpbuff += msg_hdr_sz; for (i = 0; (i < cdata->write_idx); i++) { /* Sanity check */ BUG_ON((tmpbuff - cdata->buf) > cdata->numbytes); @@ -1217,22 +1502,23 @@ static int msm_rpm_send_data(struct msm_rpm_request *cdata, memcpy(tmpbuff, cdata->kvp[i].value, cdata->kvp[i].nbytes); tmpbuff += cdata->kvp[i].nbytes; - if (cdata->msg_hdr.set == MSM_RPM_CTX_SLEEP_SET) - msm_rpm_notify_sleep_chain(&cdata->msg_hdr, + if (set == MSM_RPM_CTX_SLEEP_SET) + msm_rpm_notify_sleep_chain(cdata->client_buf, &cdata->kvp[i]); } - memcpy(cdata->buf, &cdata->req_hdr, req_hdr_sz + msg_hdr_sz); - - if ((cdata->msg_hdr.set == MSM_RPM_CTX_SLEEP_SET) && + memcpy(cdata->buf, cdata->client_buf, msg_hdr_sz); + if ((set == MSM_RPM_CTX_SLEEP_SET) && !msm_rpm_smd_buffer_request(cdata, msg_size, GFP_FLAG(noirq))) return 1; - cdata->msg_hdr.msg_id = msm_rpm_get_next_msg_id(); - - memcpy(cdata->buf + req_hdr_sz, &cdata->msg_hdr, msg_hdr_sz); + msg_id = msm_rpm_get_next_msg_id(); + /* Set the version bit for new protocol */ + set_msg_ver(cdata->buf, rpm_msg_fmt_ver); + set_msg_id(cdata->buf, msg_id); + set_msg_id(cdata->client_buf, msg_id); if (msm_rpm_debug_mask & (MSM_RPM_LOG_REQUEST_PRETTY | MSM_RPM_LOG_REQUEST_RAW)) @@ -1242,30 +1528,30 @@ static int msm_rpm_send_data(struct msm_rpm_request *cdata, for (i = 0; (i < cdata->write_idx); i++) cdata->kvp[i].valid = false; - cdata->msg_hdr.data_len = 0; - ret = cdata->msg_hdr.msg_id; + set_data_len(cdata->client_buf, 0); + ret = msg_id; return ret; } if (!noack) - msm_rpm_add_wait_list(cdata->msg_hdr.msg_id); + msm_rpm_add_wait_list(msg_id); ret = msm_rpm_send_buffer(&cdata->buf[0], msg_size, noirq); if (ret == msg_size) { for (i = 0; (i < cdata->write_idx); i++) cdata->kvp[i].valid = false; - cdata->msg_hdr.data_len = 0; - ret = cdata->msg_hdr.msg_id; - trace_rpm_smd_send_active_set(cdata->msg_hdr.msg_id, - cdata->msg_hdr.resource_type, - cdata->msg_hdr.resource_id); + set_data_len(cdata->client_buf, 0); + ret = msg_id; + trace_rpm_smd_send_active_set(msg_id, + get_rsc_type(cdata->client_buf), + get_rsc_id(cdata->client_buf)); } else if (ret < msg_size) { struct msm_rpm_wait_data *rc; ret = 0; pr_err("Failed to write data msg_size:%d ret:%d msg_id:%d\n", - msg_size, ret, cdata->msg_hdr.msg_id); - rc = msm_rpm_get_entry_from_msg_id(cdata->msg_hdr.msg_id); + msg_size, ret, msg_id); + rc = msm_rpm_get_entry_from_msg_id(msg_id); if (rc) msm_rpm_free_list_entry(rc); } @@ -1801,6 +2087,8 @@ static int msm_rpm_dev_probe(struct platform_device *pdev) { char *key = NULL; int ret = 0; + void __iomem *reg_base; + uint32_t version = V0_PROTOCOL_VERSION; /* set to default v0 format */ /* * Check for standalone support @@ -1812,6 +2100,18 @@ static int msm_rpm_dev_probe(struct platform_device *pdev) goto skip_init; } + reg_base = of_iomap(pdev->dev.of_node, 0); + + if (reg_base) { + version = readq_relaxed(reg_base); + iounmap(reg_base); + } + + if (version == V1_PROTOCOL_VERSION) + rpm_msg_fmt_ver = RPM_MSG_V1_FMT; + + pr_debug("RPM-SMD running version %d/n", rpm_msg_fmt_ver); + ret = msm_rpm_dev_glink_probe(pdev); if (!ret) { pr_info("APSS-RPM communication over GLINK\n"); diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c index 123c8cd245cc..3c37f0728481 100644 --- a/drivers/thermal/msm_lmh_dcvs.c +++ b/drivers/thermal/msm_lmh_dcvs.c @@ -32,6 +32,10 @@ #include "thermal_core.h" +#define CREATE_TRACE_POINTS +#define LMH_DCVS_TRACE +#include <trace/trace_thermal.h> + #define MSM_LIMITS_DCVSH 0x10 #define MSM_LIMITS_NODE_DCVS 0x44435653 @@ -97,6 +101,7 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw) val = readl_relaxed(hw->osm_hw_reg); dcvsh_get_frequency(val, max_limit); sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit); + trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit); return max_limit; } diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 13ba52ad7b62..f9c0b6a04224 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -2360,12 +2360,11 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb, dev_dbg(mdwc->dev, "host:%ld (id:%d) event received\n", event, id); cc_state = extcon_get_cable_state_(edev, EXTCON_USB_CC); - if (cc_state < 0) { - dev_err(mdwc->dev, "%s: failed to get cc state\n", __func__); - goto done; - } - - mdwc->typec_orientation = cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1; + if (cc_state < 0) + mdwc->typec_orientation = ORIENTATION_NONE; + else + mdwc->typec_orientation = + cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1; dbg_event(0xFF, "cc_state", mdwc->typec_orientation); @@ -2398,12 +2397,11 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, return NOTIFY_DONE; cc_state = extcon_get_cable_state_(edev, EXTCON_USB_CC); - if (cc_state < 0) { - dev_err(mdwc->dev, "%s: failed to get cc state\n", __func__); - goto done; - } - - mdwc->typec_orientation = cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1; + if (cc_state < 0) + mdwc->typec_orientation = ORIENTATION_NONE; + else + mdwc->typec_orientation = + cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1; dbg_event(0xFF, "cc_state", mdwc->typec_orientation); diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index 1be93a7ca4a1..45cfc01573d9 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c @@ -136,12 +136,47 @@ static struct usb_interface_descriptor acc_interface_desc = { .bInterfaceProtocol = 0, }; +static struct usb_endpoint_descriptor acc_superspeed_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor acc_superspeed_in_comp_desc = { + .bLength = sizeof(acc_superspeed_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + +static struct usb_endpoint_descriptor acc_superspeed_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor acc_superspeed_out_comp_desc = { + .bLength = sizeof(acc_superspeed_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + + static struct usb_endpoint_descriptor acc_highspeed_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(512), }; static struct usb_endpoint_descriptor acc_highspeed_out_desc = { @@ -149,7 +184,7 @@ static struct usb_endpoint_descriptor acc_highspeed_out_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(512), }; static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { @@ -180,6 +215,15 @@ static struct usb_descriptor_header *hs_acc_descs[] = { NULL, }; +static struct usb_descriptor_header *ss_acc_descs[] = { + (struct usb_descriptor_header *) &acc_interface_desc, + (struct usb_descriptor_header *) &acc_superspeed_in_desc, + (struct usb_descriptor_header *) &acc_superspeed_in_comp_desc, + (struct usb_descriptor_header *) &acc_superspeed_out_desc, + (struct usb_descriptor_header *) &acc_superspeed_out_comp_desc, + NULL, +}; + static struct usb_string acc_string_defs[] = { [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", { }, /* end of list */ @@ -959,6 +1003,14 @@ __acc_function_bind(struct usb_configuration *c, acc_fullspeed_out_desc.bEndpointAddress; } + /* support super speed hardware */ + if (gadget_is_superspeed(c->cdev->gadget)) { + acc_superspeed_in_desc.bEndpointAddress = + acc_fullspeed_in_desc.bEndpointAddress; + acc_superspeed_out_desc.bEndpointAddress = + acc_fullspeed_out_desc.bEndpointAddress; + } + DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", f->name, dev->ep_in->name, dev->ep_out->name); @@ -1315,6 +1367,7 @@ static struct usb_function *acc_alloc(struct usb_function_instance *fi) dev->function.strings = acc_strings, dev->function.fs_descriptors = fs_acc_descs; dev->function.hs_descriptors = hs_acc_descs; + dev->function.ss_descriptors = ss_acc_descs; dev->function.bind = acc_function_bind_configfs; dev->function.unbind = acc_function_unbind; dev->function.set_alt = acc_function_set_alt; diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c index dc157efd5fc3..ee927da07e83 100644 --- a/drivers/usb/gadget/function/f_mtp.c +++ b/drivers/usb/gadget/function/f_mtp.c @@ -55,7 +55,7 @@ #define STATE_ERROR 4 /* error from completion routine */ /* number of tx and rx requests to allocate */ -#define TX_REQ_MAX 4 +#define MTP_TX_REQ_MAX 8 #define RX_REQ_MAX 2 #define INTR_REQ_MAX 5 @@ -73,6 +73,15 @@ #define MTP_RESPONSE_DEVICE_BUSY 0x2019 #define DRIVER_NAME "mtp" +unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE; +module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR); + +unsigned int mtp_tx_req_len = MTP_BULK_BUFFER_SIZE; +module_param(mtp_tx_req_len, uint, S_IRUGO | S_IWUSR); + +unsigned int mtp_tx_reqs = MTP_TX_REQ_MAX; +module_param(mtp_tx_reqs, uint, S_IRUGO | S_IWUSR); + static const char mtp_shortname[] = DRIVER_NAME "_usb"; struct mtp_dev { @@ -135,6 +144,40 @@ static struct usb_interface_descriptor ptp_interface_desc = { .bInterfaceProtocol = 1, }; +static struct usb_endpoint_descriptor mtp_superspeed_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor mtp_superspeed_in_comp_desc = { + .bLength = sizeof(mtp_superspeed_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + +static struct usb_endpoint_descriptor mtp_superspeed_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor mtp_superspeed_out_comp_desc = { + .bLength = sizeof(mtp_superspeed_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + static struct usb_endpoint_descriptor mtp_highspeed_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -174,6 +217,16 @@ static struct usb_endpoint_descriptor mtp_intr_desc = { .bInterval = 6, }; +static struct usb_ss_ep_comp_descriptor mtp_superspeed_intr_comp_desc = { + .bLength = sizeof(mtp_superspeed_intr_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 3 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ + .wBytesPerInterval = cpu_to_le16(INTR_BUFFER_SIZE), +}; + static struct usb_descriptor_header *fs_mtp_descs[] = { (struct usb_descriptor_header *) &mtp_interface_desc, (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, @@ -190,6 +243,17 @@ static struct usb_descriptor_header *hs_mtp_descs[] = { NULL, }; +static struct usb_descriptor_header *ss_mtp_descs[] = { + (struct usb_descriptor_header *) &mtp_interface_desc, + (struct usb_descriptor_header *) &mtp_superspeed_in_desc, + (struct usb_descriptor_header *) &mtp_superspeed_in_comp_desc, + (struct usb_descriptor_header *) &mtp_superspeed_out_desc, + (struct usb_descriptor_header *) &mtp_superspeed_out_comp_desc, + (struct usb_descriptor_header *) &mtp_intr_desc, + (struct usb_descriptor_header *) &mtp_superspeed_intr_comp_desc, + NULL, +}; + static struct usb_descriptor_header *fs_ptp_descs[] = { (struct usb_descriptor_header *) &ptp_interface_desc, (struct usb_descriptor_header *) &mtp_fullspeed_in_desc, @@ -206,6 +270,17 @@ static struct usb_descriptor_header *hs_ptp_descs[] = { NULL, }; +static struct usb_descriptor_header *ss_ptp_descs[] = { + (struct usb_descriptor_header *) &ptp_interface_desc, + (struct usb_descriptor_header *) &mtp_superspeed_in_desc, + (struct usb_descriptor_header *) &mtp_superspeed_in_comp_desc, + (struct usb_descriptor_header *) &mtp_superspeed_out_desc, + (struct usb_descriptor_header *) &mtp_superspeed_out_comp_desc, + (struct usb_descriptor_header *) &mtp_intr_desc, + (struct usb_descriptor_header *) &mtp_superspeed_intr_comp_desc, + NULL, +}; + static struct usb_string mtp_string_defs[] = { /* Naming interface "MTP" so libmtp will recognize us */ [INTERFACE_STRING_INDEX].s = "MTP", @@ -442,18 +517,46 @@ static int mtp_create_bulk_endpoints(struct mtp_dev *dev, ep->driver_data = dev; /* claim the endpoint */ dev->ep_intr = ep; +retry_tx_alloc: + if (mtp_tx_req_len > MTP_BULK_BUFFER_SIZE) + mtp_tx_reqs = 4; + /* now allocate requests for our endpoints */ - for (i = 0; i < TX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_in, MTP_BULK_BUFFER_SIZE); - if (!req) - goto fail; + for (i = 0; i < mtp_tx_reqs; i++) { + req = mtp_request_new(dev->ep_in, mtp_tx_req_len); + if (!req) { + if (mtp_tx_req_len <= MTP_BULK_BUFFER_SIZE) + goto fail; + while ((req = mtp_req_get(dev, &dev->tx_idle))) + mtp_request_free(req, dev->ep_in); + mtp_tx_req_len = MTP_BULK_BUFFER_SIZE; + mtp_tx_reqs = MTP_TX_REQ_MAX; + goto retry_tx_alloc; + } req->complete = mtp_complete_in; mtp_req_put(dev, &dev->tx_idle, req); } + + /* + * The RX buffer should be aligned to EP max packet for + * some controllers. At bind time, we don't know the + * operational speed. Hence assuming super speed max + * packet size. + */ + if (mtp_rx_req_len % 1024) + mtp_rx_req_len = MTP_BULK_BUFFER_SIZE; + +retry_rx_alloc: for (i = 0; i < RX_REQ_MAX; i++) { - req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE); - if (!req) - goto fail; + req = mtp_request_new(dev->ep_out, mtp_rx_req_len); + if (!req) { + if (mtp_rx_req_len <= MTP_BULK_BUFFER_SIZE) + goto fail; + for (; i > 0; i--) + mtp_request_free(dev->rx_req[i], dev->ep_out); + mtp_rx_req_len = MTP_BULK_BUFFER_SIZE; + goto retry_rx_alloc; + } req->complete = mtp_complete_out; dev->rx_req[i] = req; } @@ -478,13 +581,13 @@ static ssize_t mtp_read(struct file *fp, char __user *buf, struct mtp_dev *dev = fp->private_data; struct usb_composite_dev *cdev = dev->cdev; struct usb_request *req; - ssize_t r = count; - unsigned xfer; + ssize_t r = count, xfer, len; int ret = 0; DBG(cdev, "mtp_read(%zu)\n", count); - if (count > MTP_BULK_BUFFER_SIZE) + len = ALIGN(count, dev->ep_out->maxpacket); + if (len > mtp_rx_req_len) return -EINVAL; /* we will block until we're online */ @@ -508,7 +611,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf, requeue_req: /* queue a request */ req = dev->rx_req[0]; - req->length = count; + req->length = len; dev->rx_done = 0; ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); if (ret < 0) { @@ -519,7 +622,17 @@ requeue_req: } /* wait for a request to complete */ - ret = wait_event_interruptible(dev->read_wq, dev->rx_done); + ret = wait_event_interruptible(dev->read_wq, + dev->rx_done || dev->state != STATE_BUSY); + if (dev->state == STATE_CANCELED) { + r = -ECANCELED; + if (!dev->rx_done) + usb_ep_dequeue(dev->ep_out, req); + spin_lock_irq(&dev->lock); + dev->state = STATE_CANCELED; + spin_unlock_irq(&dev->lock); + goto done; + } if (ret < 0) { r = ret; usb_ep_dequeue(dev->ep_out, req); @@ -733,7 +846,8 @@ static void send_file_work(struct work_struct *data) ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); if (ret < 0) { DBG(cdev, "send_file_work: xfer error %d\n", ret); - dev->state = STATE_ERROR; + if (dev->state != STATE_OFFLINE) + dev->state = STATE_ERROR; r = -EIO; break; } @@ -773,6 +887,9 @@ static void receive_file_work(struct work_struct *data) count = dev->xfer_file_length; DBG(cdev, "receive_file_work(%lld)\n", count); + if (!IS_ALIGNED(count, dev->ep_out->maxpacket)) + DBG(cdev, "%s- count(%lld) not multiple of mtu(%d)\n", __func__, + count, dev->ep_out->maxpacket); while (count > 0 || write_req) { if (count > 0) { @@ -780,13 +897,15 @@ static void receive_file_work(struct work_struct *data) read_req = dev->rx_req[cur_buf]; cur_buf = (cur_buf + 1) % RX_REQ_MAX; - read_req->length = (count > MTP_BULK_BUFFER_SIZE - ? MTP_BULK_BUFFER_SIZE : count); + /* some h/w expects size to be aligned to ep's MTU */ + read_req->length = mtp_rx_req_len; + dev->rx_done = 0; ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL); if (ret < 0) { r = -EIO; - dev->state = STATE_ERROR; + if (dev->state != STATE_OFFLINE) + dev->state = STATE_ERROR; break; } } @@ -798,7 +917,8 @@ static void receive_file_work(struct work_struct *data) DBG(cdev, "vfs_write %d\n", ret); if (ret != write_req->actual) { r = -EIO; - dev->state = STATE_ERROR; + if (dev->state != STATE_OFFLINE) + dev->state = STATE_ERROR; break; } write_req = NULL; @@ -808,12 +928,18 @@ static void receive_file_work(struct work_struct *data) /* wait for our last read to complete */ ret = wait_event_interruptible(dev->read_wq, dev->rx_done || dev->state != STATE_BUSY); - if (dev->state == STATE_CANCELED) { + if (dev->state == STATE_CANCELED + || dev->state == STATE_OFFLINE) { r = -ECANCELED; if (!dev->rx_done) usb_ep_dequeue(dev->ep_out, read_req); break; } + + /* Check if we aligned the size due to MTU constraint */ + if (count < read_req->length) + read_req->actual = (read_req->actual > count ? + count : read_req->actual); /* if xfer_file_length is 0xFFFFFFFF, then we read until * we get a zero length packet */ @@ -1140,6 +1266,14 @@ mtp_function_bind(struct usb_configuration *c, struct usb_function *f) mtp_fullspeed_out_desc.bEndpointAddress; } + /* support super speed hardware */ + if (gadget_is_superspeed(c->cdev->gadget)) { + mtp_superspeed_in_desc.bEndpointAddress = + mtp_fullspeed_in_desc.bEndpointAddress; + mtp_superspeed_out_desc.bEndpointAddress = + mtp_fullspeed_out_desc.bEndpointAddress; + } + DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", f->name, dev->ep_in->name, dev->ep_out->name); @@ -1418,9 +1552,11 @@ struct usb_function *function_alloc_mtp_ptp(struct usb_function_instance *fi, if (mtp_config) { dev->function.fs_descriptors = fs_mtp_descs; dev->function.hs_descriptors = hs_mtp_descs; + dev->function.ss_descriptors = ss_mtp_descs; } else { dev->function.fs_descriptors = fs_ptp_descs; dev->function.hs_descriptors = hs_ptp_descs; + dev->function.ss_descriptors = ss_ptp_descs; } dev->function.bind = mtp_function_bind; dev->function.unbind = mtp_function_unbind; diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c index 91b91dcc7960..29d6caa8ff7b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_layer.c +++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c @@ -1421,6 +1421,17 @@ static bool __multirect_validate_format(struct mdp_input_layer **layers, if (count != 2) return false; + if ((layers[0]->flags & MDP_LAYER_SOLID_FILL) != + (layers[1]->flags & MDP_LAYER_SOLID_FILL)) { + pr_err("solid fill mismatch between multirect layers\n"); + return false; + } + /* if both are solidfill, no need for format checks */ + else if ((layers[0]->flags & MDP_LAYER_SOLID_FILL) && + (layers[1]->flags & MDP_LAYER_SOLID_FILL)) { + return true; + } + /* format related validation */ rec0_fmt = mdss_mdp_get_format_params(layers[0]->buffer.format); if (!rec0_fmt) { @@ -1458,12 +1469,6 @@ static bool __multirect_validate_format(struct mdp_input_layer **layers, return false; } - if ((layers[0]->flags & MDP_LAYER_SOLID_FILL) != - (layers[1]->flags & MDP_LAYER_SOLID_FILL)) { - pr_err("solid fill mismatch between multirect layers\n"); - return false; - } - return true; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index a2a8855ac473..e011e35ac62e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -2287,6 +2287,24 @@ static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe, return 0; } +static void __set_pipe_multirect_opmode(struct mdss_mdp_pipe *pipe) +{ + u32 multirect_opmode = 0; + /* + * enable multirect only when both RECT0 and RECT1 are enabled, + * othwerise expect to work in non-multirect only in RECT0 + */ + if (pipe->multirect.mode != MDSS_MDP_PIPE_MULTIRECT_NONE) { + multirect_opmode = BIT(0) | BIT(1); + + if (pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_SERIAL) + multirect_opmode |= BIT(2); + } + + mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_MULTI_REC_OP_MODE, + multirect_opmode); +} + static int mdss_mdp_pipe_solidfill_setup(struct mdss_mdp_pipe *pipe) { int ret; @@ -2336,6 +2354,8 @@ static int mdss_mdp_pipe_solidfill_setup(struct mdss_mdp_pipe *pipe) MDSS_MDP_REG_SSPP_SRC_OP_MODE_REC1, opmode); } + __set_pipe_multirect_opmode(pipe); + if (pipe->type != MDSS_MDP_PIPE_TYPE_DMA) { mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SCALE_CONFIG, 0); if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) @@ -2603,7 +2623,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, int ret = 0; struct mdss_mdp_ctl *ctl; u32 params_changed; - u32 opmode = 0, multirect_opmode = 0; + u32 opmode = 0; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); bool roi_changed = false; bool delayed_programming; @@ -2729,19 +2749,8 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, } } - /* - * enable multirect only when both RECT0 and RECT1 are enabled, - * othwerise expect to work in non-multirect only in RECT0 - */ - if (pipe->multirect.mode != MDSS_MDP_PIPE_MULTIRECT_NONE) { - multirect_opmode = BIT(0) | BIT(1); - - if (pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_SERIAL) - multirect_opmode |= BIT(2); - } + __set_pipe_multirect_opmode(pipe); - mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_MULTI_REC_OP_MODE, - multirect_opmode); if (src_data == NULL) { pr_debug("src_data=%p pipe num=%dx\n", src_data, pipe->num); diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-cobalt.h index bb2c7b64809a..cfbccad9f516 100644 --- a/include/dt-bindings/clock/msm-clocks-cobalt.h +++ b/include/dt-bindings/clock/msm-clocks-cobalt.h @@ -199,6 +199,7 @@ #define clk_gcc_gpu_bimc_gfx_src_clk 0x377cb748 #define clk_gcc_bimc_hmss_axi_clk 0x84653931 #define clk_gcc_gpu_cfg_ahb_clk 0x72f20a57 +#define clk_gcc_gpu_iref_clk 0xfd82abad #define clk_gcc_hmss_ahb_clk 0x62818713 #define clk_gcc_hmss_dvm_bus_clk 0x17cc8b53 #define clk_gcc_hmss_rbcpr_clk 0x699183be diff --git a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h b/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h index 52a28b5cbaf5..4175d3be68a3 100644 --- a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h +++ b/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h @@ -170,6 +170,7 @@ #define GCC_GPU_BIMC_GFX_SRC_CBCR 0x7100C #define GCC_GPU_CFG_AHB_CBCR 0x71004 #define GCC_GPU_SNOC_DVM_GFX_CBCR 0x71018 +#define GCC_GPU_IREF_EN 0x88010 #define GCC_BIMC_HMSS_AXI_CBCR 0x48004 #define GCC_HMSS_AHB_CBCR 0x48000 #define GCC_HMSS_DVM_BUS_CBCR 0x4808C diff --git a/include/trace/trace_thermal.h b/include/trace/trace_thermal.h index 0be0f47f88d2..39f3e9d08d13 100644 --- a/include/trace/trace_thermal.h +++ b/include/trace/trace_thermal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -112,6 +112,37 @@ TRACE_EVENT(lmh_debug_data, ) ); +#elif defined(LMH_DCVS_TRACE) +DECLARE_EVENT_CLASS(msm_lmh_dcvs_print, + + TP_PROTO(int cpu, long max_freq), + + TP_ARGS( + cpu, max_freq + ), + + TP_STRUCT__entry( + __field(int, cpu) + __field(long, max_freq) + ), + + TP_fast_assign( + __entry->cpu = cpu; + __entry->max_freq = max_freq; + ), + + TP_printk( + "cpu:%d max frequency:%ld", + __entry->cpu, __entry->max_freq + ) +); + +DEFINE_EVENT(msm_lmh_dcvs_print, lmh_dcvs_freq, + + TP_PROTO(int cpu, long max_freq), + + TP_ARGS(cpu, max_freq) +); #elif defined(TRACE_MSM_THERMAL) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 01b4412d08f0..eeafd4782e11 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -678,34 +678,28 @@ static inline void __free_one_page(struct page *page, unsigned long combined_idx; unsigned long uninitialized_var(buddy_idx); struct page *buddy; - unsigned int max_order = MAX_ORDER; + unsigned int max_order; + + max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1); VM_BUG_ON(!zone_is_initialized(zone)); VM_BUG_ON_PAGE(page->flags & PAGE_FLAGS_CHECK_AT_PREP, page); VM_BUG_ON(migratetype == -1); - if (is_migrate_isolate(migratetype)) { - /* - * We restrict max order of merging to prevent merge - * between freepages on isolate pageblock and normal - * pageblock. Without this, pageblock isolation - * could cause incorrect freepage accounting. - */ - max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1); - } else { + if (likely(!is_migrate_isolate(migratetype))) __mod_zone_freepage_state(zone, 1 << order, migratetype); - } - page_idx = pfn & ((1 << max_order) - 1); + page_idx = pfn & ((1 << MAX_ORDER) - 1); VM_BUG_ON_PAGE(page_idx & ((1 << order) - 1), page); VM_BUG_ON_PAGE(bad_range(zone, page), page); +continue_merging: while (order < max_order - 1) { buddy_idx = __find_buddy_index(page_idx, order); buddy = page + (buddy_idx - page_idx); if (!page_is_buddy(page, buddy, order)) - break; + goto done_merging; /* * Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page, * merge with it and move up one order. @@ -722,6 +716,33 @@ static inline void __free_one_page(struct page *page, page_idx = combined_idx; order++; } + if (max_order < MAX_ORDER) { + /* If we are here, it means order is >= pageblock_order. + * We want to prevent merge between freepages on isolate + * pageblock and normal pageblock. Without this, pageblock + * isolation could cause incorrect freepage or CMA accounting. + * + * We don't want to hit this code for the more frequent + * low-order merging. + */ + if (unlikely(has_isolate_pageblock(zone))) { + int buddy_mt; + + buddy_idx = __find_buddy_index(page_idx, order); + buddy = page + (buddy_idx - page_idx); + buddy_mt = get_pageblock_migratetype(buddy); + + if (migratetype != buddy_mt + && (is_migrate_isolate(migratetype) || + is_migrate_isolate(buddy_mt))) + goto done_merging; + } + max_order++; + goto continue_merging; + } + +done_merging: + set_page_order(page, order); /* diff --git a/net/wireless/db.txt b/net/wireless/db.txt index fa4805bb406b..1626d1553986 100644 --- a/net/wireless/db.txt +++ b/net/wireless/db.txt @@ -25,21 +25,21 @@ country AE: DFS-FCC country AF: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country AI: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country AL: DFS-ETSI (2402 - 2482 @ 40), (20) - (5150 - 5250 @ 80), (20), AUTO-BW - (5250 - 5350 @ 80), (20), DFS, AUTO-BW - (5470 - 5710 @ 160), (27), DFS + (5150 - 5250 @ 80), (23), AUTO-BW + (5250 - 5350 @ 80), (23), DFS, AUTO-BW + (5470 - 5710 @ 160), (30), DFS country AM: DFS-ETSI (2402 - 2482 @ 40), (20) @@ -48,9 +48,9 @@ country AM: DFS-ETSI country AN: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country AR: DFS-FCC (2402 - 2482 @ 40), (20) @@ -69,9 +69,9 @@ country AS: DFS-FCC country AT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -94,9 +94,9 @@ country AU: DFS-FCC country AW: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country AZ: DFS-ETSI (2402 - 2482 @ 40), (20) @@ -105,9 +105,9 @@ country AZ: DFS-ETSI country BA: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR @@ -123,9 +123,9 @@ country BD: country BE: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -147,9 +147,9 @@ country BF: DFS-FCC country BG: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -170,9 +170,9 @@ country BH: DFS-ETSI country BL: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country BM: DFS-FCC (2402 - 2472 @ 40), (30) @@ -208,15 +208,15 @@ country BS: DFS-FCC country BT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country BY: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country BZ: (2402 - 2482 @ 40), (30) @@ -239,9 +239,9 @@ country CF: DFS-FCC country CH: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -299,9 +299,9 @@ country CX: DFS-FCC country CY: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -316,13 +316,11 @@ country CY: DFS-ETSI # Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf # and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf -# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is -# implemented. country CZ: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -339,20 +337,13 @@ country CZ: DFS-ETSI # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf # For the 5GHz range also see # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf -# The values have been reduced by a factor of 2 (3db) for non TPC devices -# (in other words: devices with TPC can use twice the tx power of this table). -# Note that the docs do not require TPC for 5150--5250; the reduction to -# 100mW thus is not strictly required -- however the conservative 100mW -# limit is used here as the non-interference with radar and satellite -# apps relies on the attenuation by the building walls only in the -# absence of DFS; the neighbour countries have 100mW limit here as well. country DE: DFS-ETSI # entries 279004 and 280006 (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -367,9 +358,9 @@ country DE: DFS-ETSI country DK: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -409,9 +400,9 @@ country EC: DFS-FCC country EE: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -426,14 +417,14 @@ country EE: DFS-ETSI country EG: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 40), (20) - (5250 - 5330 @ 40), (20), DFS + (5170 - 5250 @ 20), (20) + (5250 - 5330 @ 20), (20), DFS country ES: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -448,15 +439,15 @@ country ES: DFS-ETSI country ET: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country FI: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -478,9 +469,9 @@ country FM: DFS-FCC country FR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -495,9 +486,9 @@ country FR: DFS-ETSI country GB: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -526,9 +517,9 @@ country GE: DFS-ETSI country GF: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country GH: DFS-FCC (2402 - 2482 @ 40), (20) @@ -539,21 +530,21 @@ country GH: DFS-FCC country GL: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country GP: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country GR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -568,16 +559,16 @@ country GR: DFS-ETSI country GT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country GU: DFS-FCC (2402 - 2472 @ 40), (30) - (5170 - 5250 @ 20), (24) - (5250 - 5330 @ 20), (24), DFS - (5490 - 5730 @ 20), (24), DFS - (5735 - 5835 @ 20), (30) + (5170 - 5250 @ 80), (24), AUTO-BW + (5250 - 5330 @ 80), (24), DFS, AUTO-BW + (5490 - 5730 @ 160), (24), DFS + (5735 - 5835 @ 80), (30) country GY: (2402 - 2482 @ 40), (30) @@ -599,9 +590,9 @@ country HN: DFS-FCC country HR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -623,9 +614,9 @@ country HT: DFS-FCC country HU: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -640,14 +631,14 @@ country HU: DFS-ETSI country ID: # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf - (2402 - 2482 @ 20), (30) + (2402 - 2482 @ 40), (30) (5735 - 5815 @ 20), (30) country IE: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 60 gHz band channels 1-4, ref: Etsi En 302 567 # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf @@ -678,9 +669,9 @@ country IR: country IS: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -695,9 +686,9 @@ country IS: DFS-ETSI country IT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -740,9 +731,9 @@ country KE: DFS-ETSI country KH: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country KN: DFS-ETSI (2402 - 2482 @ 40), (20) @@ -796,9 +787,9 @@ country LC: DFS-ETSI country LI: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -818,15 +809,15 @@ country LK: DFS-FCC country LS: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country LT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -841,9 +832,9 @@ country LT: DFS-ETSI country LU: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -858,9 +849,9 @@ country LU: DFS-ETSI country LV: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -880,27 +871,27 @@ country MA: DFS-ETSI country MC: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MD: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country ME: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MF: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MH: DFS-FCC (2402 - 2472 @ 40), (30) @@ -911,9 +902,9 @@ country MH: DFS-FCC country MK: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR @@ -940,21 +931,21 @@ country MP: DFS-FCC country MQ: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -982,9 +973,9 @@ country MV: DFS-ETSI country MW: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country MX: DFS-FCC (2402 - 2482 @ 40), (30) @@ -993,6 +984,13 @@ country MX: DFS-FCC (5490 - 5730 @ 160), (24), DFS (5735 - 5835 @ 80), (30) +country NA: DFS-ETSI + (2402 - 2482 @ 40), (20) + (5170 - 5250 @ 80), (20), AUTO-BW + (5250 - 5330 @ 80), (20), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS + (5735 - 5815 @ 80), (30) + country MY: DFS-FCC (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (24), AUTO-BW @@ -1014,9 +1012,9 @@ country NI: DFS-FCC country NL: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1031,9 +1029,9 @@ country NL: DFS-ETSI country NO: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1061,9 +1059,9 @@ country NZ: DFS-FCC country OM: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country PA: DFS-FCC (2402 - 2472 @ 40), (30) @@ -1080,9 +1078,9 @@ country PE: DFS-FCC country PF: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country PG: DFS-FCC (2402 - 2482 @ 40), (20) @@ -1099,14 +1097,14 @@ country PH: DFS-FCC (5735 - 5835 @ 80), (30) country PK: - (2402 - 2482 @ 40), (20) + (2402 - 2482 @ 40), (30) (5735 - 5835 @ 80), (30) country PL: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1121,9 +1119,9 @@ country PL: DFS-ETSI country PM: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country PR: DFS-FCC (2402 - 2472 @ 40), (30) @@ -1141,9 +1139,9 @@ country PS: DFS-FCC country PT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1176,15 +1174,15 @@ country QA: country RE: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country RO: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1201,9 +1199,9 @@ country RO: DFS-ETSI # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf country RS: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR @@ -1211,7 +1209,7 @@ country RU: DFS-ETSI (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (20), AUTO-BW (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5650 - 5710 @ 40), (30), DFS + (5490 - 5730 @ 160), (30), DFS (5735 - 5835 @ 80), (30) country RW: DFS-FCC @@ -1223,15 +1221,15 @@ country RW: DFS-FCC country SA: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country SE: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1253,9 +1251,9 @@ country SG: DFS-FCC country SI: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1270,9 +1268,9 @@ country SI: DFS-ETSI country SK: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 5.9ghz band # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf (5850 - 5870 @ 10), (30) @@ -1294,9 +1292,9 @@ country SN: DFS-FCC country SR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country SV: DFS-FCC (2402 - 2482 @ 40), (20) @@ -1316,15 +1314,15 @@ country TC: DFS-FCC country TD: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country TG: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 40), (20) - (5250 - 5330 @ 40), (20), DFS - (5490 - 5710 @ 40), (27), DFS + (5170 - 5250 @ 40), (23) + (5250 - 5330 @ 40), (23), DFS + (5490 - 5710 @ 40), (30), DFS country TH: DFS-FCC (2402 - 2482 @ 40), (20) @@ -1340,9 +1338,9 @@ country TN: DFS-ETSI country TR: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR @@ -1423,9 +1421,9 @@ country UZ: DFS-ETSI country VC: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country VE: DFS-FCC (2402 - 2482 @ 40), (30) @@ -1456,15 +1454,15 @@ country VU: DFS-FCC country WF: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country WS: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 40), (20) - (5250 - 5330 @ 40), (20), DFS - (5490 - 5710 @ 40), (27), DFS + (5170 - 5250 @ 40), (23) + (5250 - 5330 @ 40), (23), DFS + (5490 - 5710 @ 40), (30), DFS country XA: DFS-JP (2402 - 2482 @ 40), (20) @@ -1479,9 +1477,9 @@ country YE: country YT: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS country ZA: DFS-FCC (2402 - 2482 @ 40), (20) @@ -1492,6 +1490,6 @@ country ZA: DFS-FCC country ZW: DFS-ETSI (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS + (5170 - 5250 @ 80), (23), AUTO-BW + (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5490 - 5710 @ 160), (30), DFS diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig index 9ff235d11f8e..82d0737dfb30 100644 --- a/sound/soc/msm/Kconfig +++ b/sound/soc/msm/Kconfig @@ -100,6 +100,7 @@ config SND_SOC_MSM8996 select MSM_QDSP6V2_CODECS select SND_SOC_WCD9335 select SND_SOC_WSA881X + select SND_SOC_MSM_HDMI_CODEC_RX select DTS_SRS_TM select QTI_PP select SND_SOC_CPE |
