ipq806x: add quantenna wireless firmware for E8350/R7500v1

This commit is contained in:
coolsnowwolf 2021-07-22 14:11:47 +08:00
parent cda8c08d33
commit 54d5790ab6
12 changed files with 885 additions and 0 deletions

View File

@ -0,0 +1,53 @@
# Known Quantenna firmware bugs #
This is an attempt to document Quantenna firmware bugs, explaining strange
implemtation details in this OpenWrt package and also hopefully helping
anyone else trying to get this mess to work...
## Quantenna switch and VLANs ##
Mapping WiFi VIFs to VLANs has a horrible side effect: Traffic from the
Quantenna SoC, like the RPC responses, is tagged with the last used VLAN.
The tag depends on Wireless client activity! I.e it is unpredictable.
And even if it were predictable: The module does not accept tagged RPC
calls or other management traffic. The RPC requests must be sent
untagged even if the module responds with an arbitrary tag...
The switch state is not reset on either Quantenna module reboot by RPC
call, or reset by GPIO. The VLAN issue affects the bootloader,
making the module fail to load the second stage bootloader and OS over
tftp because of the VLAN tag mismatch.
Full power cycling is necessary to reset the Quantenna switch to
non-tagging. There is no known software controllable reset method.
### Workaround ###
Playing with static and gratuitous ARPs, in combination with VLAN
interfaces accepting local traffic works pretty well.
But this does not solve the reboot issue, caused by the switch bug
being persistent over reset. The two U-Boot stages will switch mac
addresses up to 3 times during module reboot. The final address is
often dynamically allocated, changing for each boot. This makes it
hard to manage a static ARP entry.
Using "tc" to pop the VLAN tag of any tagged IP and ARP packets for
our management address works perfectly.
## Using bootloader environment ##
The Quantenna bootloader environment is ignored by the firmware unless
/scripts/build_config contains STATELESS=Y. This is a build time
setting, which is not set by the Netgear firmware we use.
The implications is that the module will use different mac adresses
etc compared to an OEM firmware with STATELESS=Y.
This should not be considered a bug, but is an issue caused by our
choice of a common Quantenna firmware image for all hosts with such a
module.

View File

