Guest User

Untitled

a guest
Jul 18th, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.97 KB | None | 0 0
  1. #!/bin/bash
  2. # Copyright (c) 2010-2013 Luis R. Rodriguez <[email protected]>
  3. #
  4. # Permission to use, copy, modify, and/or distribute this software for any
  5. # purpose with or without fee is hereby granted, provided that the above
  6. # copyright notice and this permission notice appear in all copies.
  7. #
  8. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15.  
  16.  
  17. # ASPM Tuning script
  18. #
  19. # This script lets you enable ASPM on your devices in case your BIOS
  20. # does not have it enabled for some reason. If your BIOS does not have
  21. # it enabled it is usually for a good reason so you should only use this if
  22. # you know what you are doing. Typically you would only need to enable
  23. # ASPM manually when doing development and using a card that typically
  24. # is not present on a laptop, or using the cardbus slot. The BIOS typically
  25. # disables ASPM for foreign cards and on the cardbus slot. Check also
  26. # if you may need to do other things than what is below on your vendor
  27. # documentation.
  28. #
  29. # To use this script You will need for now to at least query your device
  30. # PCI endpoint and root complex addresses using the convention output by
  31. # lspci: [<bus>]:[<slot>].[<func>]
  32. #
  33. # For example:
  34. #
  35. # 03:00.0 Network controller: Atheros Communications Inc. AR9300 Wireless LAN adaptor (rev 01
  36. # 00:1c.1 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 2 (rev 03)
  37. #
  38. # The root complex for the endpoint can be found using lspci -PP
  39. #
  40. # For more details refer to:
  41. #
  42. # en:users:documentation:aspm [Linux Wireless]
  43.  
  44. # You just need to modify these three values:
  45.  
  46. ENDPOINT=$1
  47.  
  48. # We'll only enable the last 2 bits by using a mask
  49. # of :3 to setpci, this will ensure we keep the existing
  50. # values on the byte.
  51. #
  52. # Hex Binary Meaning
  53. # -------------------------
  54. # 0 0b00 L0 only
  55. # 1 0b01 L0s only
  56. # 2 0b10 L1 only
  57. # 3 0b11 L1 and L0s
  58. ASPM_SETTING=$2
  59.  
  60. function aspm_setting_to_string()
  61. {
  62. case $1 in
  63. 0)
  64. echo -e "${BLUE}L0 only${NORMAL}, ${RED}ASPM disabled${NORMAL}"
  65. ;;
  66. 1)
  67. echo -e "${GREEN}L0s only${NORMAL}"
  68. ;;
  69. 2)
  70. echo -e "${GREEN}L1 only${NORMAL}"
  71. ;;
  72. 3)
  73. echo -e "${GREEN}L1 and L0s${NORMAL}"
  74. ;;
  75. *)
  76. echo -e "${RED}Invalid${NORMAL}"
  77. ;;
  78. esac
  79. }
  80.  
  81.  
  82. ###################################################################
  83. # Do not edit below here unless you are sending me a patch
  84. ###################################################################
  85. #
  86. # TODO: patches are welcomed to me until we submit to to
  87. # PCI Utilities upstream.
  88. #
  89. # This can be improved by in this order:
  90. #
  91. # * Accept arguments for endpoint and root complex address, and
  92. # desired ASPM settings
  93. # * Look for your ASPM capabilities by quering your
  94. # LnkCap register first. Use these values to let you
  95. # select whether you want to enable only L1 or L1 & L0s
  96. # * Searching for your root complex for you
  97. # * Search for your PCI device by using the driver
  98. # * Disable your driver and ask to reboot ?
  99. # * Rewrite in C
  100. # * Write ncurses interface [ wishlist ]
  101. # * Write GTK/QT interface [ wishlist ]
  102. # * Submit upstream as aspm.c to the PCI Utilities, which are
  103. # maintained by Martin Mares <[email protected]>
  104.  
  105. # Pretty colors
  106. GREEN="\033[01;32m"
  107. YELLOW="\033[01;33m"
  108. NORMAL="\033[00m"
  109. BLUE="\033[34m"
  110. RED="\033[31m"
  111. PURPLE="\033[35m"
  112. CYAN="\033[36m"
  113. UNDERLINE="\033[02m"
  114.  
  115. # we can surely read the spec to get a better value
  116. MAX_SEARCH=20
  117. SEARCH_COUNT=1
  118. ASPM_BYTE_ADDRESS="INVALID"
  119.  
  120. if [[ $# -ne 2 ]]; then
  121. echo "Usage: ./enable-aspm.sh ENDPOINT ASPM_SETTING"
  122. exit 1
  123. fi
  124.  
  125. ENDPOINT_PRESENT=$(lspci -s $ENDPOINT)
  126.  
  127. if [[ $(id -u) != 0 ]]; then
  128. echo "This needs to be run as root"
  129. exit 1
  130. fi
  131.  
  132. if [[ ${#ENDPOINT_PRESENT} -eq 0 ]]; then
  133. echo "Endpoint $ENDPOINT is not present"
  134. exit
  135. fi
  136.  
  137. function device_present()
  138. {
  139.  
  140. PRESENT=$(lspci -s $1)
  141. COMPLAINT="${RED}not present${NORMAL}"
  142.  
  143. if [[ ${#PRESENT} -eq 0 ]]; then
  144. if [[ $2 != "present" ]]; then
  145. COMPLAINT="${RED}disappeared${NORMAL}"
  146. fi
  147.  
  148. echo -e "Device ${BLUE}${1}${NORMAL} $COMPLAINT"
  149. return 1
  150. fi
  151. return 0
  152. }
  153.  
  154. function find_aspm_byte_address()
  155. {
  156. device_present $ENDPOINT present
  157. if [[ $? -ne 0 ]]; then
  158. exit
  159. fi
  160.  
  161. SEARCH=$(setpci -s $1 34.b)
  162. # We know on the first search $SEARCH will not be
  163. # 10 but this simplifies the implementation.
  164. while [[ $SEARCH != 10 && $SEARCH_COUNT -le $MAX_SEARCH ]]; do
  165. END_SEARCH=$(setpci -s $1 ${SEARCH}.b)
  166.  
  167. # Convert hex digits to uppercase for bc
  168. SEARCH_UPPER=$(printf "%X" 0x${SEARCH})
  169.  
  170. if [[ $END_SEARCH = 10 ]]; then
  171. ASPM_BYTE_ADDRESS=$(echo "obase=16; ibase=16; $SEARCH_UPPER + 10" | bc)
  172. break
  173. fi
  174.  
  175. SEARCH=$(echo "obase=16; ibase=16; $SEARCH_UPPER + 1" | bc)
  176. SEARCH=$(setpci -s $1 ${SEARCH}.b)
  177.  
  178. let SEARCH_COUNT=$SEARCH_COUNT+1
  179. done
  180.  
  181. if [[ $SEARCH_COUNT -ge $MAX_SEARCH ]]; then
  182. echo -e "Long loop while looking for ASPM word for $1"
  183. return 1
  184. fi
  185. return 0
  186. }
  187.  
  188. function enable_aspm_byte()
  189. {
  190. device_present $1 present
  191. if [[ $? -ne 0 ]]; then
  192. exit
  193. fi
  194.  
  195. find_aspm_byte_address $1
  196. if [[ $? -ne 0 ]]; then
  197. return 1
  198. fi
  199.  
  200. ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b)
  201. ASPM_BYTE_HEX=$(printf "%X" 0x${ASPM_BYTE_HEX})
  202. # setpci doesn't support a mask on the query yet, only on the set,
  203. # so to verify a setting on a mask we have no other optoin but
  204. # to do do this stuff ourselves.
  205. DESIRED_ASPM_BYTE_HEX=$(printf "%X" $(( (0x${ASPM_BYTE_HEX} & ~0x7) |0x${ASPM_SETTING})))
  206.  
  207. if [[ $ASPM_BYTE_ADDRESS = "INVALID" ]]; then
  208. echo -e "No ASPM byte could be found for $(lspci -s $1)"
  209. return
  210. fi
  211.  
  212. echo -e "$(lspci -s $1)"
  213. echo -en "\t${YELLOW}0x${ASPM_BYTE_ADDRESS}${NORMAL} : ${CYAN}0x${ASPM_BYTE_HEX}${GREEN} --> ${BLUE}0x${DESIRED_ASPM_BYTE_HEX}${NORMAL} ... "
  214.  
  215. device_present $1 present
  216. if [[ $? -ne 0 ]]; then
  217. exit
  218. fi
  219.  
  220. # Avoid setting if already set
  221. if [[ $ASPM_BYTE_HEX = $DESIRED_ASPM_BYTE_HEX ]]; then
  222. echo -n -e "[${GREEN}SUCESS${NORMAL}] (${GREEN}already set${NORMAL}) "
  223. aspm_setting_to_string $ASPM_SETTING
  224. return 0
  225. fi
  226.  
  227. # This only writes the last 3 bits
  228. setpci -s $1 ${ASPM_BYTE_ADDRESS}.b=${ASPM_SETTING}:3
  229.  
  230. sleep 0.1
  231.  
  232. ACTUAL_ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b)
  233. ACTUAL_ASPM_BYTE_HEX=$(printf "%X" 0x${ACTUAL_ASPM_BYTE_HEX})
  234.  
  235. # Do not retry this if it failed, if it failed to set.
  236. # Likey if it failed its a good reason and you should look
  237. # into that.
  238. if [[ $ACTUAL_ASPM_BYTE_HEX != $DESIRED_ASPM_BYTE_HEX ]]; then
  239. echo -e "[${RED}FAIL${NORMAL}] (0x${ACTUAL_ASPM_BYTE_HEX})"
  240. return 1
  241. fi
  242.  
  243. echo -n -e "[${GREEN}SUCCESS]${NORMAL} "
  244. aspm_setting_to_string $ASPM_SETTING
  245.  
  246. return 0
  247. }
  248.  
  249. device_present $ENDPOINT not_sure
  250. if [[ $? -ne 0 ]]; then
  251. exit
  252. fi
  253.  
  254. echo -e -n "${CYAN}Device${NORMAL}: "
  255. enable_aspm_byte $ENDPOINT
  256.  
Advertisement
Add Comment
Please, Sign In to add comment