13
13
#include "txgbe_aml.h"
14
14
#include "txgbe_hw.h"
15
15
16
+ void txgbe_gpio_init_aml (struct wx * wx )
17
+ {
18
+ u32 status ;
19
+
20
+ wr32 (wx , WX_GPIO_INTTYPE_LEVEL , TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 );
21
+ wr32 (wx , WX_GPIO_INTEN , TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 );
22
+
23
+ status = rd32 (wx , WX_GPIO_INTSTATUS );
24
+ for (int i = 0 ; i < 6 ; i ++ ) {
25
+ if (status & BIT (i ))
26
+ wr32 (wx , WX_GPIO_EOI , BIT (i ));
27
+ }
28
+ }
29
+
30
+ irqreturn_t txgbe_gpio_irq_handler_aml (int irq , void * data )
31
+ {
32
+ struct txgbe * txgbe = data ;
33
+ struct wx * wx = txgbe -> wx ;
34
+ u32 status ;
35
+
36
+ wr32 (wx , WX_GPIO_INTMASK , 0xFF );
37
+ status = rd32 (wx , WX_GPIO_INTSTATUS );
38
+ if (status & TXGBE_GPIOBIT_2 ) {
39
+ set_bit (WX_FLAG_NEED_SFP_RESET , wx -> flags );
40
+ wr32 (wx , WX_GPIO_EOI , TXGBE_GPIOBIT_2 );
41
+ wx_service_event_schedule (wx );
42
+ }
43
+ if (status & TXGBE_GPIOBIT_3 ) {
44
+ set_bit (WX_FLAG_NEED_LINK_CONFIG , wx -> flags );
45
+ wx_service_event_schedule (wx );
46
+ wr32 (wx , WX_GPIO_EOI , TXGBE_GPIOBIT_3 );
47
+ }
48
+
49
+ wr32 (wx , WX_GPIO_INTMASK , 0 );
50
+ return IRQ_HANDLED ;
51
+ }
52
+
53
+ static int txgbe_identify_sfp_hostif (struct wx * wx , struct txgbe_hic_i2c_read * buffer )
54
+ {
55
+ buffer -> hdr .cmd = FW_READ_SFP_INFO_CMD ;
56
+ buffer -> hdr .buf_len = sizeof (struct txgbe_hic_i2c_read ) -
57
+ sizeof (struct wx_hic_hdr );
58
+ buffer -> hdr .cmd_or_resp .cmd_resv = FW_CEM_CMD_RESERVED ;
59
+
60
+ return wx_host_interface_command (wx , (u32 * )buffer ,
61
+ sizeof (struct txgbe_hic_i2c_read ),
62
+ WX_HI_COMMAND_TIMEOUT , true);
63
+ }
64
+
65
+ static int txgbe_set_phy_link_hostif (struct wx * wx , int speed , int autoneg , int duplex )
66
+ {
67
+ struct txgbe_hic_ephy_setlink buffer ;
68
+
69
+ buffer .hdr .cmd = FW_PHY_SET_LINK_CMD ;
70
+ buffer .hdr .buf_len = sizeof (struct txgbe_hic_ephy_setlink ) -
71
+ sizeof (struct wx_hic_hdr );
72
+ buffer .hdr .cmd_or_resp .cmd_resv = FW_CEM_CMD_RESERVED ;
73
+
74
+ switch (speed ) {
75
+ case SPEED_25000 :
76
+ buffer .speed = TXGBE_LINK_SPEED_25GB_FULL ;
77
+ break ;
78
+ case SPEED_10000 :
79
+ buffer .speed = TXGBE_LINK_SPEED_10GB_FULL ;
80
+ break ;
81
+ }
82
+
83
+ buffer .fec_mode = TXGBE_PHY_FEC_AUTO ;
84
+ buffer .autoneg = autoneg ;
85
+ buffer .duplex = duplex ;
86
+
87
+ return wx_host_interface_command (wx , (u32 * )& buffer , sizeof (buffer ),
88
+ WX_HI_COMMAND_TIMEOUT , true);
89
+ }
90
+
91
+ static void txgbe_get_link_capabilities (struct wx * wx )
92
+ {
93
+ struct txgbe * txgbe = wx -> priv ;
94
+
95
+ if (test_bit (PHY_INTERFACE_MODE_25GBASER , txgbe -> sfp_interfaces ))
96
+ wx -> adv_speed = SPEED_25000 ;
97
+ else if (test_bit (PHY_INTERFACE_MODE_10GBASER , txgbe -> sfp_interfaces ))
98
+ wx -> adv_speed = SPEED_10000 ;
99
+ else
100
+ wx -> adv_speed = SPEED_UNKNOWN ;
101
+
102
+ wx -> adv_duplex = wx -> adv_speed == SPEED_UNKNOWN ?
103
+ DUPLEX_HALF : DUPLEX_FULL ;
104
+ }
105
+
16
106
static void txgbe_get_phy_link (struct wx * wx , int * speed )
17
107
{
18
108
u32 status ;
@@ -28,6 +118,120 @@ static void txgbe_get_phy_link(struct wx *wx, int *speed)
28
118
* speed = SPEED_UNKNOWN ;
29
119
}
30
120
121
+ int txgbe_set_phy_link (struct wx * wx )
122
+ {
123
+ int speed , err ;
124
+ u32 gpio ;
125
+
126
+ /* Check RX signal */
127
+ gpio = rd32 (wx , WX_GPIO_EXT );
128
+ if (gpio & TXGBE_GPIOBIT_3 )
129
+ return - ENODEV ;
130
+
131
+ txgbe_get_link_capabilities (wx );
132
+ if (wx -> adv_speed == SPEED_UNKNOWN )
133
+ return - ENODEV ;
134
+
135
+ txgbe_get_phy_link (wx , & speed );
136
+ if (speed == wx -> adv_speed )
137
+ return 0 ;
138
+
139
+ err = txgbe_set_phy_link_hostif (wx , wx -> adv_speed , 0 , wx -> adv_duplex );
140
+ if (err ) {
141
+ wx_err (wx , "Failed to setup link\n" );
142
+ return err ;
143
+ }
144
+
145
+ return 0 ;
146
+ }
147
+
148
+ static int txgbe_sfp_to_linkmodes (struct wx * wx , struct txgbe_sfp_id * id )
149
+ {
150
+ __ETHTOOL_DECLARE_LINK_MODE_MASK (modes ) = { 0 , };
151
+ DECLARE_PHY_INTERFACE_MASK (interfaces );
152
+ struct txgbe * txgbe = wx -> priv ;
153
+
154
+ if (id -> com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE |
155
+ TXGBE_SFF_25GBASEER_CAPABLE |
156
+ TXGBE_SFF_25GBASELR_CAPABLE )) {
157
+ phylink_set (modes , 25000b aseSR_Full );
158
+ __set_bit (PHY_INTERFACE_MODE_25GBASER , interfaces );
159
+ }
160
+ if (id -> com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE ) {
161
+ phylink_set (modes , 10000b aseSR_Full );
162
+ __set_bit (PHY_INTERFACE_MODE_10GBASER , interfaces );
163
+ }
164
+ if (id -> com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE ) {
165
+ phylink_set (modes , 10000b aseLR_Full );
166
+ __set_bit (PHY_INTERFACE_MODE_10GBASER , interfaces );
167
+ }
168
+
169
+ if (phy_interface_empty (interfaces )) {
170
+ wx_err (wx , "unsupported SFP module\n" );
171
+ return - EINVAL ;
172
+ }
173
+
174
+ phylink_set (modes , Pause );
175
+ phylink_set (modes , Asym_Pause );
176
+ phylink_set (modes , FIBRE );
177
+ txgbe -> link_port = PORT_FIBRE ;
178
+
179
+ if (!linkmode_equal (txgbe -> sfp_support , modes )) {
180
+ linkmode_copy (txgbe -> sfp_support , modes );
181
+ phy_interface_and (txgbe -> sfp_interfaces ,
182
+ wx -> phylink_config .supported_interfaces ,
183
+ interfaces );
184
+ linkmode_copy (txgbe -> advertising , modes );
185
+
186
+ set_bit (WX_FLAG_NEED_LINK_CONFIG , wx -> flags );
187
+ }
188
+
189
+ return 0 ;
190
+ }
191
+
192
+ int txgbe_identify_sfp (struct wx * wx )
193
+ {
194
+ struct txgbe_hic_i2c_read buffer ;
195
+ struct txgbe_sfp_id * id ;
196
+ int err = 0 ;
197
+ u32 gpio ;
198
+
199
+ gpio = rd32 (wx , WX_GPIO_EXT );
200
+ if (gpio & TXGBE_GPIOBIT_2 )
201
+ return - ENODEV ;
202
+
203
+ err = txgbe_identify_sfp_hostif (wx , & buffer );
204
+ if (err ) {
205
+ wx_err (wx , "Failed to identify SFP module\n" );
206
+ return err ;
207
+ }
208
+
209
+ id = & buffer .id ;
210
+ if (id -> identifier != TXGBE_SFF_IDENTIFIER_SFP ) {
211
+ wx_err (wx , "Invalid SFP module\n" );
212
+ return - ENODEV ;
213
+ }
214
+
215
+ err = txgbe_sfp_to_linkmodes (wx , id );
216
+ if (err )
217
+ return err ;
218
+
219
+ if (gpio & TXGBE_GPIOBIT_3 )
220
+ set_bit (WX_FLAG_NEED_LINK_CONFIG , wx -> flags );
221
+
222
+ return 0 ;
223
+ }
224
+
225
+ void txgbe_setup_link (struct wx * wx )
226
+ {
227
+ struct txgbe * txgbe = wx -> priv ;
228
+
229
+ phy_interface_zero (txgbe -> sfp_interfaces );
230
+ linkmode_zero (txgbe -> sfp_support );
231
+
232
+ txgbe_identify_sfp (wx );
233
+ }
234
+
31
235
static void txgbe_get_link_state (struct phylink_config * config ,
32
236
struct phylink_link_state * state )
33
237
{
0 commit comments