@ -0,0 +1,155 @@
#
# Copyright (C) 2020 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=quantenna
PKG_VERSION:=37.3.2.44
PKG_RELEASE:=1
PKG_MAINTAINER:=Bjørn Mork <bjorn@mork.no>
# available versions, ref https://kb.netgear.com/2649/NETGEAR-Open-Source-Code-for-Programmers-GPL
# qtn sdk v36.6.0.23: 1.0.0.46,
# qtn sdk v36.6.0.28: 1.0.0.52,
# qtn sdk v36.6.0.30: 1.0.0.68, 1.0.0.70,
# qtn sdk v36.7.3.23: 1.0.0.76, 1.0.0.82,
# qtn sdk v37.3.1.25: 1.0.0.94, 1.0.0.108, 1.0.0.110 , 1.0.0.112, 1.0.0.116, 1.0.0.122,
# qtn sdk v37.3.2.44: 1.0.0.124
NETGEAR_R7500V1_SRC-37.3.2.44=R7500-and_qtn_gpl_src_v1.0.0.124.tar.bz2.zip
NETGEAR_R7500V1_HASH-37.3.2.44=6592e3286c66a8b0ba689e6cff2d10cac5aea3ddef8ca8746d7771319e47112e
PKG_SOURCE:=$(NETGEAR_R7500V1_SRC-$(strip $(PKG_VERSION)))
PKG_SOURCE_URL:=https://www.downloads.netgear.com/files/GPL
PKG_HASH:=$(NETGEAR_R7500V1_HASH-$(strip $(PKG_VERSION)))
QCSAPI_ARCHIVE-37.3.2.44=quantenna_gpl_v$(PKG_VERSION).tar.bz2
UNPACK_CMD-37.3.2.44=unzip -q -p $(DL_DIR)/$(PKG_SOURCE) | bzcat | $(HOST_TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
UNPACK_CMD=$(UNPACK_CMD-$(strip $(PKG_VERSION)))
PKG_BUILD_DEPENDS:=libtirpc
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define Build/Prepare
$(PKG_UNPACK)
bzcat $(PKG_BUILD_DIR)/$(QCSAPI_ARCHIVE-$(strip $(PKG_VERSION))) | \
$(HOST_TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) --strip-components=1 \
--wildcards */libqcsapi_client_src.zip --wildcards *drivers/pcie2*
bzcat $(PKG_BUILD_DIR)/R7500-*.tar.bz2 | \
$(HOST_TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) --strip-components=4 \
--wildcards */package/qt-wireless/binary/{topaz-linux.lzma.img,u-boot.bin}
unzip -q -d $(PKG_BUILD_DIR) $(PKG_BUILD_DIR)/libqcsapi_client_src.zip
# tunning to make the same patch apply to versions with or without -fstrict-aliasing
sed -i -e 's/ -fstrict-aliasing//' $(PKG_BUILD_DIR)/Makefile
$(Build/Patch)
endef
define Package/qtn-utils
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Quantenna QV840 (QTS1000) Utilities
DEPENDS:=+libtirpc +tc +kmod-sched-act-vlan
endef
define Package/qtn-utils/description
Management tools for Quantenna QV840 (QTS1000) WiFi modules
endef
TARGET_CFLAGS += $(FPIC) -I$(STAGING_DIR)/usr/include/tirpc
TARGET_LDFLAGS += -ltirpc
define Build/Compile
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS) qcsapi_sockrpc
ifdef CONFIG_PACKAGE_kmod-qtn-pcie2
$(call Build/Compile/qtn-pcie2)
endif
endef
define Package/qtn-utils/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/etc/init.d
$(CP) $(PKG_BUILD_DIR)/libqcsapi_client.so* $(1)/usr/lib/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/qcsapi_sockrpc $(1)/usr/sbin/
ln -s /tmp/qcsapi_target_ip.conf $(1)/etc
$(INSTALL_BIN) ./files/qtn-utils.init $(1)/etc/init.d/qtn-utils
endef
define Package/qtn-firmware
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Quantenna QV840 (QTS1000) firmware
DEPENDS:=+dnsmasq
endef
define Package/qtn-firmware/description
Firmware for Quantenna QV840 (QTS1000) WiFi modules
endef
define Package/qtn-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/qtn
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/u-boot.bin \
$(PKG_BUILD_DIR)/topaz-linux.lzma.img \
$(1)/lib/firmware/qtn
ln -s u-boot.bin $(1)/lib/firmware/qtn/uboot_qsr1000.img
ln -s topaz-linux.lzma.img $(1)/lib/firmware/qtn/fmac_qsr1000.img
cd $(1)/lib/firmware && ln -s qtn/u-boot.bin . && ln -s qtn/topaz-linux.lzma.img .
$(INSTALL_BIN) ./files/qtn-firmware.defaults $(1)/etc/uci-defaults
endef
define Package/qtn-proto
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Quantenna QV840 (QTS1000) netifd support
DEPENDS:=+qtn-utils
endef
define Package/qtn-proto/install
echo "######################################### QTN-PROTO INSTALL #####################################"
$(INSTALL_DIR) $(1)/lib/wifi
$(INSTALL_DIR) $(1)/lib/netifd
$(INSTALL_DIR) $(1)/lib/netifd/wireless
$(INSTALL_BIN) ./files/lib/wifi/quantenna.sh $(1)/lib/wifi
$(INSTALL_BIN) ./files/lib/netifd/quantenna.sh $(1)/lib/netifd
$(INSTALL_BIN) ./files/lib/netifd/wireless/quantenna.sh $(1)/lib/netifd/wireless
endef
define KernelPackage/qtn-pcie2
SECTION:=kernel
SUBMENU:=Wireless Drivers
TITLE:=Quantenna QV840 (QTS1000) pcie2 driver
DEPENDS:=+qtn-utils
FILES:=$(PKG_BUILD_DIR)/drivers/pcie2/host/arm/qdpc-host.ko
AUTOLOAD:=$(call AutoProbe,qdpc-host)
endef
define KernelPackage/qtn-pcie2/description
Quantenna QV840 (QTS1000) WiFi modules PCIE2 driver
endef
define Build/Compile/qtn-pcie2
echo "######################################### PCIE2 DRIVER BUILD #####################################"
cd $(PKG_BUILD_DIR)/drivers/pcie2/host/arm
+$(MAKE) $(CT_MAKEDEFS) $(PKG_JOBS) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)/drivers/pcie2/host/arm" \
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
modules
endef
$(eval $(call BuildPackage,qtn-utils))
$(eval $(call BuildPackage,qtn-firmware))
$(eval $(call BuildPackage,qtn-proto))
$(eval $(call KernelPackage,qtn-pcie2))

