Divested-WRT: No-nonsense hardened builds for Linksys WRT series

I'll try to backport couple fixes in the mvneta. I do believe...every fix will improve our immune response. Thanks @SkewedZeppelin!

This one implement basic mqprio support.

--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -102,6 +102,8 @@
 #define      MVNETA_TX_NO_DATA_SWAP              BIT(5)
 #define      MVNETA_DESC_SWAP                    BIT(6)
 #define      MVNETA_TX_BRST_SZ_MASK(burst)       ((burst) << 22)
+#define        MVNETA_VLAN_PRIO_TO_RXQ                  0x2440
+#define      MVNETA_VLAN_PRIO_RXQ_MAP(prio, rxq) ((rxq) << ((prio) * 3))
 #define MVNETA_PORT_STATUS                       0x2444
 #define      MVNETA_TX_IN_PRGRS                  BIT(0)
 #define      MVNETA_TX_FIFO_EMPTY                BIT(8)
@@ -490,6 +492,7 @@
        u8 mcast_count[256];
        u16 tx_ring_size;
        u16 rx_ring_size;
+       u8 prio_tc_map[8];

        phy_interface_t phy_interface;
        struct device_node *dn;
@@ -4903,6 +4910,63 @@
        return phylink_ethtool_set_eee(pp->phylink, eee);
 }

