diff mbox series

[OpenWrt-Devel] netgear r7800: Fix mac address of radios.

Message ID 1540501682-13168-1-git-send-email-greearb@candelatech.com
State Superseded
Delegated to: John Crispin
Headers show
Series [OpenWrt-Devel] netgear r7800: Fix mac address of radios. | expand

Commit Message

Ben Greear Oct. 25, 2018, 9:08 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

Reloading the driver causes the phyX to change, and that caused
the MAC address to change.  Instead, match on pci-bus which should
be immutable.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../ipq806x/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac    | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Comments

Christian Lamparter Oct. 25, 2018, 11:11 p.m. UTC | #1
Hello,

On Thursday, October 25, 2018 11:08:02 PM CEST greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> Reloading the driver causes the phyX to change, and that caused
> the MAC address to change.  Instead, match on pci-bus which should
> be immutable.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>

Mathias Kresin developped a shell function which can just patch the MACs
into the binary pre-cal files. And it should give you the same result.
I don't have a R7800, so I just copied and pasted the functions from
the ipq40xx target and added the R7800 (along with the D7800 and
R7500v2) as an example. It's all untested. It looks like all other
IPQ806x devices could be converted in a similar fashion.

---
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..c0e4d940f9 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
@@ -36,6 +52,29 @@ ath10kcal_patch_mac() {
 	macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc bs=1 seek=6 count=6
 }
 
+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
+
+	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}"
+
+	ath10kcal_patch_mac "$mac" && {
+		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
 
 . /lib/functions.sh
@@ -55,6 +94,7 @@ case "$FIRMWARE" in
 	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
@@ -79,6 +119,7 @@ case "$FIRMWARE" in
 	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
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 afa425f075..5e5dd84729 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
@@ -18,11 +18,6 @@ case "$board" in
 	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
 		;;
---
Ben Greear Oct. 26, 2018, 12:03 a.m. UTC | #2
On 10/25/2018 04:11 PM, Christian Lamparter wrote:
> Hello,
>
> On Thursday, October 25, 2018 11:08:02 PM CEST greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> Reloading the driver causes the phyX to change, and that caused
>> the MAC address to change.  Instead, match on pci-bus which should
>> be immutable.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>
> Mathias Kresin developped a shell function which can just patch the MACs
> into the binary pre-cal files. And it should give you the same result.
> I don't have a R7800, so I just copied and pasted the functions from
> the ipq40xx target and added the R7800 (along with the D7800 and
> R7500v2) as an example. It's all untested. It looks like all other
> IPQ806x devices could be converted in a similar fashion.

This appears to work on my R7800, and with the added benefit that the
wlanX interfaces have proper MACs now.

So, looks good to me, and better than my patch.

Thanks,
Ben

>
> ---
> 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..c0e4d940f9 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
> @@ -36,6 +52,29 @@ ath10kcal_patch_mac() {
>  	macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc bs=1 seek=6 count=6
>  }
>
> +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
> +
> +	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}"
> +
> +	ath10kcal_patch_mac "$mac" && {
> +		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
>
>  . /lib/functions.sh
> @@ -55,6 +94,7 @@ case "$FIRMWARE" in
>  	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
> @@ -79,6 +119,7 @@ case "$FIRMWARE" in
>  	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
> 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 afa425f075..5e5dd84729 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
> @@ -18,11 +18,6 @@ case "$board" in
>  	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
>  		;;
> ---
>
>
>
>
diff mbox series

Patch

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 afa425f..fef8205 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
@@ -19,8 +19,14 @@  case "$board" in
 		echo $(macaddr_add $(mtd_get_mac_binary PRODUCTDATA 12) $((1 - $PHYNBR)) ) > /sys${DEVPATH}/macaddress
 		;;
 	netgear,d7800 |\
-	netgear,r7500v2 |\
+	netgear,r7500v2)
+		echo $(macaddr_add $(mtd_get_mac_binary art 6)  $(($PHYNBR + 1)) ) > /sys${DEVPATH}/macaddress
+		;;
 	netgear,r7800)
+	        # Match off of pci-bus, it is less mutable than the phy name since phy name
+	        # changes on module reload.
+	        grep PCI_SLOT_NAME=0000:01:00.0 /sys${DEVPATH}/device/uevent && PHYNBR=0
+	        grep PCI_SLOT_NAME=0001:01:00.0 /sys${DEVPATH}/device/uevent && PHYNBR=1
 		echo $(macaddr_add $(mtd_get_mac_binary art 6)  $(($PHYNBR + 1)) ) > /sys${DEVPATH}/macaddress
 		;;
 	tplink,c2600)