View File

@ -0,0 +1,31 @@
QUANTENNA_TARGET_IP=""
QUANTENNA_FW_VER=""
QUANTENNA_PRIMARY=""
quantenna_target_ip() {
echo "$QUANTENNA_TARGET_IP"
}
quantenna_device() {
[ -n "$QUANTENNA_TARGET_IP" ] && ip route get "$QUANTENNA_TARGET_IP" 2>/dev/null | sed -e 's,.* dev ,,' -e 's, .*,,' | tr -d \\n
}
quantenna_fw_ver() {
echo "$QUANTENNA_FW_VER"
}
quantenna_api_ver() {
echo "$QUANTENNA_FW_VER" | cut -d. -f1
}
quantenna_primaryif() {
echo "$QUANTENNA_PRIMARY"
}
quantenna_ifprefix() {
echo "${QUANTENNA_PRIMARY%0}"
}
# This depends on a configured qtn-utils package
[ -z "$QUANTENNA_TARGET_IP" ] && [ -r "/etc/qcsapi_target_ip.conf" ] && [ -x "$(which qcsapi_sockrpc)" ] && QUANTENNA_TARGET_IP=$(cat /etc/qcsapi_target_ip.conf)
[ -n "$QUANTENNA_TARGET_IP" ] && [ -z "$QUANTENNA_FW_VER" ] && QUANTENNA_FW_VER=$(qcsapi_sockrpc get_firmware_version)
[ -n "$QUANTENNA_TARGET_IP" ] && [ -z "$QUANTENNA_PRIMARY" ] && QUANTENNA_PRIMARY=$(qcsapi_sockrpc get_primary_interface)

View File