+static void mvneta_clear_rx_prio_map(struct mvneta_port *pp)
+{
+       mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, 0);
+}
+
+static void mvneta_setup_rx_prio_map(struct mvneta_port *pp)
+{
+       u32 val = 0;
+       int i;
+
+       for (i = 0; i < rxq_number; i++)
+               val |= MVNETA_VLAN_PRIO_RXQ_MAP(i, pp->prio_tc_map[i]);
+
+       mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val);
+}
+
+static int mvneta_setup_mqprio(struct net_device *dev,
+                              struct tc_mqprio_qopt *qopt)
+{
+       struct mvneta_port *pp = netdev_priv(dev);
+       u8 num_tc;
+       int i;
+
+       qopt->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+       num_tc = qopt->num_tc;
+
+       if (num_tc > rxq_number)
+               return -EINVAL;
+
+       if (!num_tc) {
+               mvneta_clear_rx_prio_map(pp);
+               netdev_reset_tc(dev);
+               return 0;
+       }
+
+       memcpy(pp->prio_tc_map, qopt->prio_tc_map, sizeof(pp->prio_tc_map));
+
+       mvneta_setup_rx_prio_map(pp);
+
+       netdev_set_num_tc(dev, qopt->num_tc);
+       for (i = 0; i < qopt->num_tc; i++)
+               netdev_set_tc_queue(dev, i, qopt->count[i], qopt->offset[i]);
+
+       return 0;
+}
+
+static int mvneta_setup_tc(struct net_device *dev, enum tc_setup_type type,
+                          void *type_data)
+{
+       switch (type) {
+       case TC_SETUP_QDISC_MQPRIO:
+               return mvneta_setup_mqprio(dev, type_data);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static const struct net_device_ops mvneta_netdev_ops = {
        .ndo_open            = mvneta_open,
        .ndo_stop            = mvneta_stop,
@@ -4915,6 +4979,7 @@
        .ndo_do_ioctl        = mvneta_ioctl,
        .ndo_bpf             = mvneta_xdp,
        .ndo_xdp_xmit        = mvneta_xdp_xmit,
+       .ndo_setup_tc        = mvneta_setup_tc,
 };

 static const struct ethtool_ops mvneta_eth_tool_ops = {

Since moving to this build, I've got a problematic wifi client that gets stuck in disconnect, and then blacklists the router bssid.
Its a linux based client and I can see the wpa_supplicant logs at the client side. But it looks like openwrt's hostapd has been compiled with a lot of the lower level debug removed to reduce size. I don't see much of any management level messages at the router logs (and I moved to verbose debugging).

The client 'initially' connected and was running for some time (I don't know the conditions here, but there is some stickiness once things break). After some time, and possibly from power off/disconnects reconnects, the client can't get back on the network. I've tried clearing blacklist, disabling and renabling the network (client), rescanning, resetting wpa_supplicant, rebooting the client etc, nothing works, as it just quickly moves right back to disabled and blacklisted.

The router is sending ASSOC-REJECT (12) status code =1 to the client. I wish I could see the router side of the exchange in logging.

I've got a sanitized snippet of wpa_supplicant log below, just after the supplicant finds its ssid in scan and tries to connect.. Does anyone have any ideas?

1634772434.261811:   * freq_hint=2412
1634772434.261837:   * SSID - hexdump_ascii(len=6):
    6d 79 73 73 69 64                                       myssid            
1634772434.261907:   * IEs - hexdump(len=31): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 00 00 3b 07 51 51 73 76 79 7c 7d
1634772434.262011:   * WPA Versions 0x2
1634772434.262035:   * pairwise=0xfac04
1634772434.262056:   * group=0xfac04
1634772434.262077:   * akm=0xfac02
1634772434.262102:   * Auth Type 0
1634772434.277179: nl80211: Connect request send successfully
1634772434.277339: wlan0: Setting authentication timeout: 10 sec 0 usec
1634772434.277441: EAPOL: External notification - EAP success=0
1634772434.277494: EAPOL: External notification - EAP fail=0
1634772434.277524: EAPOL: External notification - portControl=Auto
1634772434.465961: nl80211: Event message available
1634772434.466289: nl80211: Drv Event 46 (NL80211_CMD_CONNECT) received for wlan0
1634772434.466356: nl80211: Connect event (status=1 ignore_next_local_disconnect=0)
1634772434.466430: wlan0: Event ASSOC_REJECT (12) received
1634772434.466533: wlan0: CTRL-EVENT-ASSOC-REJECT bssid=aa:bb:cc:dd:ee:ff status_code=1
1634772434.466619: wlan0: Radio work 'connect'@0x1517b0 done in 0.210513 seconds
1634772434.466674: wlan0: radio_work_free('connect'@0x1517b0): num_active_works --> 0
1634772434.466719: Added BSSID aa:bb:cc:dd:ee:ff into blacklist
1634772434.466755: Continuous association failures - consider temporary network disabling
1634772434.466908: wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="myssid" auth_failures=3 duration=30 reason=CONN_FAILED
1634772434.466972: wlan0: Blacklist count 29 --> request scan in 10000 ms

Just curious "since moving to this build" from what build? OEM, Master Snapshot, 21.02.1, 19.07.8, etc.?

1 Like

@phinn,

I moved from DavidC's last build. The client worked fine on that, but obviously there were a billion changes between 19.x and 21.02. Could still be the client doing something wrong that may have been tolerated in 19.x, but I need to figure out what the router doesn't like.

Are you familiar with this discussion? A few brave people are trying to solve/find a workaround for the wifi issues for WRT3200ACM/WRT32X.

They've currently been able to track down the problem and remedy the issue by replacing the current mac80211, with an older one (5.7.5), in a 21.02.1 build. If it works for master as well, maybe this is something we could try out here too?

2 Likes

I've updated to the latest build from the last David built on my WRT1900AC and the fan appears to be stuck on maximum. Any ideas?

It seems like there is a pwm fan control package but I think the kernel is too new to install.

Courtesy of @anomeome :

This looks great. I've not had to install a package from source before. Are there instructions around somewhere? My googling is failing me.

There was a change to master quite a while back which I fixed up locally but never got around pushing to my repo, so:

/etc/init.d/fan_control
#!/bin/sh /etc/rc.common
# Copyright (C) 2016-2017 LEDE-Project.org

START=65
STOP=80
USE_PROCD=1
#PROCD_DEBUG=1

boot() {
. /lib/functions.sh

board=$(board_name)

case "$board" in
linksys,wrt1900ac-v1)
    rc_procd start_service
    ;;
esac
}

start_service() {
    procd_open_instance
    procd_set_param command /usr/sbin/fan_monitor -b -a
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_close_instance
}

and

/usr/sbin/fan_monitor
#!/bin/sh

# put in /usr/sbin/fan_monitor
# fan_monitor
# Utility script to monitor temperatures and run fan at 50%/75%/100%
# For Reference the original Belkin specs.

INTERVAL=20  # sleep time in seconds between temp check
FANLOW=127   # low fan speed, set to 0 for off
FANMID=191   # mid fan speed
FANHI=255    # high fan speed

# Set fan to 100% on >= these temperatures
#CPU_HI=80000    # Belkin default is 85
#DDR_HI=58000    # Belkin default is 65
#WIFI_HI=75000   # Belkin default is 105

# Set fan to 75% <= these, otherwise 100% 
CPU_MID=80000     # Belkin sets no default
DDR_MID=58000     # Belkin sets no default
WIFI_MID=75000    # Belkin sets no default

# Set fan to 50% <= these temperatures
CPU_LOW=72000     # Belkin default is 80
DDR_LOW=52000     # Belkin default is 60
WIFI_LOW=55000    # Belkin default is 100

cur_pwm=0
new_pwm="$FANHI"  # start fan at HI while coming up

fan_set() {
    local ppwm
    cur_pwm=$1

    if [ "$1" -eq $FANLOW ]; then
        ppwm="50%"
    elif [ "$1" -eq $FANMID ]; then
        ppwm="75%"
    else
        ppwm="100%"
    fi

    logger -t FAN_MONITOR "Setting Fan to $ppwm"
    echo "$1" > /sys/devices/platform/pwm_fan/hwmon/hwmon0/pwm1
}

# Crank fan on exit
trap "{ logger -t FAN_MONITOR Fan monitor exiting; fan_set $FANHI; logger -t FAN_MONITOR as a precaution; exit; }" SIGINT SIGTERM

# Main fan control loop
while :
do
    if [ "$new_pwm" -ne "$cur_pwm" ]
    then
        fan_set "$new_pwm"
    fi
    sleep $INTERVAL

    cpu=`cat /sys/class/hwmon/hwmon2/temp1_input`
    ddr=`cat /sys/class/hwmon/hwmon1/temp1_input`
    wifi=`cat /sys/class/hwmon/hwmon1/temp2_input`

    if [ "$cpu" -le $CPU_LOW -a "$ddr" -le $DDR_LOW -a "$wifi" -le $WIFI_LOW ]
    then
        new_pwm="$FANLOW"
    elif [ "$cpu" -le $CPU_MID -a "$ddr" -le $DDR_MID -a "$wifi" -le $WIFI_MID ]
    then
        new_pwm="$FANMID"
    else
        new_pwm="$FANHI"
    fi
done

check file attributes, comment out the current fan control (/etc/rc./local), enable and start

/etc/init.d/fan_control enable
/etc/init.d/fan_control start

will push that to my repo real soon now, unless sloth gets the better of me.

3 Likes

Excellent! That quieted things down nicely! Thanks a lot.

Just checked in on that thread today and saw the great news! (haven't flashed it yet but hoping it's finally fixed fingers crossed)

+1 for integrating the fix into the divested builds

1 Like

@slh has an excellent response on why that isn't a good idea.

1 Like

Looks like this is the only known option for 3200ACM/32X users at the moment to upgrade to 21.02 without connectivity issues, since functionality is broken past 19.07 builds where maintenance has stopped completely; kind of stuck between a rock and a hard place unfortunately. While not ideal, not sure what other options we have for these two devices other than ditch them for something newer (kind of leaning towards that since mwlwifi is abandoned but want to squeeze some more use out of it) or stick with the old builds indefinitely.

1 Like

Was it 19.02 or 19.07?

yup 19.07, typo

Dear Divested-WRT people, where can I find the patch to enble multi CPU on DSA? Thanks!

FWIW. Not yet ready for prime time?

Ok, it was just to try

I am only getting about 350-400Mb on my WAN port. Any ideas? My asymetric internetspeed is around 750-800Mb.

Linksys WRT1900ACS with latest version - SNAPSHOT r18088+9-9bd9e04b6f
Nothing much default settings and application enabled.
Enables:

  • Cake
  • Enabled irqbalance

@steinmb
What are your speeds with cake off?