From 330965b342670def66d956d5a20009475ab30d0c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 28 Oct 2018 17:39:43 +0100 Subject: [PATCH] ipq806x: add ath10k calibration data MAC addresses patching Ben Greear reported in his patch: |Subject: netgear r7800: Fix mac address of radios. | |Reloading the driver causes the phyX to change, and that |caused the MAC address to change. This is because all ODM/OEMs except QCA bothered to write the correct MAC address for the ath10k wifi into the calibration data. This patch copies over the MAC patching helper functions from ipq40xx's target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata file and converts all the devices to patch the correct MACs into the extracted calibration data before it gets sent to the driver, which sets up the device with the correct MAC address. It also removes the entries in the 10_fix_wifi_mac file as they have served their purpose for good. Please note the C2600: There is conflicting information on what the offset for the second wifi is supposed to be. This patch uses what was specified in 10_fix_wifi_mac. According to Ben Greear this method is save to use with the stock firmware too. As he explained that the stock firmware messes up rx-bssid mask calculation when the MAC is changed after the first vif is created. Reported-by: Ben Greear Signed-off-by: Christian Lamparter --- .../etc/hotplug.d/firmware/11-ath10k-caldata | 60 ++++++++++++++++--- .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 27 --------- 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index fa49c250f0..ba7a8e0b14 100644 --- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -1,5 +1,21 @@ #!/bin/sh +# xor multiple hex values of the same length +xor() { + local val + local ret="0x$1" + local retlen=${#1} + + shift + while [ -n "$1" ]; do + val="0x$1" + ret=$((ret ^ val)) + shift + done + + printf "%0${retlen}x" "$ret" +} + ath10kcal_die() { echo "ath10cal: " "$*" exit 1 @@ -28,12 +44,29 @@ ath10kcal_extract() { ath10kcal_die "failed to extract calibration data from $mtd" } -ath10kcal_patch_mac() { +ath10kcal_patch_mac_crc() { local mac=$1 + local mac_offset=6 + local chksum_offset=2 + local xor_mac + local xor_fw_mac + local xor_fw_chksum [ -z "$mac" ] && return + xor_fw_mac=$(hexdump -v -n 6 -s $mac_offset -e '/1 "%02x"' /lib/firmware/$FIRMWARE) + xor_fw_mac="${xor_fw_mac:0:4} ${xor_fw_mac:4:4} ${xor_fw_mac:8:4}" + macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc bs=1 seek=6 count=6 + + xor_mac=${mac//:/} + xor_mac="${xor_mac:0:4} ${xor_mac:4:4} ${xor_mac:8:4}" + + xor_fw_chksum=$(hexdump -v -n 2 -s $chksum_offset -e '/1 "%02x"' /lib/firmware/$FIRMWARE) + xor_fw_chksum=$(xor $xor_fw_chksum $xor_fw_mac $xor_mac) + + printf "%b" "\x${xor_fw_chksum:0:2}\x${xor_fw_chksum:2:2}" | \ + dd of=/lib/firmware/$FIRMWARE conv=notrunc bs=1 seek=$chksum_offset count=2 } [ -e /lib/firmware/$FIRMWARE ] && exit 0 @@ -43,53 +76,64 @@ ath10kcal_patch_mac() { board=$(board_name) - case "$FIRMWARE" in "ath10k/pre-cal-pci-0000:01:00.0.bin") case $board in linksys,ea8500) - hw_mac_addr=$(mtd_get_mac_ascii devinfo hw_mac_addr) ath10kcal_extract "art" 4096 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_ascii devinfo hw_mac_addr) +1) + ;; + nec,wg2600hp) + ath10kcal_extract "ART" 4096 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary PRODUCTDATA 12) +1) ;; netgear,d7800 |\ netgear,r7500v2 |\ netgear,r7800) ath10kcal_extract "art" 4096 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary art 6) +1) ;; tplink,c2600) ath10kcal_extract "radio" 4096 12064 -# ath10kcal_patch_mac $(macaddr_add $(mtd_get_mac_binary default-mac 8) -1) + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary default-mac 8) -1) ;; - nec,wg2600hp |\ tplink,vr2600v) ath10kcal_extract "ART" 4096 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary default-mac 0) -1) ;; zyxel,nbg6817) ath10kcal_extract "0:ART" 4096 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_ascii 0:APPSBLENV ethaddr) +1) ;; esac ;; "ath10k/pre-cal-pci-0001:01:00.0.bin") case $board in linksys,ea8500) - hw_mac_addr=$(mtd_get_mac_ascii devinfo hw_mac_addr) ath10kcal_extract "art" 20480 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_ascii devinfo hw_mac_addr) +2) + ;; + nec,wg2600hp) + ath10kcal_extract "ART" 20480 12064 + ath10kcal_patch_mac_crc $(mtd_get_mac_binary PRODUCTDATA 12) ;; netgear,d7800 |\ netgear,r7500v2 |\ netgear,r7800) ath10kcal_extract "art" 20480 12064 + ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary art 6) +2) ;; tplink,c2600) ath10kcal_extract "radio" 20480 12064 -# ath10kcal_patch_mac $(macaddr_add $(mtd_get_mac_binary default-mac 8) -2) + ath10kcal_patch_mac_crc $(mtd_get_mac_binary default-mac 8) ;; - nec,wg2600hp |\ tplink,vr2600v) ath10kcal_extract "ART" 20480 12064 + ath10kcal_patch_mac_crc $(mtd_get_mac_binary default-mac 0) ;; zyxel,nbg6817) ath10kcal_extract "0:ART" 20480 12064 + ath10kcal_patch_mac_crc $(mtd_get_mac_ascii 0:APPSBLENV ethaddr) ;; esac ;; diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index 8956bbd74a..4b476e56ae 100644 --- a/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -9,33 +9,6 @@ PHYNBR=${DEVPATH##*/phy} . /lib/functions.sh . /lib/functions/system.sh -board=$(board_name) - -case "$board" in - linksys,ea8500) - echo $(macaddr_add $(mtd_get_mac_ascii devinfo hw_mac_addr) $(($PHYNBR + 1)) ) > /sys${DEVPATH}/macaddress - ;; - nec,wg2600hp) - echo $(macaddr_add $(mtd_get_mac_binary PRODUCTDATA 12) $((1 - $PHYNBR)) ) > /sys${DEVPATH}/macaddress - ;; - netgear,d7800 |\ - netgear,r7500v2 |\ - netgear,r7800) - echo $(macaddr_add $(mtd_get_mac_binary art 6) $(($PHYNBR + 1)) ) > /sys${DEVPATH}/macaddress - ;; - tplink,c2600) - echo $(macaddr_add $(mtd_get_mac_binary default-mac 8) $(($PHYNBR - 1)) ) > /sys${DEVPATH}/macaddress - ;; - tplink,vr2600v) - echo $(macaddr_add $(mtd_get_mac_binary default-mac 0) $(($PHYNBR - 1)) ) > /sys${DEVPATH}/macaddress - ;; - zyxel,nbg6817) - echo $(macaddr_add $(mtd_get_mac_ascii 0:APPSBLENV ethaddr) $((1 - $PHYNBR)) ) > /sys${DEVPATH}/macaddress - ;; - *) - ;; -esac - OPATH=${DEVPATH##/devices/platform/} OPATH=${OPATH%%/ieee*}