@ -0,0 +1,328 @@
#!/bin/sh
. /lib/netifd/netifd-wireless.sh
. /lib/netifd/quantenna.sh
init_wireless_driver "$@"
# primarily to allow RPC API call debugging
quantenna_call() {
logger "Calling qcsapi_sockrpc" $*
qcsapi_sockrpc $*
}
quantenna_rfenable() {
local enable=$1
# compat: fw v36 req "wifi0" arg, v37 (and later?) does not
case "$(quantenna_api_ver)" in
v36)
quantenna_call rfenable $(quantenna_primaryif) $enable
;;
*)
quantenna_call rfenable $enable
;;
esac
}
quantenna_rfstatus() {
# compat: fw v36 req "wifi0" arg, v37 (and later?) does not
case "$(quantenna_api_ver)" in
v36)
quantenna_call rfstatus $(quantenna_primaryif)
;;
*)
quantenna_call rfstatus
;;
esac
}
# mostly harmless if already done
quantenna_ready() {
[ -n "$(quantenna_ifprefix)" ] || return 1
[ "$(quantenna_call startprod)" = "complete" ] || return 1
[ "$(quantenna_call is_startprod_done)" = "1" ] || return 1
[ "$(quantenna_rfstatus)" = "On" ] || [ "$(quantenna_rfenable 1)" = "complete" ] || return 1
return 0
}
quantenna_set_security_mode() {
local ifname=$1
[ "$(quantenna_call apply_security_config $ifname)" = "complete" ] || return 1
return 0
}
quantenna_set_ssid_hidden() {
local ifname=$1
local hidden=${2:-0}
local enable=1
[ $hidden -gt 0 ] && enable=0
[ "$(quantenna_call set_option $ifname SSID_broadcast $enable)" = "complete" ] || return 1
return 0
}
quantenna_interface_enable() {
local ifname=$1
local enable=${2:-0}
local updown=down
[ $enable -gt 0 ] && updown=up
ip link set $ifname $updown
[ "$(quantenna_call enable_interface $ifname $enable)" = "complete" ] || return 1
return 0
}
_ifname2vid() {
echo "$((${1#$(quantenna_ifprefix)}+10))"
}
quantenna_interface_add() {
local ifname="$1"
local type="$2"
local phy="$3"
local vid=$(_ifname2vid $ifname)
# maximum number of devs is 8
[ $vid -lt 18 ] || return
case "$type" in
ap)
[ "$ifname" = "$(quantenna_primaryif)" ] || [ "$(quantenna_call wifi_create_bss $ifname)" = "complete" ] || echo "failed to create $ifname"
quantenna_set_security_mode $ifname || return 1
[ "$(quantenna_call set_pmf $ifname 0)" = "complete" ] || return 1
;;
*)
echo "$ifname: unsupported interface type '$type'"
return
;;
esac
# host local vlan dev
ip link add link $phy name $ifname type vlan id $vid
# bind quantenna vif to vlan
[ "$(quantenna_call vlan_config $ifname enable $vid)" = "complete" ] || return 1
[ "$(quantenna_call vlan_config $ifname bind $vid)" = "complete" ] || return 1
# disable interface until configured
quantenna_interface_enable $ifname 0
}
quantenna_interface_del() {
local ifname="$1"
local type="$2"
local vid=$(_ifname2vid $ifname)
quantenna_call vlan_config $ifname unbind $vid
quantenna_call vlan_config $ifname disable $vid
quantenna_interface_enable $ifname 0
case "$type" in
ap)
[ "$ifname" = "$(quantenna_primaryif)" ] || quantenna_call wifi_remove_bss $ifname
;;
*)
echo "$ifname: unsupported interface type '$type'"
return
;;
esac
ip link del $ifname
}
quantenna_set_ssid() {
local ifname=$1
local ssid=$2
quantenna_call set_SSID $ifname $ssid
}
quantenna_set_macaddr() {
local ifname=$1
local mac=$2
quantenna_call set_macaddr $ifname "$mac"
}
quantenna_set_encr() {
local ifname=$1
local encr=$2
quantenna_call set_WPA_encryption_modes $ifname "$encr"
}
quantenna_set_auth() {
local ifname=$1
local auth=$2
quantenna_call set_WPA_authentication_mode $ifname "$auth"
}
quantenna_set_key() {
local ifname=$1
local key=$2
quantenna_call set_passphrase $ifname 0 "$key"
}
quantenna_set_beacon() {
local ifname=$1
local type=$2
quantenna_call set_beacon $ifname "$type"
}
# This will not work with hairpin_mode enabled
quantenna_fixup_vif() {
echo "quantenna_fixup_vif: $(json_dump)"
json_select data
json_get_vars ifname
json_select ..
[ -r "/sys/class/net/$ifname/brport/hairpin_mode" ] && echo 0 > "/sys/class/net/$ifname/brport/hairpin_mode"
}
quantenna_setup_vif() {
local name="$1"
echo "quantenna_setup_vif: $(json_dump)"
json_select config
json_get_vars mode ssid macaddr enable key hidden
json_select ..
# FIXME - mac addresses for VAPs will be auto-generated by Quantenna firmware - we need only managed the first one...
# [ -n "$macaddr" ] || {
# macaddr="$(mac80211_generate_mac $phy)"
# macidx="$(($macidx + 1))"
# }
if_idx=$((${if_idx:--1} + 1))
local ifname="$(quantenna_ifprefix)${if_idx}"
set_default enable 1
json_add_object data
json_add_string ifname "$ifname"
json_close_object
json_select config
wireless_vif_parse_encryption
json_select ..
quantenna_interface_add "$ifname" "$mode" "$phy" || return
quantenna_set_ssid_hidden $ifname "$hidden"
case "$auth_type" in
none)
quantenna_set_beacon $ifname Basic
;;
psk)
quantenna_set_auth $ifname PSKAuthentication
;;
*)
echo "unsupported auth_type: $auth_type"
;;
esac
case "$wpa_cipher" in
"TKIP")
quantenna_set_beacon $ifname WPA
quantenna_set_encr $ifname TKIPEncryption
;;
"CCMP")
quantenna_set_beacon $ifname 11i
quantenna_set_encr $ifname AESEncryption
;;
"CCMP TKIP")
quantenna_set_beacon $ifname WPAand11i
quantenna_set_encr $ifname TKIPandAESEncryption
;;
*)
;;
esac
[ -n "$key" ] && quantenna_set_key $ifname "$key"
quantenna_set_ssid $ifname "$ssid"
[ -n "$macaddr" ] && quantenna_set_macaddr $ifname "$macaddr"
quantenna_interface_enable $ifname $enable
wireless_add_vif "$name" "$ifname"
}
quantenna_cleanup_vif() {
local name="$1"
echo "quantenna_cleanup_vif ($name): $(json_dump)"
json_select config
json_get_vars mode
json_select ..
json_select data
json_get_vars ifname
json_select ..
quantenna_interface_del $ifname $mode
}
# will be evaled after _wdev_common_device_config(), which adds
# config_add_string channel hwmode htmode noscan
drv_quantenna_init_device_config() {
config_add_string phy
config_add_int beacon_int
echo "drv_quantenna_init_device_config"
}
# will be evaled after _wdev_common_iface_config(), which adds
# config_add_string mode ssid encryption 'key:wpakey'
drv_quantenna_init_iface_config() {
config_add_boolean enable hidden
echo "drv_quantenna_init_iface_config"
}
drv_quantenna_setup() {
json_select config
echo "drv_quantenna_setup: $(json_dump)"
json_get_vars phy channel htmode beacon_int
json_select ..
[ "$(quantenna_device)" = "$phy" ] || {
echo "Could not find PHY for device '$1'"
wireless_set_retry 0
return 1
}
quantenna_ready || {
echo "Failed to connect to Quantenna module"
wireless_set_retry 1
return 1
}
quantenna_call set_channel $(quantenna_primaryif) $channel
case "$htmode" in
VHT20|HT20)
quantenna_call set_bw $(quantenna_primaryif) 20
;;
HT40*|VHT40)
quantenna_call set_bw $(quantenna_primaryif) 40
;;
VHT80)
quantenna_call set_bw $(quantenna_primaryif) 80
;;
*)
quantenna_call set_bw $(quantenna_primaryif) 40
;;
esac
[ -n "beacon_int" ] && quantenna_call set_beacon_interval $(quantenna_primaryif) $beacon_int
# FIMXE: support all modes: ap, sta, adhoc, wds, monitor, mesh
for_each_interface "ap" quantenna_setup_vif
wireless_set_up
for_each_interface "ap" quantenna_fixup_vif
}
drv_quantenna_teardown() {
echo "$drv_quantenna_teardown: $(json_dump)"
for_each_interface "ap" quantenna_cleanup_vif
quantenna_rfenable 0
}
add_driver quantenna

