diff options
author | specter119 | 2019-10-19 13:41:23 +0800 |
---|---|---|
committer | specter119 | 2019-10-19 13:41:23 +0800 |
commit | 4a1b4a8f147e9500453603710fe767b1a6f720e5 (patch) | |
tree | a9de8f3c6622d79bb7c34a3b925b1bcc5bf24cd3 | |
download | aur-4a1b4a8f147e9500453603710fe767b1a6f720e5.tar.gz |
init commit
-rw-r--r-- | .SRCINFO | 19 | ||||
-rw-r--r-- | PKGBUILD | 23 | ||||
-rw-r--r-- | disable-wireless-aspm.service | 13 | ||||
-rw-r--r-- | disable_wireless_aspm.sh | 201 |
4 files changed, 256 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..0838d6c1c57f --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,19 @@ +pkgbase = surface-pro-2017-disable-wireless-aspm + pkgdesc = A systemd unit to disable wireless aspm of surface pro 2017 + pkgver = 1.0 + pkgrel = 1 + url = https://github.com/jakeday/linux-surface/issues/572#issuecomment-542115727 + arch = i686 + arch = x86_64 + groups = surface + license = GPL + depends = systemd + depends = bash + provides = surface-pro-2017-disable-wireless-aspm + source = https://launchpadlibrarian.net/405591349/disable_wireless_aspm.sh + source = disable-wireless-aspm.service + md5sums = 944abcf405ee5bcba4c5774eaffbd478 + md5sums = e1d2477943dc3ab0738117e671c50cc8 + +pkgname = surface-pro-2017-disable-wireless-aspm + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..7b140acdbbce --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,23 @@ +# Maintainer: Ke Liu <spcter119@gmail.com> +pkgname=surface-pro-2017-disable-wireless-aspm +pkgver=1.0 +pkgrel=1 +pkgdesc='A systemd unit to disable wireless aspm of surface pro 2017' +arch=('i686' 'x86_64') +url="https://github.com/jakeday/linux-surface/issues/572#issuecomment-542115727" +license=('GPL') +groups=('surface') +depends=('systemd' 'bash') +provides=($pkgname) +source=(https://launchpadlibrarian.net/405591349/disable_wireless_aspm.sh + disable-wireless-aspm.service) +md5sums=('944abcf405ee5bcba4c5774eaffbd478' + 'e1d2477943dc3ab0738117e671c50cc8') + +package() { + cd $srcdir + install -Dm644 disable_wireless_aspm.sh "$pkgdir/usr/share/surface/disable_wireless_aspm.sh" + install -Dm644 disable-wireless-aspm.service "$pkgdir/usr/lib/systemd/system/disable-wireless-aspm.service" +} + +# vim:set ts=2 sw=2 et: diff --git a/disable-wireless-aspm.service b/disable-wireless-aspm.service new file mode 100644 index 000000000000..bf1b6d4c2ab1 --- /dev/null +++ b/disable-wireless-aspm.service @@ -0,0 +1,13 @@ +[Unit] +Description=Disable wireless aspm for surface pro 2017 + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/share/surface/disable_wireless_aspm.sh +TimeoutSec=0 +#StandardOutput=tty +RemainAfterExit=yes +SysVStartPriority=99 + +[Install] +WantedBy=multi-user.target diff --git a/disable_wireless_aspm.sh b/disable_wireless_aspm.sh new file mode 100644 index 000000000000..0098d7138279 --- /dev/null +++ b/disable_wireless_aspm.sh @@ -0,0 +1,201 @@ +#!/bin/bash +# +# Disable ASPM for Marvell Wireles driver on Surface Pro 5 2017 +# +# Original script by Luis R. Rodriguez <mcgrof@do-not-panic.com> +# Force enable ASPM L0 and L1 for all devices on Dell 9360 +# https://gist.github.com/baybal/b499fc5811a7073df0c03ab8da4be904 +# BIG THANKS to HIM! +# +# Modified by P.I.Julius <me@pijulius.com> +# Modification include simply using one device and setting ASPM +# to disabled instead of enabled by default. +# +# IMPORTANT: you will need to run this script on every fresh start +# but it seems resume keeps the set value +# +# To use this script You will need for now to at least query your device +# lspci -vvv +# +# For example: +# 01:00.0 Ethernet controller: Marvell Technology Group Ltd. 88W8897 [AVASTAR] 802.11ac Wireless +# + +PCIDEVICE="01:00.0" + +# We'll only enable the last 2 bits by using a mask +# of :3 to setpci, this will ensure we keep the existing +# values on the byte. +# +# Hex Binary Meaning +# ------------------------- +# 0 0b00 L0 only +# 1 0b01 L0s only +# 2 0b10 L1 only +# 3 0b11 L1 and L0s +ASPM_SETTING=0 + +function aspm_setting_to_string() +{ + case $1 in + 0) + echo -e "\t${BLUE}L0 only${NORMAL}, ${RED}ASPM disabled${NORMAL}" + ;; + 1) + ;; + 2) + echo -e "\t${GREEN}L1 only${NORMAL}" + ;; + 3) + echo -e "\t${GREEN}L1 and L0s${NORMAL}" + ;; + *) + echo -e "\t${RED}Invalid${NORMAL}" + ;; + esac +} + +# Pretty colors +GREEN="\033[01;32m" +YELLOW="\033[01;33m" +NORMAL="\033[00m" +BLUE="\033[34m" +RED="\033[31m" +PURPLE="\033[35m" +CYAN="\033[36m" +UNDERLINE="\033[02m" + +# we can surely read the spec to get a better value +MAX_SEARCH=20 +SEARCH_COUNT=1 +ASPM_BYTE_ADDRESS="INVALID" + +PCIDEVICE_PRESENT=$(lspci | grep -c "$PCIDEVICE") + +if [[ $(id -u) != 0 ]]; then + echo "This needs to be run as root" + exit 1 +fi + +if [[ $PCIDEVICE_PRESENT -eq 0 ]]; then + echo "Device $PCIDEVICE is not present" + exit +fi + +# XXX: lspci -s some_device_not_existing does not return positive +# if the device does not exist, fix this upstream +function device_present() +{ + + PRESENT=$(lspci | grep -c "$1") + COMPLAINT="${RED}not present${NORMAL}" + + if [[ $PRESENT -eq 0 ]]; then + if [[ $2 != "present" ]]; then + COMPLAINT="${RED}disappeared${NORMAL}" + fi + + echo -e "Device ${BLUE}${1}${NORMAL} $COMPLAINT" + return 1 + fi + return 0 +} + +function find_aspm_byte_address() +{ + device_present $PCIDEVICE present + if [[ $? -ne 0 ]]; then + exit + fi + + SEARCH=$(setpci -s $1 34.b) + # We know on the first search $SEARCH will not be + # 10 but this simplifies the implementation. + while [[ $SEARCH != 10 && $SEARCH_COUNT -le $MAX_SEARCH ]]; do + END_SEARCH=$(setpci -s $1 ${SEARCH}.b) + + # Convert hex digits to uppercase for bc + SEARCH_UPPER=$(printf "%X" 0x${SEARCH}) + + if [[ $END_SEARCH = 10 ]]; then + ASPM_BYTE_ADDRESS=$(echo "obase=16; ibase=16; $SEARCH_UPPER + 10" | bc) + break + fi + + SEARCH=$(echo "obase=16; ibase=16; $SEARCH + 1" | bc) + SEARCH=$(setpci -s $1 ${SEARCH}.b) + + let SEARCH_COUNT=$SEARCH_COUNT+1 + done + + if [[ $SEARCH_COUNT -ge $MAX_SEARCH ]]; then + echo -e "Long loop while looking for ASPM word for $1" + return 1 + fi + return 0 +} + +function enable_aspm_byte() +{ + device_present $1 present + if [[ $? -ne 0 ]]; then + exit + fi + + find_aspm_byte_address $1 + if [[ $? -ne 0 ]]; then + return 1 + fi + + ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b) + ASPM_BYTE_HEX=$(printf "%X" 0x${ASPM_BYTE_HEX}) + # setpci doesn't support a mask on the query yet, only on the set, + # so to verify a setting on a mask we have no other optoin but + # to do do this stuff ourselves. + DESIRED_ASPM_BYTE_HEX=$(printf "%X" $(( (0x${ASPM_BYTE_HEX} & ~0x7) |0x${ASPM_SETTING}))) + + if [[ $ASPM_BYTE_ADDRESS = "INVALID" ]]; then + echo -e "No ASPM byte could be found for $(lspci -s $1)" + return + fi + + echo -e "$(lspci -s $1)" + echo -en "\t${YELLOW}0x${ASPM_BYTE_ADDRESS}${NORMAL} : ${CYAN}0x${ASPM_BYTE_HEX}${GREEN} --> ${BLUE}0x${DESIRED_ASPM_BYTE_HEX}${NORMAL} ... " + + device_present $1 present + if [[ $? -ne 0 ]]; then + exit + fi + + # Avoid setting if already set + if [[ $ASPM_BYTE_HEX = $DESIRED_ASPM_BYTE_HEX ]]; then + echo -e "[${GREEN}SUCESS${NORMAL}] (${GREEN}already set${NORMAL})" + aspm_setting_to_string $ASPM_SETTING + return 0 + fi + + # This only writes the last 3 bits + setpci -s $1 ${ASPM_BYTE_ADDRESS}.b=${ASPM_SETTING}:3 + + sleep 3 + + ACTUAL_ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b) + ACTUAL_ASPM_BYTE_HEX=$(printf "%X" 0x${ACTUAL_ASPM_BYTE_HEX}) + + # Do not retry this if it failed, if it failed to set. + # Likey if it failed its a good reason and you should look + # into that. + if [[ $ACTUAL_ASPM_BYTE_HEX != $DESIRED_ASPM_BYTE_HEX ]]; then + echo -e "\t[${RED}FAIL${NORMAL}] (0x${ACTUAL_ASPM_BYTE_HEX})" + return 1 + fi + + echo -e "\t[${GREEN}SUCCESS]${NORMAL}]" + aspm_setting_to_string $ASPM_SETTING + + return 0 +} + +echo -e "${CYAN}Device${NORMAL}:" +enable_aspm_byte $PCIDEVICE +echo |