1 #!/usr/bin/env python3 1 #!/usr/bin/env python3 2 # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Cl 2 # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 3 3 4 import argparse 4 import argparse 5 import json 5 import json 6 import pprint 6 import pprint 7 import sys 7 import sys 8 import re 8 import re 9 import os << 10 9 11 from lib import YnlFamily 10 from lib import YnlFamily 12 11 13 def args_to_req(ynl, op_name, args, req): 12 def args_to_req(ynl, op_name, args, req): 14 """ 13 """ 15 Verify and convert command-line arguments 14 Verify and convert command-line arguments to the ynl-compatible request. 16 """ 15 """ 17 valid_attrs = ynl.operation_do_attributes( 16 valid_attrs = ynl.operation_do_attributes(op_name) 18 valid_attrs.remove('header') # not user-pr 17 valid_attrs.remove('header') # not user-provided 19 18 20 if len(args) == 0: 19 if len(args) == 0: 21 print(f'no attributes, expected: {vali 20 print(f'no attributes, expected: {valid_attrs}') 22 sys.exit(1) 21 sys.exit(1) 23 22 24 i = 0 23 i = 0 25 while i < len(args): 24 while i < len(args): 26 attr = args[i] 25 attr = args[i] 27 if i + 1 >= len(args): 26 if i + 1 >= len(args): 28 print(f'expected value for \'{attr 27 print(f'expected value for \'{attr}\'') 29 sys.exit(1) 28 sys.exit(1) 30 29 31 if attr not in valid_attrs: 30 if attr not in valid_attrs: 32 print(f'invalid attribute \'{attr} 31 print(f'invalid attribute \'{attr}\', expected: {valid_attrs}') 33 sys.exit(1) 32 sys.exit(1) 34 33 35 val = args[i+1] 34 val = args[i+1] 36 i += 2 35 i += 2 37 36 38 req[attr] = val 37 req[attr] = val 39 38 40 def print_field(reply, *desc): 39 def print_field(reply, *desc): 41 """ 40 """ 42 Pretty-print a set of fields from the repl 41 Pretty-print a set of fields from the reply. desc specifies the 43 fields and the optional type (bool/yn). 42 fields and the optional type (bool/yn). 44 """ 43 """ 45 if len(desc) == 0: 44 if len(desc) == 0: 46 return print_field(reply, *zip(reply.k 45 return print_field(reply, *zip(reply.keys(), reply.keys())) 47 46 48 for spec in desc: 47 for spec in desc: 49 try: 48 try: 50 field, name, tp = spec 49 field, name, tp = spec 51 except: 50 except: 52 field, name = spec 51 field, name = spec 53 tp = 'int' 52 tp = 'int' 54 53 55 value = reply.get(field, None) 54 value = reply.get(field, None) 56 if tp == 'yn': 55 if tp == 'yn': 57 value = 'yes' if value else 'no' 56 value = 'yes' if value else 'no' 58 elif tp == 'bool' or isinstance(value, 57 elif tp == 'bool' or isinstance(value, bool): 59 value = 'on' if value else 'off' 58 value = 'on' if value else 'off' 60 else: 59 else: 61 value = 'n/a' if value is None els 60 value = 'n/a' if value is None else value 62 61 63 print(f'{name}: {value}') 62 print(f'{name}: {value}') 64 63 65 def print_speed(name, value): 64 def print_speed(name, value): 66 """ 65 """ 67 Print out the speed-like strings from the 66 Print out the speed-like strings from the value dict. 68 """ 67 """ 69 speed_re = re.compile(r'[0-9]+base[^/]+/.+ 68 speed_re = re.compile(r'[0-9]+base[^/]+/.+') 70 speed = [ k for k, v in value.items() if v 69 speed = [ k for k, v in value.items() if v and speed_re.match(k) ] 71 print(f'{name}: {" ".join(speed)}') 70 print(f'{name}: {" ".join(speed)}') 72 71 73 def doit(ynl, args, op_name): 72 def doit(ynl, args, op_name): 74 """ 73 """ 75 Prepare request header, parse arguments an 74 Prepare request header, parse arguments and doit. 76 """ 75 """ 77 req = { 76 req = { 78 'header': { 77 'header': { 79 'dev-name': args.device, 78 'dev-name': args.device, 80 }, 79 }, 81 } 80 } 82 81 83 args_to_req(ynl, op_name, args.args, req) 82 args_to_req(ynl, op_name, args.args, req) 84 ynl.do(op_name, req) 83 ynl.do(op_name, req) 85 84 86 def dumpit(ynl, args, op_name, extra = {}): 85 def dumpit(ynl, args, op_name, extra = {}): 87 """ 86 """ 88 Prepare request header, parse arguments an 87 Prepare request header, parse arguments and dumpit (filtering out the 89 devices we're not interested in). 88 devices we're not interested in). 90 """ 89 """ 91 reply = ynl.dump(op_name, { 'header': {} } 90 reply = ynl.dump(op_name, { 'header': {} } | extra) 92 if not reply: 91 if not reply: 93 return {} 92 return {} 94 93 95 for msg in reply: 94 for msg in reply: 96 if msg['header']['dev-name'] == args.d 95 if msg['header']['dev-name'] == args.device: 97 if args.json: 96 if args.json: 98 pprint.PrettyPrinter().pprint( 97 pprint.PrettyPrinter().pprint(msg) 99 sys.exit(0) 98 sys.exit(0) 100 msg.pop('header', None) 99 msg.pop('header', None) 101 return msg 100 return msg 102 101 103 print(f"Not supported for device {args.dev 102 print(f"Not supported for device {args.device}") 104 sys.exit(1) 103 sys.exit(1) 105 104 106 def bits_to_dict(attr): 105 def bits_to_dict(attr): 107 """ 106 """ 108 Convert ynl-formatted bitmask to a dict of 107 Convert ynl-formatted bitmask to a dict of bit=value. 109 """ 108 """ 110 ret = {} 109 ret = {} 111 if 'bits' not in attr: 110 if 'bits' not in attr: 112 return dict() 111 return dict() 113 if 'bit' not in attr['bits']: 112 if 'bit' not in attr['bits']: 114 return dict() 113 return dict() 115 for bit in attr['bits']['bit']: 114 for bit in attr['bits']['bit']: 116 if bit['name'] == '': 115 if bit['name'] == '': 117 continue 116 continue 118 name = bit['name'] 117 name = bit['name'] 119 value = bit.get('value', False) 118 value = bit.get('value', False) 120 ret[name] = value 119 ret[name] = value 121 return ret 120 return ret 122 121 123 def main(): 122 def main(): 124 parser = argparse.ArgumentParser(descripti 123 parser = argparse.ArgumentParser(description='ethtool wannabe') 125 parser.add_argument('--json', action=argpa 124 parser.add_argument('--json', action=argparse.BooleanOptionalAction) 126 parser.add_argument('--show-priv-flags', a 125 parser.add_argument('--show-priv-flags', action=argparse.BooleanOptionalAction) 127 parser.add_argument('--set-priv-flags', ac 126 parser.add_argument('--set-priv-flags', action=argparse.BooleanOptionalAction) 128 parser.add_argument('--show-eee', action=a 127 parser.add_argument('--show-eee', action=argparse.BooleanOptionalAction) 129 parser.add_argument('--set-eee', action=ar 128 parser.add_argument('--set-eee', action=argparse.BooleanOptionalAction) 130 parser.add_argument('-a', '--show-pause', 129 parser.add_argument('-a', '--show-pause', action=argparse.BooleanOptionalAction) 131 parser.add_argument('-A', '--set-pause', a 130 parser.add_argument('-A', '--set-pause', action=argparse.BooleanOptionalAction) 132 parser.add_argument('-c', '--show-coalesce 131 parser.add_argument('-c', '--show-coalesce', action=argparse.BooleanOptionalAction) 133 parser.add_argument('-C', '--set-coalesce' 132 parser.add_argument('-C', '--set-coalesce', action=argparse.BooleanOptionalAction) 134 parser.add_argument('-g', '--show-ring', a 133 parser.add_argument('-g', '--show-ring', action=argparse.BooleanOptionalAction) 135 parser.add_argument('-G', '--set-ring', ac 134 parser.add_argument('-G', '--set-ring', action=argparse.BooleanOptionalAction) 136 parser.add_argument('-k', '--show-features 135 parser.add_argument('-k', '--show-features', action=argparse.BooleanOptionalAction) 137 parser.add_argument('-K', '--set-features' 136 parser.add_argument('-K', '--set-features', action=argparse.BooleanOptionalAction) 138 parser.add_argument('-l', '--show-channels 137 parser.add_argument('-l', '--show-channels', action=argparse.BooleanOptionalAction) 139 parser.add_argument('-L', '--set-channels' 138 parser.add_argument('-L', '--set-channels', action=argparse.BooleanOptionalAction) 140 parser.add_argument('-T', '--show-time-sta 139 parser.add_argument('-T', '--show-time-stamping', action=argparse.BooleanOptionalAction) 141 parser.add_argument('-S', '--statistics', 140 parser.add_argument('-S', '--statistics', action=argparse.BooleanOptionalAction) 142 # TODO: --show-tunnels tunnel-info- 141 # TODO: --show-tunnels tunnel-info-get 143 # TODO: --show-module module-get 142 # TODO: --show-module module-get 144 # TODO: --get-plca-cfg plca-get 143 # TODO: --get-plca-cfg plca-get 145 # TODO: --get-plca-status plca-get-sta 144 # TODO: --get-plca-status plca-get-status 146 # TODO: --show-mm mm-get 145 # TODO: --show-mm mm-get 147 # TODO: --show-fec fec-get 146 # TODO: --show-fec fec-get 148 # TODO: --dump-module-eerpom module-eepro 147 # TODO: --dump-module-eerpom module-eeprom-get 149 # TODO: pse-get 148 # TODO: pse-get 150 # TODO: rss-get 149 # TODO: rss-get 151 parser.add_argument('device', metavar='dev 150 parser.add_argument('device', metavar='device', type=str) 152 parser.add_argument('args', metavar='args' 151 parser.add_argument('args', metavar='args', type=str, nargs='*') 153 global args 152 global args 154 args = parser.parse_args() 153 args = parser.parse_args() 155 154 156 script_abs_dir = os.path.dirname(os.path.a !! 155 spec = '../../../Documentation/netlink/specs/ethtool.yaml' 157 spec = os.path.join(script_abs_dir, !! 156 schema = '../../../Documentation/netlink/genetlink-legacy.yaml' 158 '../../../Documentatio << 159 schema = os.path.join(script_abs_dir, << 160 '../../../Documentat << 161 157 162 ynl = YnlFamily(spec, schema) 158 ynl = YnlFamily(spec, schema) 163 159 164 if args.set_priv_flags: 160 if args.set_priv_flags: 165 # TODO: parse the bitmask 161 # TODO: parse the bitmask 166 print("not implemented") 162 print("not implemented") 167 return 163 return 168 164 169 if args.set_eee: 165 if args.set_eee: 170 return doit(ynl, args, 'eee-set') 166 return doit(ynl, args, 'eee-set') 171 167 172 if args.set_pause: 168 if args.set_pause: 173 return doit(ynl, args, 'pause-set') 169 return doit(ynl, args, 'pause-set') 174 170 175 if args.set_coalesce: 171 if args.set_coalesce: 176 return doit(ynl, args, 'coalesce-set') 172 return doit(ynl, args, 'coalesce-set') 177 173 178 if args.set_features: 174 if args.set_features: 179 # TODO: parse the bitmask 175 # TODO: parse the bitmask 180 print("not implemented") 176 print("not implemented") 181 return 177 return 182 178 183 if args.set_channels: 179 if args.set_channels: 184 return doit(ynl, args, 'channels-set') 180 return doit(ynl, args, 'channels-set') 185 181 186 if args.set_ring: 182 if args.set_ring: 187 return doit(ynl, args, 'rings-set') 183 return doit(ynl, args, 'rings-set') 188 184 189 if args.show_priv_flags: 185 if args.show_priv_flags: 190 flags = bits_to_dict(dumpit(ynl, args, 186 flags = bits_to_dict(dumpit(ynl, args, 'privflags-get')['flags']) 191 print_field(flags) 187 print_field(flags) 192 return 188 return 193 189 194 if args.show_eee: 190 if args.show_eee: 195 eee = dumpit(ynl, args, 'eee-get') 191 eee = dumpit(ynl, args, 'eee-get') 196 ours = bits_to_dict(eee['modes-ours']) 192 ours = bits_to_dict(eee['modes-ours']) 197 peer = bits_to_dict(eee['modes-peer']) 193 peer = bits_to_dict(eee['modes-peer']) 198 194 199 if 'enabled' in eee: 195 if 'enabled' in eee: 200 status = 'enabled' if eee['enabled 196 status = 'enabled' if eee['enabled'] else 'disabled' 201 if 'active' in eee and eee['active 197 if 'active' in eee and eee['active']: 202 status = status + ' - active' 198 status = status + ' - active' 203 else: 199 else: 204 status = status + ' - inactive 200 status = status + ' - inactive' 205 else: 201 else: 206 status = 'not supported' 202 status = 'not supported' 207 203 208 print(f'EEE status: {status}') 204 print(f'EEE status: {status}') 209 print_field(eee, ('tx-lpi-timer', 'Tx 205 print_field(eee, ('tx-lpi-timer', 'Tx LPI')) 210 print_speed('Advertised EEE link modes 206 print_speed('Advertised EEE link modes', ours) 211 print_speed('Link partner advertised E 207 print_speed('Link partner advertised EEE link modes', peer) 212 208 213 return 209 return 214 210 215 if args.show_pause: 211 if args.show_pause: 216 print_field(dumpit(ynl, args, 'pause-g 212 print_field(dumpit(ynl, args, 'pause-get'), 217 ('autoneg', 'Autonegotiate', ' 213 ('autoneg', 'Autonegotiate', 'bool'), 218 ('rx', 'RX', 'bool'), 214 ('rx', 'RX', 'bool'), 219 ('tx', 'TX', 'bool')) 215 ('tx', 'TX', 'bool')) 220 return 216 return 221 217 222 if args.show_coalesce: 218 if args.show_coalesce: 223 print_field(dumpit(ynl, args, 'coalesc 219 print_field(dumpit(ynl, args, 'coalesce-get')) 224 return 220 return 225 221 226 if args.show_features: 222 if args.show_features: 227 reply = dumpit(ynl, args, 'features-ge 223 reply = dumpit(ynl, args, 'features-get') 228 available = bits_to_dict(reply['hw']) 224 available = bits_to_dict(reply['hw']) 229 requested = bits_to_dict(reply['wanted 225 requested = bits_to_dict(reply['wanted']).keys() 230 active = bits_to_dict(reply['active']) 226 active = bits_to_dict(reply['active']).keys() 231 never_changed = bits_to_dict(reply['no 227 never_changed = bits_to_dict(reply['nochange']).keys() 232 228 233 for f in sorted(available): 229 for f in sorted(available): 234 value = "off" 230 value = "off" 235 if f in active: 231 if f in active: 236 value = "on" 232 value = "on" 237 233 238 fixed = "" 234 fixed = "" 239 if f not in available or f in neve 235 if f not in available or f in never_changed: 240 fixed = " [fixed]" 236 fixed = " [fixed]" 241 237 242 req = "" 238 req = "" 243 if f in requested: 239 if f in requested: 244 if f in active: 240 if f in active: 245 req = " [requested on]" 241 req = " [requested on]" 246 else: 242 else: 247 req = " [requested off]" 243 req = " [requested off]" 248 244 249 print(f'{f}: {value}{fixed}{req}') 245 print(f'{f}: {value}{fixed}{req}') 250 246 251 return 247 return 252 248 253 if args.show_channels: 249 if args.show_channels: 254 reply = dumpit(ynl, args, 'channels-ge 250 reply = dumpit(ynl, args, 'channels-get') 255 print(f'Channel parameters for {args.d 251 print(f'Channel parameters for {args.device}:') 256 252 257 print(f'Pre-set maximums:') 253 print(f'Pre-set maximums:') 258 print_field(reply, 254 print_field(reply, 259 ('rx-max', 'RX'), 255 ('rx-max', 'RX'), 260 ('tx-max', 'TX'), 256 ('tx-max', 'TX'), 261 ('other-max', 'Other'), 257 ('other-max', 'Other'), 262 ('combined-max', 'Combined')) 258 ('combined-max', 'Combined')) 263 259 264 print(f'Current hardware settings:') 260 print(f'Current hardware settings:') 265 print_field(reply, 261 print_field(reply, 266 ('rx-count', 'RX'), 262 ('rx-count', 'RX'), 267 ('tx-count', 'TX'), 263 ('tx-count', 'TX'), 268 ('other-count', 'Other'), 264 ('other-count', 'Other'), 269 ('combined-count', 'Combined')) 265 ('combined-count', 'Combined')) 270 266 271 return 267 return 272 268 273 if args.show_ring: 269 if args.show_ring: 274 reply = dumpit(ynl, args, 'channels-ge 270 reply = dumpit(ynl, args, 'channels-get') 275 271 276 print(f'Ring parameters for {args.devi 272 print(f'Ring parameters for {args.device}:') 277 273 278 print(f'Pre-set maximums:') 274 print(f'Pre-set maximums:') 279 print_field(reply, 275 print_field(reply, 280 ('rx-max', 'RX'), 276 ('rx-max', 'RX'), 281 ('rx-mini-max', 'RX Mini'), 277 ('rx-mini-max', 'RX Mini'), 282 ('rx-jumbo-max', 'RX Jumbo'), 278 ('rx-jumbo-max', 'RX Jumbo'), 283 ('tx-max', 'TX')) 279 ('tx-max', 'TX')) 284 280 285 print(f'Current hardware settings:') 281 print(f'Current hardware settings:') 286 print_field(reply, 282 print_field(reply, 287 ('rx', 'RX'), 283 ('rx', 'RX'), 288 ('rx-mini', 'RX Mini'), 284 ('rx-mini', 'RX Mini'), 289 ('rx-jumbo', 'RX Jumbo'), 285 ('rx-jumbo', 'RX Jumbo'), 290 ('tx', 'TX')) 286 ('tx', 'TX')) 291 287 292 print_field(reply, 288 print_field(reply, 293 ('rx-buf-len', 'RX Buf Len'), 289 ('rx-buf-len', 'RX Buf Len'), 294 ('cqe-size', 'CQE Size'), 290 ('cqe-size', 'CQE Size'), 295 ('tx-push', 'TX Push', 'bool')) 291 ('tx-push', 'TX Push', 'bool')) 296 292 297 return 293 return 298 294 299 if args.statistics: 295 if args.statistics: 300 print(f'NIC statistics:') 296 print(f'NIC statistics:') 301 297 302 # TODO: pass id? 298 # TODO: pass id? 303 strset = dumpit(ynl, args, 'strset-get 299 strset = dumpit(ynl, args, 'strset-get') 304 pprint.PrettyPrinter().pprint(strset) 300 pprint.PrettyPrinter().pprint(strset) 305 301 306 req = { 302 req = { 307 'groups': { 303 'groups': { 308 'size': 1, 304 'size': 1, 309 'bits': { 305 'bits': { 310 'bit': 306 'bit': 311 # TODO: support passing the bi 307 # TODO: support passing the bitmask 312 #[ 308 #[ 313 #{ 'name': 'eth-phy', 'value 309 #{ 'name': 'eth-phy', 'value': True }, 314 { 'name': 'eth-mac', 'value' 310 { 'name': 'eth-mac', 'value': True }, 315 #{ 'name': 'eth-ctrl', 'valu 311 #{ 'name': 'eth-ctrl', 'value': True }, 316 #{ 'name': 'rmon', 'value': 312 #{ 'name': 'rmon', 'value': True }, 317 #], 313 #], 318 }, 314 }, 319 }, 315 }, 320 } 316 } 321 317 322 rsp = dumpit(ynl, args, 'stats-get', r 318 rsp = dumpit(ynl, args, 'stats-get', req) 323 pprint.PrettyPrinter().pprint(rsp) 319 pprint.PrettyPrinter().pprint(rsp) 324 return 320 return 325 321 326 if args.show_time_stamping: 322 if args.show_time_stamping: 327 req = { !! 323 tsinfo = dumpit(ynl, args, 'tsinfo-get') 328 'header': { << 329 'flags': 'stats', << 330 }, << 331 } << 332 << 333 tsinfo = dumpit(ynl, args, 'tsinfo-get << 334 324 335 print(f'Time stamping parameters for { 325 print(f'Time stamping parameters for {args.device}:') 336 326 337 print('Capabilities:') 327 print('Capabilities:') 338 [print(f'\t{v}') for v in bits_to_dict 328 [print(f'\t{v}') for v in bits_to_dict(tsinfo['timestamping'])] 339 329 340 print(f'PTP Hardware Clock: {tsinfo["p 330 print(f'PTP Hardware Clock: {tsinfo["phc-index"]}') 341 331 342 print('Hardware Transmit Timestamp Mod 332 print('Hardware Transmit Timestamp Modes:') 343 [print(f'\t{v}') for v in bits_to_dict 333 [print(f'\t{v}') for v in bits_to_dict(tsinfo['tx-types'])] 344 334 345 print('Hardware Receive Filter Modes:' 335 print('Hardware Receive Filter Modes:') 346 [print(f'\t{v}') for v in bits_to_dict 336 [print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])] 347 << 348 print('Statistics:') << 349 [print(f'\t{k}: {v}') for k, v in tsin << 350 return 337 return 351 338 352 print(f'Settings for {args.device}:') 339 print(f'Settings for {args.device}:') 353 linkmodes = dumpit(ynl, args, 'linkmodes-g 340 linkmodes = dumpit(ynl, args, 'linkmodes-get') 354 ours = bits_to_dict(linkmodes['ours']) 341 ours = bits_to_dict(linkmodes['ours']) 355 342 356 supported_ports = ('TP', 'AUI', 'BNC', 'M 343 supported_ports = ('TP', 'AUI', 'BNC', 'MII', 'FIBRE', 'Backplane') 357 ports = [ p for p in supported_ports if ou 344 ports = [ p for p in supported_ports if ours.get(p, False)] 358 print(f'Supported ports: [ {" ".join(ports 345 print(f'Supported ports: [ {" ".join(ports)} ]') 359 346 360 print_speed('Supported link modes', ours) 347 print_speed('Supported link modes', ours) 361 348 362 print_field(ours, ('Pause', 'Supported pau 349 print_field(ours, ('Pause', 'Supported pause frame use', 'yn')) 363 print_field(ours, ('Autoneg', 'Supports au 350 print_field(ours, ('Autoneg', 'Supports auto-negotiation', 'yn')) 364 351 365 supported_fec = ('None', 'PS', 'BASER', ' 352 supported_fec = ('None', 'PS', 'BASER', 'LLRS') 366 fec = [ p for p in supported_fec if ours.g 353 fec = [ p for p in supported_fec if ours.get(p, False)] 367 fec_str = " ".join(fec) 354 fec_str = " ".join(fec) 368 if len(fec) == 0: 355 if len(fec) == 0: 369 fec_str = "Not reported" 356 fec_str = "Not reported" 370 357 371 print(f'Supported FEC modes: {fec_str}') 358 print(f'Supported FEC modes: {fec_str}') 372 359 373 speed = 'Unknown!' 360 speed = 'Unknown!' 374 if linkmodes['speed'] > 0 and linkmodes['s 361 if linkmodes['speed'] > 0 and linkmodes['speed'] < 0xffffffff: 375 speed = f'{linkmodes["speed"]}Mb/s' 362 speed = f'{linkmodes["speed"]}Mb/s' 376 print(f'Speed: {speed}') 363 print(f'Speed: {speed}') 377 364 378 duplex_modes = { 365 duplex_modes = { 379 0: 'Half', 366 0: 'Half', 380 1: 'Full', 367 1: 'Full', 381 } 368 } 382 duplex = duplex_modes.get(linkmodes["duple 369 duplex = duplex_modes.get(linkmodes["duplex"], None) 383 if not duplex: 370 if not duplex: 384 duplex = f'Unknown! ({linkmodes["duple 371 duplex = f'Unknown! ({linkmodes["duplex"]})' 385 print(f'Duplex: {duplex}') 372 print(f'Duplex: {duplex}') 386 373 387 autoneg = "off" 374 autoneg = "off" 388 if linkmodes.get("autoneg", 0) != 0: 375 if linkmodes.get("autoneg", 0) != 0: 389 autoneg = "on" 376 autoneg = "on" 390 print(f'Auto-negotiation: {autoneg}') 377 print(f'Auto-negotiation: {autoneg}') 391 378 392 ports = { 379 ports = { 393 0: 'Twisted Pair', 380 0: 'Twisted Pair', 394 1: 'AUI', 381 1: 'AUI', 395 2: 'MII', 382 2: 'MII', 396 3: 'FIBRE', 383 3: 'FIBRE', 397 4: 'BNC', 384 4: 'BNC', 398 5: 'Directly Attached Copper', 385 5: 'Directly Attached Copper', 399 0xef: 'None', 386 0xef: 'None', 400 } 387 } 401 linkinfo = dumpit(ynl, args, 'linkinfo-get 388 linkinfo = dumpit(ynl, args, 'linkinfo-get') 402 print(f'Port: {ports.get(linkinfo["port"], 389 print(f'Port: {ports.get(linkinfo["port"], "Other")}') 403 390 404 print_field(linkinfo, ('phyaddr', 'PHYAD') 391 print_field(linkinfo, ('phyaddr', 'PHYAD')) 405 392 406 transceiver = { 393 transceiver = { 407 0: 'Internal', 394 0: 'Internal', 408 1: 'External', 395 1: 'External', 409 } 396 } 410 print(f'Transceiver: {transceiver.get(link 397 print(f'Transceiver: {transceiver.get(linkinfo["transceiver"], "Unknown")}') 411 398 412 mdix_ctrl = { 399 mdix_ctrl = { 413 1: 'off', 400 1: 'off', 414 2: 'on', 401 2: 'on', 415 } 402 } 416 mdix = mdix_ctrl.get(linkinfo['tp-mdix-ctr 403 mdix = mdix_ctrl.get(linkinfo['tp-mdix-ctrl'], None) 417 if mdix: 404 if mdix: 418 mdix = mdix + ' (forced)' 405 mdix = mdix + ' (forced)' 419 else: 406 else: 420 mdix = mdix_ctrl.get(linkinfo['tp-mdix 407 mdix = mdix_ctrl.get(linkinfo['tp-mdix'], 'Unknown (auto)') 421 print(f'MDI-X: {mdix}') 408 print(f'MDI-X: {mdix}') 422 409 423 debug = dumpit(ynl, args, 'debug-get') 410 debug = dumpit(ynl, args, 'debug-get') 424 msgmask = bits_to_dict(debug.get("msgmask" 411 msgmask = bits_to_dict(debug.get("msgmask", [])).keys() 425 print(f'Current message level: {" ".join(m 412 print(f'Current message level: {" ".join(msgmask)}') 426 413 427 linkstate = dumpit(ynl, args, 'linkstate-g 414 linkstate = dumpit(ynl, args, 'linkstate-get') 428 detected_states = { 415 detected_states = { 429 0: 'no', 416 0: 'no', 430 1: 'yes', 417 1: 'yes', 431 } 418 } 432 # TODO: wol-get 419 # TODO: wol-get 433 detected = detected_states.get(linkstate[' 420 detected = detected_states.get(linkstate['link'], 'unknown') 434 print(f'Link detected: {detected}') 421 print(f'Link detected: {detected}') 435 422 436 if __name__ == '__main__': 423 if __name__ == '__main__': 437 main() 424 main()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.