From 27138c983811b04533951c7ac4afd669873f62ef Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Mon, 26 Jun 2017 11:29:09 +0200 Subject: [PATCH] kernel-module-qualcomm: let udev load wireless module NetworkManager is not able to detect and manage the wireless interface until is actually created, so let udev load the kernel module and create the interface on boot. Signed-off-by: Mike Engel --- .../kernel-module-qualcomm.bb | 10 +- .../kernel-module-qualcomm/80-sdio-qcom.rules | 2 + .../kernel-module-qualcomm/qualcomm-pre-up | 114 ------------------ .../kernel-module-qualcomm/qualcomm.sh | 105 ++++++++++++++++ 4 files changed, 113 insertions(+), 118 deletions(-) create mode 100644 meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/80-sdio-qcom.rules delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm-pre-up create mode 100644 meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm.sh diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb index ef6e6e3c2..f71415430 100644 --- a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb +++ b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb @@ -17,8 +17,9 @@ SRC_URI = " \ " SRC_URI_append = " \ - file://qualcomm-pre-up \ + file://80-sdio-qcom.rules \ file://modprobe-qualcomm.conf \ + file://qualcomm.sh \ " S = "${WORKDIR}/git" @@ -38,18 +39,19 @@ do_compile_prepend() { } do_install_append() { - install -d ${D}${sysconfdir}/network/if-pre-up.d - install -m 0755 ${WORKDIR}/qualcomm-pre-up ${D}${sysconfdir}/network/if-pre-up.d/qualcomm install -d ${D}${sysconfdir}/modprobe.d install -m 0644 ${WORKDIR}/modprobe-qualcomm.conf ${D}${sysconfdir}/modprobe.d/qualcomm.conf install -d ${D}${base_libdir}/firmware/wlan/ install -m 0644 ${WORKDIR}/git/firmware_bin/WCNSS_cfg.dat ${D}${base_libdir}/firmware/wlan/cfg.dat install -m 0644 ${WORKDIR}/git/firmware_bin/WCNSS_qcom_cfg.ini ${D}${base_libdir}/firmware/wlan/qcom_cfg.ini + install -d ${D}${sysconfdir}/udev/rules.d ${D}${sysconfdir}/udev/scripts + install -m 0644 ${WORKDIR}/80-sdio-qcom.rules ${D}${sysconfdir}/udev/rules.d/ + install -m 0755 ${WORKDIR}/qualcomm.sh ${D}${sysconfdir}/udev/scripts/ } FILES_${PN} += " \ - ${sysconfdir}/network/if-pre-up.d/qualcomm \ ${sysconfdir}/modprobe.d/qualcomm.conf \ + ${sysconfdir}/udev/ \ ${base_libdir}/firmware/wlan/cfg.dat \ ${base_libdir}/firmware/wlan/qcom_cfg.ini \ " diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/80-sdio-qcom.rules b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/80-sdio-qcom.rules new file mode 100644 index 000000000..1eb47fabd --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/80-sdio-qcom.rules @@ -0,0 +1,2 @@ +# Load Qualcomm wireless module +SUBSYSTEM=="sdio", ACTION=="add", ENV{MODALIAS}=="sdio:c00v0271d050A" RUN+="/etc/udev/scripts/qualcomm.sh" diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm-pre-up b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm-pre-up deleted file mode 100644 index 3c1cccdeb..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm-pre-up +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/sh -#=============================================================================== -# -# qualcomm-pre-up -# -# Copyright (C) 2016 by Digi International Inc. -# 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 as published by -# the Free Software Foundation. -# -# -# !Description: Load Qualcomm' wireless driver -# -#=============================================================================== - -[ "${IFACE}" != "wlan0" ] && [ "${IFACE}" != "p2p0" ] && exit 0 - -# If the qualcomm driver is already loaded exit -grep -qws 'wlan' /proc/modules && exit 0 - -FIRMWARE_DIR="/lib/firmware" -MACFILE="${FIRMWARE_DIR}/wlan/wlan_mac.bin" -TMP_MACFILE="$(mktemp -t wlan_mac.XXXXXX)" - -# Read the MACs from DeviceTree. We can have up to four wireless interfaces -# The only required one is wlan0 that is mapped with device tree mac address -# without suffix. -for index in $(seq 0 3); do - DT_WLANx_MAC="/proc/device-tree/wireless/mac-address" - if [ "${index}" = "0" ]; then - # Set a default MAC for wlan0 - MAC_ADDR="00:04:F3:FF:FF:FB" - else - # Add the interface suffix for the device tree node - DT_WLANx_MAC=${DT_WLANx_MAC}${index} - MAC_ADDR="" - fi - - if [ -f "${DT_WLANx_MAC}" ]; then - MAC_ADDR="$(hexdump -ve '1/1 "%02X" ":"' ${DT_WLANx_MAC} | sed 's/:$//g')" - fi - - # Dump the MAC address in a file with the expected firmware format. - # example: Intf0MacAddress=0004f3fffffb - echo "Intf${index}MacAddress=${MAC_ADDR}" | sed s/://g >> ${TMP_MACFILE} -done - -# Override the MAC firmware file only if the MAC file has changed. -if ! cmp -s ${TMP_MACFILE} ${MACFILE}; then - cp ${TMP_MACFILE} ${MACFILE} -fi -rm -f ${TMP_MACFILE} - -OTP_REGION_CODE="$(cat /proc/device-tree/digi,hwid,cert 2>/dev/null)" -DTB_REGION_CODE="$(cat /proc/device-tree/wireless/regulatory-domain 2>/dev/null)" -US_CODE="0x0" -WW_CODE="0x1" -JP_CODE="0x2" -# Check if the DTB_REGION_CODE is in the list of valid codes, -# if not use the OTP programmed value. -case "${DTB_REGION_CODE}" in - ${US_CODE}|${WW_CODE}|${JP_CODE}) - REGULATORY_DOMAIN=${DTB_REGION_CODE};; - *) - if [ -n "${DTB_REGION_CODE}" ]; then - logger -t qca6564 "[ERROR] Invalid region code in device tree, using OTP value" - fi - REGULATORY_DOMAIN=${OTP_REGION_CODE};; -esac - -BDATA_LINK="${FIRMWARE_DIR}/bdwlan30.bin" -UTFBDATA_LINK="${FIRMWARE_DIR}/utfbd30.bin" -# Create a symbolic links to the FW files for the specific country region. -BDATA_SOURCE="${FIRMWARE_DIR}/bdwlan30_US.bin" -case "${REGULATORY_DOMAIN}" in - ${US_CODE}) - logger -t qca6564 "Setting US wireless region";; - ${WW_CODE}|${JP_CODE}) - if [ -e "${FIRMWARE_DIR}/bdwlan30_World.bin" ]; then - logger -t qca6564 "Setting WW (world wide) wireless region" - BDATA_SOURCE="${FIRMWARE_DIR}/bdwlan30_World.bin" - else - logger -t qca6564 "[WARN] No WW (worldwide) board data file, using US" - fi - ;; - "") - logger -t qca6564 "[WARN] region code not found, using US";; - *) - logger -t qca6564 "[WARN] Invalid region code, using US";; -esac - -# We don't want to rewrite NAND every time we boot so only -# change the links if they are wrong. -if [ ! -e "${BDATA_LINK}" ] || ! cmp -s "${BDATA_LINK}" "${BDATA_SOURCE}"; then - ln -sf "${BDATA_SOURCE}" "${BDATA_LINK}" - ln -sf "${BDATA_SOURCE}" "${UTFBDATA_LINK}" -fi - -# Check the version of modprobe installed to compound the arguments. -if readlink -f $(which modprobe) | grep -qs kmod; then - MODPROBE_ARGS="-i" -fi -# Load the wireless module with the params defined in modprobe.d/qualcomm.conf -modprobe ${MODPROBE_ARGS} wlan - -# Validate that firmware was loaded by checking if the interface is present. -if [ -d "/sys/class/net/${IFACE}" ]; then - echo "Loading qca6564 module: [OK]" -else - echo "Loading qca6564 module: [FAILED]" - exit 1 -fi diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm.sh b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm.sh new file mode 100644 index 000000000..d387bc667 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm/qualcomm.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# +# Copyright (c) 2017, Digi International Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# Do nothing if the module is already loaded +grep -qws 'wlan' /proc/modules && exit 0 + +FIRMWARE_DIR="/lib/firmware" +MACFILE="${FIRMWARE_DIR}/wlan/wlan_mac.bin" +TMP_MACFILE="$(mktemp -t wlan_mac.XXXXXX)" + +# Read the MACs from DeviceTree. We can have up to four wireless interfaces +# The only required one is wlan0 that is mapped with device tree mac address +# without suffix. +for index in $(seq 0 3); do + MAC_ADDR="$(hexdump -ve '1/1 "%02X"' /proc/device-tree/wireless/mac-address${index%0} 2>/dev/null)" + if [ "${index}" = "0" ] && { [ -z "${MAC_ADDR}" ] || [ "${MAC_ADDR}" = "00:00:00:00:00:00" ]; }; then + # Set a default MAC for wlan0 + MAC_ADDR="0004F3FFFFFB" + fi + + # Add the MAC address to the firmware file with the expected format + echo "Intf${index}MacAddress=${MAC_ADDR}" >> ${TMP_MACFILE} +done + +# Override the MAC firmware file only if the MAC file has changed. +if ! cmp -s ${TMP_MACFILE} ${MACFILE}; then + cp ${TMP_MACFILE} ${MACFILE} +fi +rm -f "${TMP_MACFILE}" + +OTP_REGION_CODE="$(cat /proc/device-tree/digi,hwid,cert 2>/dev/null)" +DTB_REGION_CODE="$(cat /proc/device-tree/wireless/regulatory-domain 2>/dev/null)" +US_CODE="0x0" +WW_CODE="0x1" +JP_CODE="0x2" +# Check if the DTB_REGION_CODE is in the list of valid codes, +# if not use the OTP programmed value. +case "${DTB_REGION_CODE}" in + ${US_CODE} | ${WW_CODE} | ${JP_CODE}) + REGULATORY_DOMAIN="${DTB_REGION_CODE}";; + *) + if [ -n "${DTB_REGION_CODE}" ]; then + logger -t qca6564 "[WARN] Invalid region code in device tree, using OTP value" + fi + REGULATORY_DOMAIN="${OTP_REGION_CODE}";; +esac + + +# Create symbolic links to the proper FW files depending on the country region +# Use a sub-shell here to change to firmware directory +( + cd "${FIRMWARE_DIR}" + + BDATA_SOURCE="bdwlan30_US.bin" + case "${REGULATORY_DOMAIN}" in + ${US_CODE}) + logger -t qca6564 "Setting US wireless region";; + ${WW_CODE}|${JP_CODE}) + if [ -f "bdwlan30_World.bin" ]; then + logger -t qca6564 "Setting WW (world wide) wireless region" + BDATA_SOURCE="bdwlan30_World.bin" + else + logger -t qca6564 "[WARN] No WW (worldwide) board data file, using US" + fi + ;; + "") + logger -t qca6564 "[WARN] region code not found, using US";; + *) + logger -t qca6564 "[WARN] Invalid region code, using US";; + esac + + # We don't want to rewrite NAND every time we boot so only + # change the links if they are wrong. + BDATA_LINK="bdwlan30.bin" + UTFBDATA_LINK="utfbd30.bin" + if [ ! -e "${BDATA_LINK}" ] || ! cmp -s "${BDATA_LINK}" "${BDATA_SOURCE}"; then + ln -sf "${BDATA_SOURCE}" "${BDATA_LINK}" + ln -sf "${BDATA_SOURCE}" "${UTFBDATA_LINK}" + fi +) + +# Check the version of modprobe installed to compound the arguments. +if readlink -f $(which modprobe) | grep -qs kmod; then + MODPROBE_ARGS="-i" +fi + +# Load the wireless module with the params defined in modprobe.d/qualcomm.conf +modprobe ${MODPROBE_ARGS} wlan + +# Verify the interface is present +[ -d "/sys/class/net/wlan0" ] || logger -t qca6564 "[ERROR] Loading qca6564 module"