blob: 9fe6c8b02e76c76daaea38ef39d5f4fd4ffa2a60 [file] [log] [blame]
Damjan Marion98a5d812018-06-09 15:11:52 +02001#!/bin/bash
2
3function die() {
4 echo "ERROR: $*" >&2
5 exit 1
6}
Damjan Marionf4901f32019-01-31 19:41:50 +01007function pci-unbind() {
8 echo $1 | sudo tee /sys/bus/pci/devices/$1/driver/unbind > /dev/null
9}
10function pci-bind() {
11 pci-unbind $1
12 echo $2 | sudo tee /sys/bus/pci/devices/$1/driver_override > /dev/null
13 echo $1 | sudo tee /sys/bus/pci/drivers/$2/bind > /dev/null
14 echo | sudo tee /sys/bus/pci/devices/$1/driver_override > /dev/null
15}
Damjan Marion98a5d812018-06-09 15:11:52 +020016
17function show_vfs() {
18 path=$1
19 netdev=$2
20 printf "\nVirtual Functions:\n%-2s %-12s %-9s %-12s %-17s %s\n" \
21 "ID" "PCI Addr" "PCI ID" "Driver" "MAC Addr" "Config"
22 for vf_path in ${path}/virtfn*; do
23 vf=$(basename $(readlink ${vf_path}))
24 vfid=$(basename ${vf_path//virtfn/})
25 line=$(ip link show dev ${netdev} | grep "vf ${vfid}")
26 driver=$(basename $(readlink ${vf_path}/driver))
27 pciid="$(cat ${vf_path}/vendor | cut -dx -f2):$(cat ${vf_path}/device | cut -dx -f2)"
28 mac=$(echo $line | sed -n -E -e 's/.*MAC ([0-9a-f:]+),.*/\1/p')
29 cfg=$(echo $line | cut -d, -f2-)
30
31 printf "%-2s %-12s %-9s %-12s %-17s%s\n" \
32 $vfid $vf $pciid $driver $mac "$cfg"
33 done
34}
35function get_pci_addr() {
36 local addr
37 if [ -d /sys/class/net/$2/device ]; then
38 addr=$(basename $(readlink /sys/class/net/${2}/device))
39 else
40 addr=$2
41 fi
42 if [ ! -d /sys/bus/pci/devices/${pci_addr} ]; then
43 die "PCI device $2 doesn't exist"
44 fi
45 eval "$1=${addr}"
46}
47
48function show () {
49 get_pci_addr pci_addr $1
50 path="/sys/bus/pci/devices/${pci_addr}"
51
52 if [ ! -f ${path}/sriov_numvfs ]; then
53 die "PCI device $1 is not SR-IOV device"
54 fi
55
56 printf "%-20s: %s\n" "PCI Address" ${pci_addr}
57 printf "%-20s: %s\n" "PCI ID" \
58 "$(cat ${path}/vendor | cut -dx -f2):$(cat ${path}/device | cut -dx -f2)"
59 printf "%-20s: %s\n" "Driver name" $(basename $(readlink ${path}/driver))
60 printf "%-20s: %s\n" "Driver Version" $(cat ${path}/driver/module/version)
61 printf "%-20s: %s\n" "PCI Link Speed (max)" "$(cat ${path}/current_link_speed) ($(cat ${path}/max_link_speed))"
62 printf "%-20s: %s\n" "PCI Link Width (max)" "$(cat ${path}/current_link_width) ($(cat ${path}/max_link_width))"
63 printf "%-20s: %s\n" "NUMA Node" $(cat ${path}/numa_node)
64 printf "%-20s: %s\n" "Number of VFs" $(cat ${path}/sriov_numvfs)
65 printf "%-20s: %s\n" "Total VFs" $(cat ${path}/sriov_totalvfs)
66 if [ -d ${path}/net/* ] ; then
67 netdev=$(basename ${path}/net/*)
68 netdev_path=${path}/net/${netdev}
69 printf "%-20s: %s\n" "Interface" ${netdev}
70 printf "%-20s: %s\n" "MAC Address" $(cat ${netdev_path}/address)
71 printf "%-20s: %s\n" "Speed" $(cat ${netdev_path}/speed)
72 printf "%-20s: %s\n" "State" $(cat ${netdev_path}/operstate)
73 fi
74
75 [ $(cat ${path}/sriov_numvfs) -gt 0 ] && show_vfs ${path} ${netdev}
76}
77
78function remove_all () {
79 get_pci_addr pci_addr $1
80 path="/sys/bus/pci/devices/${pci_addr}"
81 [ $(cat ${path}/sriov_numvfs) -gt 0 ] || die "No VFs configured on $1"
82 echo 0 | sudo tee ${path}/sriov_numvfs > /dev/null
83 echo "VFs removed..."
84}
85
86function create () {
87 get_pci_addr pci_addr $1
88 path="/sys/bus/pci/devices/${pci_addr}"
89 [ $(cat ${path}/sriov_numvfs) -gt 0 ] && die "VFs already configured on $1"
90 [ "0$2" -gt 0 ] || die "Please specify number of VFs to create"
91 echo $2 | sudo tee ${path}/sriov_numvfs > /dev/null
92 [ -d ${path}/net/* ] || die "No net device for $1"
93 netdev=$(basename ${path}/net/*)
94 netdev_path=${path}/net/${netdev}
95
96 mac_prefix=$(cat ${netdev_path}/address | cut -d: -f1,3,4,5,6 )
97 for vf_path in ${path}/virtfn*; do
98 vf=$(basename $(readlink ${vf_path}))
99 vfid=$(basename ${vf_path//virtfn/})
100 mac="${mac_prefix}:$(printf "%02x" ${vfid})"
101 sudo ip link set dev ${netdev} vf ${vfid} mac ${mac}
Damjan Marion539e6372018-10-26 13:43:43 +0200102 sudo ip link set dev ${netdev} vf ${vfid} trust on
103 sudo ip link set dev ${netdev} vf ${vfid} spoofchk off
Damjan Marionf4901f32019-01-31 19:41:50 +0100104 pci-bind ${vf} vfio-pci
Damjan Marion98a5d812018-06-09 15:11:52 +0200105 done
106
107 [ $(cat ${path}/sriov_numvfs) -gt 0 ] && show_vfs ${path} ${netdev}
108}
109
110function help() {
111
112cat << __EOF__
113
114$0 show <dev>
115 Displays information about <dev> where <dev> is PCI address
116 or linux interface name.
117
118$0 remove-all <dev>
119 Remove all virtual functions from device <dev>.
120
Damjan Marion539e6372018-10-26 13:43:43 +0200121$0 create <dev> <num>
Damjan Marion98a5d812018-06-09 15:11:52 +0200122 Create <num> virtual functions on device<dev>.
123__EOF__
124}
125
126case $1 in
127 show)
128 show $2
129 ;;
130 create)
131 create $2 $3
132 ;;
133 remove-all)
134 remove_all $2
135 ;;
136 help)
137 help $2
138 ;;
139 *)
140 echo "Please specify command (show, create, remove-all)"
141 help
142 ;;
143esac
144