forked from safchain/ethtool
/
ethtool_cmd_settings.go
150 lines (118 loc) · 3.77 KB
/
ethtool_cmd_settings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package ethtool
import (
"errors"
"fmt"
"unsafe"
)
type EthtoolLinkSettings struct {
Cmd uint32
Speed uint32
Duplex uint8
Port uint8
Phy_address uint8
Autoneg uint8
Mdio_support uint8
Eth_tp_mdix uint8
Eth_tp_mdix_ctrl uint8
Link_mode_masks_nwords int8
Transceiver uint8
Reserved1 [3]uint8
Reserved [7]uint32
Link_mode_masks [ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 * 3]uint32
}
type EthtoolLinkNegotiations struct {
Supported uint64
Advertising uint64
LpAdvertising uint64
}
func (ecmd *EthtoolLinkSettings) CmdGet(intf string) error {
e, err := NewEthtool()
if err != nil {
return err
}
defer e.Close()
return e.CmdGetLinkSetting(ecmd, intf)
}
func (ecmd *EthtoolLinkSettings) CmdSet(intf string) error {
e, err := NewEthtool()
if err != nil {
return err
}
defer e.Close()
return e.CmdSetLinkSetting(ecmd, intf)
}
func (ecmd *EthtoolLinkSettings) ParseNegotiations() (*EthtoolLinkNegotiations, error) {
if ecmd.Cmd != ETHTOOL_GLINKSETTINGS {
return nil, errors.New("must CmdGet before parsing")
}
if ecmd.Link_mode_masks_nwords <= 0 {
return nil, errors.New("nwords not set")
}
negotiations := &EthtoolLinkNegotiations{}
multiplicator := int(ecmd.Link_mode_masks_nwords)
offset := 0
nego := uint64(ecmd.Link_mode_masks[offset+1])
negotiations.Supported = (nego << 32) | uint64(ecmd.Link_mode_masks[offset])
offset += multiplicator
nego = uint64(ecmd.Link_mode_masks[offset+1])
negotiations.Advertising = (nego << 32) | uint64(ecmd.Link_mode_masks[offset])
offset += multiplicator
nego = uint64(ecmd.Link_mode_masks[offset+1])
negotiations.LpAdvertising = (nego << 32) | uint64(ecmd.Link_mode_masks[offset])
return negotiations, nil
}
func (ecmd *EthtoolLinkSettings) SetNegotiation(negotiations *EthtoolLinkNegotiations) error {
if ecmd.Cmd != ETHTOOL_GLINKSETTINGS {
return errors.New("must CmdGet before parsing")
}
if ecmd.Link_mode_masks_nwords <= 0 {
return errors.New("nwords not set")
}
l := uint32(negotiations.Supported & uint64(^uint32(0)))
h := uint32(negotiations.Supported >> 32)
offset := 0
ecmd.Link_mode_masks[offset] = l
ecmd.Link_mode_masks[offset+1] = h
l = uint32(negotiations.Advertising & uint64(^uint32(0)))
h = uint32(negotiations.Advertising >> 32)
offset += int(ecmd.Link_mode_masks_nwords)
ecmd.Link_mode_masks[offset] = l
ecmd.Link_mode_masks[offset+1] = h
l = uint32(negotiations.LpAdvertising & uint64(^uint32(0)))
h = uint32(negotiations.LpAdvertising >> 32)
offset += int(ecmd.Link_mode_masks_nwords)
ecmd.Link_mode_masks[offset] = l
ecmd.Link_mode_masks[offset+1] = h
return nil
}
// CmdGetLinkSetting returns the interface settings in the receiver struct
// and returns speed
func (e *Ethtool) CmdGetLinkSetting(ecmd *EthtoolLinkSettings, intf string) error {
ecmd.Cmd = ETHTOOL_GLINKSETTINGS
err := e.ioctl(intf, uintptr(unsafe.Pointer(ecmd)))
if err != nil {
return fmt.Errorf("getKernelNwords: %s", err)
}
ecmd.Link_mode_masks_nwords *= -1
err = e.ioctl(intf, uintptr(unsafe.Pointer(ecmd)))
if err != nil {
return fmt.Errorf("getEthtoolLinkSettings: %s", err)
}
return nil
}
// CmdGetLinkSetting returns the interface settings in the receiver struct
// and returns speed
func (e *Ethtool) CmdSetLinkSetting(ecmd *EthtoolLinkSettings, intf string) error {
if ecmd.Cmd != ETHTOOL_GLINKSETTINGS {
return errors.New("load data before saving")
}
if ecmd.Link_mode_masks_nwords <= 0 {
return errors.New("nwords must be filled with CmdGetLinkSetting")
}
ecmd.Cmd = ETHTOOL_SLINKSETTINGS
err := e.ioctl(intf, uintptr(unsafe.Pointer(ecmd)))
if err != nil {
return fmt.Errorf("set link settings: %s", err)
}
return nil
}