blob: fea885da7f3aedda39679d00b4076db559c488d2 [file] [log] [blame]
Potin Lai01e83552022-04-01 11:15:40 +08001#!/bin/bash
2#
3# mdio-util - MDIO Utility for AST2600
4#
5# This shell script provides the ability to access MDIO bus over devmem
6#
7# TODO: A read/write action contains multiple MDIO operations, it needs a
8# lock to protect entire action.
9
10
11RETRY_CNT=30
12RETRY_DEALY_SEC="0.1"
13
14MDIO_BASE_REG=$((16#1e650000))
15C22_READ_CMD=$((16#98000000))
16C22_WRITE_CMD=$((16#94000000))
17
18C45_ADDR_CMD=$((16#80000000))
19C45_WRITE_CMD=$((16#84000000))
20C45_PREAD_CMD=$((16#88000000))
21C45_READ_CMD=$((16#8C000000))
22
23PHY_ADDR_STEP=$((16#200000))
24DEV_ADDR_STEP=$((16#10000))
25REG_ADDR_STEP=$((16#10000))
26
27aspeed_mdio_c22_read() {
28 BUS=$1
29 PHY_ADDR=$2
30 REG_ADDR=$3
31
32 MDIO_CTRL_REG=$((MDIO_BASE_REG+BUS*8))
33 MDIO_DATA_REG=$((MDIO_CTRL_REG+4))
34
35 CMD=$((C22_READ_CMD+PHY_ADDR*PHY_ADDR_STEP+REG_ADDR*REG_ADDR_STEP))
36
37 # write control register
38 devmem $MDIO_CTRL_REG 32 $CMD
39 for i in $(seq 1 1 $RETRY_CNT)
40 do
41 CHECK_STR=$(devmem $MDIO_CTRL_REG)
42 CHECK_VAL=$((16#${CHECK_STR#"0x"}))
43 if [ $((CHECK_VAL&16#80000000)) -eq 0 ]; then
44 break
45 elif [ "$i" -eq "${RETRY_CNT}" ]; then
46 echo "[c22] read operation timeout"
47 return 1
48 fi
49 sleep "$RETRY_DEALY_SEC"
50 done
51
52 # read data register
53 for i in $(seq 1 1 $RETRY_CNT)
54 do
55 DATA_STR=$(devmem $MDIO_DATA_REG)
56 DATA_VAL=$((16#${DATA_STR#"0x"}))
57 if [ $((DATA_VAL&16#00010000)) -ne 0 ]; then
58 DATA_VAL=$((DATA_VAL&16#0000FFFF))
59 echo "0x$(printf %04x $DATA_VAL)"
60 break
61 elif [ "$i" -eq "$RETRY_CNT" ]; then
62 echo "[c22] read data timeout"
63 return 1
64 fi
65 sleep "$RETRY_DEALY_SEC"
66 done
67
68 return 0
69}
70
71aspeed_mdio_c22_write() {
72 BUS=$1
73 PHY_ADDR=$2
74 REG_ADDR=$3
75 WR_DATA=$4
76
77 MDIO_CTRL_REG=$((MDIO_BASE_REG+BUS*8))
78 MDIO_DATA_REG=$((MDIO_CTRL_REG+4))
79 CMD=$((C22_WRITE_CMD+PHY_ADDR*PHY_ADDR_STEP+REG_ADDR*REG_ADDR_STEP+WR_DATA))
80
81 # write control register
82 devmem $MDIO_CTRL_REG 32 $CMD
83 for i in $(seq 1 1 $RETRY_CNT)
84 do
85 CHECK_STR=$(devmem $MDIO_CTRL_REG)
86 CHECK_VAL=$((16#${CHECK_STR#"0x"}))
87 if [ $((CHECK_VAL&16#80000000)) -eq 0 ]; then
88 break
89 elif [ "$i" -eq "$RETRY_CNT" ]; then
90 echo "[c22] write operation timeout"
91 return 1
92 fi
93 sleep "$RETRY_DEALY_SEC"
94 done
95
96 return 0
97}
98
99aspeed_mdio_c45_ctrl() {
100 BUS=$1
101 C45_OP=$2
102 PHY_ADDR=$3
103 DEV_ADDR=$4
104 CMD_DATA=$5
105
106 MDIO_CTRL_REG=$((MDIO_BASE_REG+BUS*8))
107
108 case "$C45_OP" in
109 0)
110 CMD=$C45_ADDR_CMD
111 ;;
112 1)
113 CMD=$C45_WRITE_CMD
114 ;;
115 2)
116 CMD=$C45_PREAD_CMD
117 ;;
118 3)
119 CMD=$C45_READ_CMD
120 ;;
121 *)
122 echo "[c45] unknow operator $C45_OP"
123 return 1
124 ;;
125 esac
126
127 CMD=$((CMD+PHY_ADDR*PHY_ADDR_STEP+DEV_ADDR*DEV_ADDR_STEP+CMD_DATA))
128
129 # write control register
130 devmem $MDIO_CTRL_REG 32 $CMD
131 for i in $(seq 1 1 $RETRY_CNT)
132 do
133 CHECK_STR=$(devmem $MDIO_CTRL_REG)
134 CHECK_VAL=$((16#${CHECK_STR#"0x"}))
135 if [ $((CHECK_VAL&16#80000000)) -eq 0 ]; then
136 break
137 elif [ "$i" -eq "$RETRY_CNT" ]; then
138 echo "[c45] operation timeout, op: $C45_OP"
139 return 1
140 fi
141 sleep "$RETRY_DEALY_SEC"
142 done
143
144 return 0
145}
146
147aspeed_mdio_c45_data() {
148 BUS=$1
149 PHY_ADDR=$2
150 DEV_ADDR=$3
151
152 MDIO_CTRL_REG=$((MDIO_BASE_REG+BUS*8))
153 MDIO_DATA_REG=$((MDIO_CTRL_REG+4))
154
155 # read data register
156 for i in $(seq 1 1 $RETRY_CNT)
157 do
158 DATA_STR=$(devmem $MDIO_DATA_REG)
159 DATA_VAL=$((16#${DATA_STR#"0x"}))
160 if [ $((DATA_VAL&16#00010000)) -ne 0 ]; then
161 DATA_VAL=$((DATA_VAL&16#0000FFFF))
162 echo "0x$(printf %04x $DATA_VAL)"
163 break
164 elif [ "$i" -eq "$RETRY_CNT" ]; then
165 echo "[c45] read data timeout"
166 return 1
167 fi
168 sleep "$RETRY_DEALY_SEC"
169 done
170
171 return 0
172}
173
174print_usage() {
175 echo "Usage:"
176 echo " [clause 22]"
177 echo " $0 c22 r <BUS> <PHY_ADDR> <REG_ADDR>"
178 echo " $0 c22 w <BUS> <PHY_ADDR> <REG_ADDR> <DATA>"
179 echo " [clause 45]"
180 echo " $0 c45 r <BUS> <PHY_ADDR> <DEV_ADDR> <REG_ADDR>"
181 echo " $0 c45 w <BUS> <PHY_ADDR> <DEV_ADDR> <REG_ADDR> <DATA>"
182}
183
184CLAUSE_VER=${1}
185CMD_TYPE=${2}
186BUS=$3
187PHY_ADDR=$4
188
189if [ ! -c /dev/mem ]; then
190 mknod /dev/mem c 1 1
191fi
192
193if [ "$CLAUSE_VER" == "c22" ] && [ "$CMD_TYPE" == "r" ] && [ "$#" -eq 5 ]; then
194 REG_ADDR=${5}
195 aspeed_mdio_c22_read "$BUS" "$PHY_ADDR" "$REG_ADDR" || exit 1
196elif [ "$CLAUSE_VER" == "c22" ] && [ "$CMD_TYPE" == "w" ] && [ "$#" -eq 6 ]; then
197 REG_ADDR=${5}
198 DATA=${6}
Potin Laic7fec312022-05-12 11:43:30 +0800199 aspeed_mdio_c22_write "$BUS" "$PHY_ADDR" "$REG_ADDR" "$DATA" || exit 1
Potin Lai01e83552022-04-01 11:15:40 +0800200elif [ "$CLAUSE_VER" == "c45" ] && [ "$CMD_TYPE" == "r" ] && [ "$#" -eq 6 ]; then
201 DEV_ADDR=${5}
202 REG_ADDR=${6}
203 aspeed_mdio_c45_ctrl "$BUS" 0 "$PHY_ADDR" "$DEV_ADDR" "$REG_ADDR" || exit 1
204 aspeed_mdio_c45_ctrl "$BUS" 3 "$PHY_ADDR" "$DEV_ADDR" "$REG_ADDR" || exit 1
205 aspeed_mdio_c45_data "$BUS" "$PHY_ADDR" "$DEV_ADDR" || exit 1
206elif [ "$CLAUSE_VER" == "c45" ] && [ "$CMD_TYPE" == "w" ] && [ "$#" -eq 7 ]; then
207 DEV_ADDR=${5}
208 REG_ADDR=${6}
209 DATA=${7}
210 aspeed_mdio_c45_ctrl "$BUS" 0 "$PHY_ADDR" "$DEV_ADDR" "$REG_ADDR" || exit 1
211 aspeed_mdio_c45_ctrl "$BUS" 1 "$PHY_ADDR" "$DEV_ADDR" "$DATA" || exit 1
212else
213 print_usage
214fi