View File

@ -0,0 +1,39 @@
#!/bin/sh
. /lib/netifd/quantenna.sh
append DRIVERS "quantenna"
detect_quantenna() {
devidx=0
config_load wireless
while :; do
config_get type "radio$devidx" type
[ -n "$type" ] || break
# the qcsapi does not support more than one module in a system
[ "$type" = "quantenna" ] && return
devidx=$(($devidx + 1))
done
# find "all" - i.e. then single supported - Quantenna devices.
# there is no reliable way to do this, as it can be virtually
# any ethernet device
phy=$(quantenna_device)
[ -z "$phy" ] && return
uci -q batch <<-EOF
set wireless.radio${devidx}=wifi-device
set wireless.radio${devidx}.type=quantenna
set wireless.radio${devidx}.channel=${channel:-36}
set wireless.radio${devidx}.hwmode=11ac
set wireless.radio${devidx}.phy=${phy}
set wireless.radio${devidx}.disabled=1
set wireless.default_radio${devidx}=wifi-iface
set wireless.default_radio${devidx}.device=radio${devidx}
set wireless.default_radio${devidx}.network=lan
set wireless.default_radio${devidx}.mode=ap
set wireless.default_radio${devidx}.ssid=OpenWrt
set wireless.default_radio${devidx}.encryption=none
EOF
uci -q commit wireless
}

