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 <Mike.Engel@digi.com>
This commit is contained in:
Mike Engel 2017-06-26 11:29:09 +02:00 committed by Javier Viguera
parent 308cb251d3
commit 27138c9838
4 changed files with 113 additions and 118 deletions

View File

@ -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 \
"

View File

@ -0,0 +1,2 @@
# Load Qualcomm wireless module
SUBSYSTEM=="sdio", ACTION=="add", ENV{MODALIAS}=="sdio:c00v0271d050A" RUN+="/etc/udev/scripts/qualcomm.sh"

View File

@ -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

View File

@ -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"