-
Notifications
You must be signed in to change notification settings - Fork 6
/
platform.go
145 lines (124 loc) · 3.82 KB
/
platform.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
// Copyright © 2017 Platina Systems, Inc. All rights reserved.
// Use of this source code is governed by the GPL-2 license described in the
// LICENSE file.
package mk1
import (
"github.com/platinasystems/i2c"
"github.com/platinasystems/vnet"
"github.com/platinasystems/vnet/devices/bus/pci"
fe1 "github.com/platinasystems/vnet/devices/ethernet/switch/fe1"
"github.com/platinasystems/vnet/ethernet"
"github.com/platinasystems/vnet/gre"
ipcli "github.com/platinasystems/vnet/ip/cli"
"github.com/platinasystems/vnet/ip4"
"github.com/platinasystems/vnet/ip6"
"github.com/platinasystems/vnet/pg"
fe1_platform "github.com/platinasystems/vnet/platforms/fe1"
"github.com/platinasystems/vnet/unix"
"os"
"time"
)
func PlatformInit(v *vnet.Vnet, p *fe1_platform.Platform) (err error) {
if !p.KernelIxgbe {
fi, ferr := os.Stat("/sys/bus/pci/drivers/ixgbe")
p.KernelIxgbe = ferr == nil && fi.IsDir()
fi, ferr = os.Stat("/sys/bus/pci/drivers/ixgbevf")
p.KernelIxgbevf = ferr == nil && fi.IsDir()
}
// Select packages we want to run with.
m4 := ip4.Init(v)
m6 := ip6.Init(v)
gre.Init(v)
ethernet.Init(v, m4, m6)
pci.Init(v)
pg.Init(v)
ipcli.Init(v)
unix.Init(v, unix.Config{RxInjectNodeName: "fe1-cpu"})
gpio := pca9535_main{
bus_index: 0,
bus_address: 0x74,
}
if err = gpio.do(gpio.led_output_enable); err != nil {
return
}
if !p.DisableGpioSwitchReset {
if err = gpio.do(gpio.switch_reset); err != nil {
return
}
}
if true {
qsfpInit(v, p)
}
fe1.Init(v, p)
fe1.AddPlatform(v, p)
return
}
func PlatformExit(v *vnet.Vnet, p *fe1_platform.Platform) error {
return nil
}
type pca9535_main struct {
bus_index, bus_address int
}
func (m *pca9535_main) do(f func(bus *i2c.Bus) error) (err error) {
return i2c.Do(m.bus_index, m.bus_address, f)
}
const (
pca9535_reg_input_0 = iota // read-only input bits [7:0]
pca9535_reg_input_1 // read-only input bits [15:8]
pca9535_reg_output_0 // output bits [7:0] (default 1)
pca9535_reg_output_1 // output [15:8]
pca9535_reg_invert_polarity_0
pca9535_reg_invert_polarity_1
pca9535_reg_is_input_0 // 1 => pin is input; 0 => output
pca9535_reg_is_input_1 // defaults are 1 (pin is input)
)
// MK1 pin usage.
const (
mk1_pca9535_pin_switch_reset = 1 << iota
_
mk1_pca9535_pin_led_output_enable
)
// MK1 board front panel port LED's require PCA9535 GPIO device configuration
// to provide an output signal that allows LED operation.
func (m *pca9535_main) led_output_enable(bus *i2c.Bus) (err error) {
var d i2c.SMBusData
// Set pin to output (default is input and default value is high which we assume).
if err = bus.Read(pca9535_reg_is_input_0, i2c.ByteData, &d); err != nil {
return
}
d[0] &^= mk1_pca9535_pin_led_output_enable
return bus.Write(pca9535_reg_is_input_0, i2c.ByteData, &d)
}
// Hard reset switch via gpio pins on MK1 board.
func (m *pca9535_main) switch_reset(bus *i2c.Bus) (err error) {
const reset_bits = mk1_pca9535_pin_switch_reset
//var val, dir i2c.SMBusData
var val, out i2c.SMBusData
// Set direction to output.
if err = bus.Read(pca9535_reg_output_0, i2c.ByteData, &out); err != nil {
return
}
if out[0]&reset_bits != 0 {
out[0] &^= reset_bits
if err = bus.Write(pca9535_reg_output_0, i2c.ByteData, &out); err != nil {
return
}
}
// Set output low & wait 2 us minimum.
if err = bus.Read(pca9535_reg_is_input_0, i2c.ByteData, &val); err != nil {
return
}
val[0] &^= reset_bits
if err = bus.Write(pca9535_reg_is_input_0, i2c.ByteData, &val); err != nil {
return
}
time.Sleep(2 * time.Microsecond)
// Set output hi & wait 2 ms minimum before pci activity.
val[0] |= reset_bits
if err = bus.Write(pca9535_reg_is_input_0, i2c.ByteData, &val); err != nil {
return
}
// Need to wait a long time else the switch does not show up in pci bus and pci discovery fails.
time.Sleep(100 * time.Millisecond)
return
}