View File

@ -0,0 +1,16 @@
#!/bin/sh
# no need for tftp service if the Quantenna module is PCIe connected
[ "$(basename "$(readlink /sys/class/net/$(uci -q get network.qtn.ifname)/device/driver)")" = "qtnfmac_pcie" ] && exit 0
uci -q get dhcp.qtn_rgmii >/dev/null && exit 0
touch /etc/config/dhcp
uci batch <<EOF
set dhcp.qtn_rgmii=dnsmasq
set dhcp.qtn_rgmii.enable_tftp=1
set dhcp.qtn_rgmii.tftp_root=/lib/firmware/qtn
set dhcp.qtn_rgmii.interface='qtn'
set dhcp.qtn_rgmii.port=0
commit dhcp
EOF

View File

@ -0,0 +1,37 @@
#!/bin/sh /etc/rc.common
NAME=qtn-utils
# must start before networking
START=19
USE_PROCD=1
start_service() {
local ifname=$(uci get network.qtn.ifname)
local ipaddr=$(uci get network.qtn.ipaddr)
local hex_ip=$(printf "0x%02x%02x%02x%02x" $(echo $ipaddr | tr . \ ))
eval "$(ipcalc.sh $ipaddr $(uci get network.qtn.netmask) 2)"
echo "$START" >/tmp/qcsapi_target_ip.conf
# work around Quatenna vlan bug - pop bogus tags from arp and ip packets for 1.1.1.1
tc qdisc add dev $ifname handle ffff: ingress
tc filter add dev $ifname parent ffff: pref 1 \
protocol 802.1q u32 \
match u16 0x0806 0xffff at -2 \
match u32 $hex_ip 0xffffffff at 24 \
action vlan pop
tc filter add dev $ifname parent ffff: pref 2 \
protocol 802.1q u32 \
match u16 0x0800 0xffff at -2 \
match u32 $hex_ip 0xffffffff at 16 \
action vlan pop
}
stop_service() {
local ifname=$(uci get network.qtn.ifname)
tc filter del dev $ifname ingress
tc qdisc del dev $ifname ingress
}

View File

@ -0,0 +1,40 @@
--- a/Makefile 2019-06-24 17:38:56.000000000 +0200
+++ b/Makefile 2019-06-24 17:39:04.000000000 +0200
@@ -1,6 +1,5 @@
-CC = gcc
-CFLAGS = -I. -fPIC -O -g -Wall -Werror -Wno-unused-variable -Wno-unused-parameter
+CFLAGS += -I.
COMMON_PROG_OBJS = \
call_qcsapi.o \
@@ -49,24 +48,25 @@
LIB_LDNAME = lib$(LIB_NAME).so
LIB_SONAME = $(LIB_LDNAME).1
LIB_REALNAME = $(LIB_LDNAME).1.0.1
+LDFLAGS += -L. -l$(LIB_NAME)
c_rpc_qcsapi_sample: ${SOCKET_C_SAMPLE_OBJS:%=build/%} $(LIB_REALNAME)
- ${CC} $(filter %.o, $^) -L. -l$(LIB_NAME) -o $@
+ ${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_pcie: ${PCIE_PROG_OBJS:%=build/%} $(LIB_REALNAME)
- ${CC} $(filter %.o, $^) -L. -l$(LIB_NAME) -o $@
+ ${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_pcie_static: ${PCIE_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@
qcsapi_sockrpc: ${SOCKET_PROG_OBJS:%=build/%} $(LIB_REALNAME)
- ${CC} $(filter %.o, $^) -L. -l$(LIB_NAME) -o $@
+ ${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_sockrpc_static: ${SOCKET_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@
qcsapi_sockraw: ${SOCKET_RAW_PROG_OBJS:%=build/%} $(LIB_REALNAME)
- ${CC} $(filter %.o, $^) -L. -l$(LIB_NAME) -o $@
+ ${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_sockraw_static: ${SOCKET_RAW_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@

View File

@ -0,0 +1,11 @@
--- a/net80211/_ieee80211.h 2015-03-31 08:19:35.000000000 +0200
+++ b/net80211/_ieee80211.h 2016-04-14 00:19:20.000000000 +0200
@@ -33,7 +33,7 @@
*/
#ifndef _NET80211__IEEE80211_H_
#define _NET80211__IEEE80211_H_
-
+#include <sys/types.h>
#include <compat.h>
#ifdef __KERNEL__
#include <linux/in6.h>

View File

@ -0,0 +1,11 @@
--- a/qcsapi_rpc_common/client/rpc_pci_clnt.c 2015-03-31 07:49:58.000000000 +0200
+++ b/qcsapi_rpc_common/client/rpc_pci_clnt.c 2016-04-14 00:23:46.000000000 +0200
@@ -39,7 +39,7 @@
#include <netdb.h>
#include <linux/netlink.h>
#include <rpc/clnt.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <assert.h>
#include <qcsapi_rpc_common/common/rpc_pci.h>

View File

@ -0,0 +1,20 @@
--- a/qcsapi_rpc_common/common/rpc_raw.c 2015-03-31 07:49:58.000000000 +0200
+++ b/qcsapi_rpc_common/common/rpc_raw.c 2016-04-14 00:25:02.000000000 +0200
@@ -12,6 +12,7 @@
#include <errno.h>
#include <stdio.h>
#include <qcsapi_rpc_common/common/rpc_raw.h>
+#include <string.h>
int qrpc_set_prot_filter(const int sock, const short prot)
{
--- a/qcsapi_rpc/client/socket/qcsapi_socket_rpc_client.c 2015-03-31 07:49:58.000000000 +0200
+++ b/qcsapi_rpc/client/socket/qcsapi_socket_rpc_client.c 2016-04-14 00:21:38.000000000 +0200
@@ -48,6 +48,7 @@
#include <qcsapi_rpc_common/client/find_host_addr.h>
#include <qcsapi_rpc/client/qcsapi_rpc_client.h>
#include <qcsapi_rpc/generated/qcsapi_rpc.h>
+#include <string.h>
static int client_qcsapi_get_udp_retry_timeout(int *argc, char ***argv)
{

View File

@ -0,0 +1,144 @@
diff -Naur quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_init.c quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_init.c
--- quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_init.c 2018-03-16 15:08:37.000000000 +0200
+++ quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_init.c 2020-08-02 08:47:22.352332685 +0300
@@ -691,7 +691,7 @@
/* add code to reboot the while QCA system here*/
printk("%s: Attempting to reboot QCA system.\n", __func__);
- machine_restart(NULL);
+ emergency_restart();
break;
}
msleep(500);
diff -Naur quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_init.h quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_init.h
--- quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_init.h 2018-03-16 15:08:37.000000000 +0200
+++ quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_init.h 2020-08-02 07:38:28.814212107 +0300
@@ -42,6 +42,8 @@
#define QDPC_ROW_INCR_OFFSET 0x04
#undef QDPC_CS_DEBUG
+#define mmiowb() do { } while (0)
+
extern unsigned int (*qdpc_pci_readl)(void *addr);
extern void (*qdpc_pci_writel)(unsigned int val, void *addr);
diff -Naur quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_pcie.c quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_pcie.c
--- quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/qdpc_pcie.c 2018-03-16 15:08:37.000000000 +0200
+++ quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/qdpc_pcie.c 2020-08-02 07:42:31.174353547 +0300
@@ -29,7 +29,7 @@
#include <asm/byteorder.h>
#include <linux/pci.h>
#include <linux/moduleparam.h>
-#include <asm-generic/pci-dma-compat.h>
+#include <linux/pci-dma-compat.h>
#include <linux/module.h>
#include "qdpc_config.h"
diff -Naur quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/topaz_vnet.c quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/topaz_vnet.c
--- quantenna_gpl_v37.3.2.44/drivers/pcie2/host/common/topaz_vnet.c 2018-03-16 15:08:37.000000000 +0200
+++ quantenna_gpl_v37.3.2.44-mod/drivers/pcie2/host/common/topaz_vnet.c 2020-08-05 10:40:48.405527180 +0300
@@ -21,6 +21,8 @@
#define EXPORT_SYMTAB
#endif
+#define NET_NAME_USER 3 /* provided by user-space */
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -50,13 +52,13 @@
#include "qdpc_init.h"
#include "qdpc_debug.h"
#include "qdpc_regs.h"
-#include "nss_api_if.h"
+//#include "nss_api_if.h"
#include "qdpc_version.h"
#define DRV_NAME "qdpc-host"
#ifndef DRV_VERSION
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.0-k5.4-openwrt-nonss-tc"
#endif
#define DRV_AUTHOR "Quantenna Communications Inc."
@@ -73,8 +75,6 @@
static int __sram_text skb2rbd_attach(struct net_device *ndev, uint16_t i, uint32_t wrap);
static irqreturn_t vmac_interrupt(int irq, void *dev_id);
static void vmac_tx_timeout(struct net_device *ndev);
-static int vmac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd);
-static int vmac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd);
static void vmac_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info);
static void free_tx_skbs(struct vmac_priv *vmp);
static void init_tx_bd(struct vmac_priv *vmp);
@@ -824,7 +824,7 @@
dump_rx_bd(vmp);
- ndev->last_rx = jiffies;
+ netif_trans_update(ndev);
/*
* We are done with the current buffer attached to this descriptor, so attach a new
@@ -1180,7 +1180,7 @@
inline static void vmac_tx_timeout(struct net_device *ndev)
{
printk(KERN_ERR "%s: vmac_tx_timeout: ndev=%p\n", ndev->name, ndev);
- ndev->trans_start = jiffies;
+ netif_trans_update(ndev);
}
#ifdef RC_TXDONE_TIMER
@@ -1202,21 +1202,6 @@
}
#endif
-/* ethtools support */
-static int vmac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
-{
- return -EINVAL;
-}
-
-static int vmac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
-{
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- return -EINVAL;
-}
-
static int vmac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
return -EINVAL;
@@ -1233,13 +1218,6 @@
info->regdump_len = 0;
}
-static const struct ethtool_ops vmac_ethtool_ops = {
- .get_settings = vmac_get_settings,
- .set_settings = vmac_set_settings,
- .get_drvinfo = vmac_get_drvinfo,
- .get_link = ethtool_op_get_link,
-};
-
static const struct net_device_ops vmac_device_ops = {
.ndo_open = vmac_open,
.ndo_stop = vmac_close,
@@ -1254,7 +1232,7 @@
struct net_device * ndev;
/* Allocate device structure */
- ndev = alloc_netdev(sizeof(struct vmac_priv), vmaccfg.ifname, ether_setup);
+ ndev = alloc_netdev(sizeof(struct vmac_priv), vmaccfg.ifname, NET_NAME_USER ,ether_setup);
if(!ndev)
printk(KERN_ERR "%s: alloc_etherdev failed\n", vmaccfg.ifname);
@@ -1297,7 +1275,6 @@
ndev->netdev_ops = &vmac_device_ops;
ndev->tx_queue_len = QTN_GLOBAL_INIT_EMAC_TX_QUEUE_LEN;
- SET_ETHTOOL_OPS(ndev, &vmac_ethtool_ops);
/* Initialize private data */
vmp = netdev_priv(ndev);