Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/al_eth/al_init_eth_lm.h
39507 views
1
/*-
2
* Copyright (c) 2015,2016 Annapurna Labs Ltd. and affiliates
3
* All rights reserved.
4
*
5
* Developed by Semihalf.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
/**
30
* Ethernet
31
* @{
32
* @file al_init_eth_lm.h
33
*
34
* @brief ethernet link management common utilities
35
*
36
* Common operation example:
37
* @code
38
* int main()
39
* {
40
* struct al_eth_lm_context lm_context;
41
* struct al_eth_lm_init_params lm_params;
42
* enum al_eth_lm_link_mode old_mode;
43
* enum al_eth_lm_link_mode new_mode;
44
* al_bool fault;
45
* al_bool link_up;
46
* int rc = 0;
47
*
48
* lm_params.adapter = hal_adapter;
49
* lm_params.serdes_obj = serdes;
50
* lm_params.grp = grp;
51
* lm_params.lane = lane;
52
* lm_params.sfp_detection = true;
53
* lm_params.link_training = true;
54
* lm_params.rx_equal = true
55
* lm_params.static_values = true;
56
* lm_params.kr_fec_enable = false;
57
* lm_params.eeprom_read = &my_eeprom_read;
58
* lm_params.eeprom_context = context;
59
* lm_params.get_random_byte = &my_rand_byte;
60
* lm_params.default_mode = AL_ETH_LM_MODE_10G_DA;
61
*
62
* al_eth_lm_init(&lm_context, &lm_params);
63
*
64
* rc = al_eth_lm_link_detection(&lm_context, &fault, &old_mode, &new_mode);
65
* if (fault == false)
66
* return; // in this case the link is still up
67
*
68
* if (rc) {
69
* printf("link detection failed on error\n");
70
* return;
71
* }
72
*
73
* if (old_mode != new_mode) {
74
* // perform serdes configuration if needed
75
*
76
* // mac stop / start / config if needed
77
* }
78
*
79
* spin_lock(lock);
80
* rc = al_eth_lm_link_establish($lm_context, &link_up);
81
* spin_unlock(lock);
82
* if (rc) {
83
* printf("establish link failed\n");
84
* return;
85
* }
86
*
87
* if (link_up)
88
* printf("Link established successfully\n");
89
* else
90
* printf("No signal found. probably the link partner is disconnected\n");
91
* }
92
* @endcode
93
*
94
*/
95
96
#ifndef __AL_INIT_ETH_LM_H__
97
#define __AL_INIT_ETH_LM_H__
98
99
#include <al_serdes.h>
100
#include <al_hal_eth.h>
101
#include "al_init_eth_kr.h"
102
103
enum al_eth_lm_link_mode {
104
AL_ETH_LM_MODE_DISCONNECTED,
105
AL_ETH_LM_MODE_10G_OPTIC,
106
AL_ETH_LM_MODE_10G_DA,
107
AL_ETH_LM_MODE_1G,
108
AL_ETH_LM_MODE_25G,
109
};
110
111
enum al_eth_lm_max_speed {
112
AL_ETH_LM_MAX_SPEED_MAX,
113
AL_ETH_LM_MAX_SPEED_25G,
114
AL_ETH_LM_MAX_SPEED_10G,
115
AL_ETH_LM_MAX_SPEED_1G,
116
};
117
118
enum al_eth_lm_link_state {
119
AL_ETH_LM_LINK_DOWN,
120
AL_ETH_LM_LINK_DOWN_RF,
121
AL_ETH_LM_LINK_UP,
122
};
123
124
enum al_eth_lm_led_config_speed {
125
AL_ETH_LM_LED_CONFIG_1G,
126
AL_ETH_LM_LED_CONFIG_10G,
127
AL_ETH_LM_LED_CONFIG_25G,
128
};
129
130
struct al_eth_lm_led_config_data {
131
enum al_eth_lm_led_config_speed speed;
132
};
133
134
struct al_eth_lm_context {
135
struct al_hal_eth_adapter *adapter;
136
struct al_serdes_grp_obj *serdes_obj;
137
enum al_serdes_lane lane;
138
139
uint32_t link_training_failures;
140
141
bool tx_param_dirty;
142
bool serdes_tx_params_valid;
143
struct al_serdes_adv_tx_params tx_params_override;
144
bool rx_param_dirty;
145
bool serdes_rx_params_valid;
146
struct al_serdes_adv_rx_params rx_params_override;
147
148
struct al_eth_an_adv local_adv;
149
struct al_eth_an_adv partner_adv;
150
151
enum al_eth_lm_link_mode mode;
152
uint8_t da_len;
153
bool debug;
154
155
/* configurations */
156
bool sfp_detection;
157
uint8_t sfp_bus_id;
158
uint8_t sfp_i2c_addr;
159
160
enum al_eth_lm_link_mode default_mode;
161
uint8_t default_dac_len;
162
bool link_training;
163
bool rx_equal;
164
bool static_values;
165
166
bool retimer_exist;
167
enum al_eth_retimer_type retimer_type;
168
uint8_t retimer_bus_id;
169
uint8_t retimer_i2c_addr;
170
enum al_eth_retimer_channel retimer_channel;
171
172
/* services */
173
int (*i2c_read)(void *handle, uint8_t bus_id, uint8_t i2c_addr,
174
uint8_t reg_addr, uint8_t *val);
175
int (*i2c_write)(void *handle, uint8_t bus_id, uint8_t i2c_addr,
176
uint8_t reg_addr, uint8_t val);
177
void *i2c_context;
178
uint8_t (*get_random_byte)(void);
179
180
int (*gpio_get)(unsigned int gpio);
181
uint32_t gpio_present;
182
183
enum al_eth_retimer_channel retimer_tx_channel;
184
bool retimer_configured;
185
186
enum al_eth_lm_max_speed max_speed;
187
188
bool sfp_detect_force_mode;
189
190
enum al_eth_lm_link_state link_state;
191
bool new_port;
192
193
bool (*lm_pause)(void *handle);
194
195
void (*led_config)(void *handle, struct al_eth_lm_led_config_data *data);
196
};
197
198
struct al_eth_lm_init_params {
199
/* pointer to HAL context */
200
struct al_hal_eth_adapter *adapter;
201
/* pointer to serdes object */
202
struct al_serdes_grp_obj *serdes_obj;
203
/* serdes lane for this port */
204
enum al_serdes_lane lane;
205
206
/*
207
* set to true to perform sfp detection if the link is down.
208
* when set to true, eeprom_read below should NOT be NULL.
209
*/
210
bool sfp_detection;
211
/* i2c bus id of the SFP for this port */
212
uint8_t sfp_bus_id;
213
/* i2c addr of the SFP for this port */
214
uint8_t sfp_i2c_addr;
215
/*
216
* default mode, and dac length will be used in case sfp_detection
217
* is not set or in case the detection failed.
218
*/
219
enum al_eth_lm_link_mode default_mode;
220
uint8_t default_dac_len;
221
222
/* the i2c bus id and addr of the retimer in case it exist */
223
uint8_t retimer_bus_id;
224
uint8_t retimer_i2c_addr;
225
/* retimer channel connected to this port */
226
enum al_eth_retimer_channel retimer_channel;
227
enum al_eth_retimer_channel retimer_tx_channel;
228
/* retimer type if exist */
229
enum al_eth_retimer_type retimer_type;
230
231
/*
232
* the following parameters control what mechanisms to run
233
* on link_establish with the following steps:
234
* - if retimer_exist is set, the retimer will be configured based on DA len.
235
* - if link_training is set and DA detected run link training. if succeed return 0
236
* - if rx_equal is set serdes equalization will be run to configure the rx parameters.
237
* - if static_values is set, tx and rx values will be set based on static values.
238
*/
239
bool retimer_exist;
240
bool link_training;
241
bool rx_equal;
242
bool static_values;
243
244
/* enable / disable fec capabilities in AN */
245
bool kr_fec_enable;
246
247
/*
248
* pointer to function that's read 1 byte from eeprom
249
* in case no eeprom is connected should return -ETIMEDOUT
250
*/
251
int (*i2c_read)(void *handle, uint8_t bus_id, uint8_t i2c_addr,
252
uint8_t reg_addr, uint8_t *val);
253
int (*i2c_write)(void *handle, uint8_t bus_id, uint8_t i2c_addr,
254
uint8_t reg_addr, uint8_t val);
255
void *i2c_context;
256
/* pointer to function that return 1 rand byte */
257
uint8_t (*get_random_byte)(void);
258
259
/* pointer to function that gets GPIO value - if NULL gpio present won't be used */
260
int (*gpio_get)(unsigned int gpio);
261
/* gpio number connected to the SFP present pin */
262
uint32_t gpio_present;
263
264
enum al_eth_lm_max_speed max_speed;
265
266
/* in case force mode is true - the default mode will be set regardless to
267
* the SFP EEPROM content */
268
bool sfp_detect_force_mode;
269
270
/* lm pause callback - in case it return true the LM will try to preserve
271
* the current link status and will not try to establish new link (and will not
272
* access to i2c bus) */
273
bool (*lm_pause)(void *handle);
274
275
/* config ethernet LEDs according to data. can be NULL if no configuration needed */
276
void (*led_config)(void *handle, struct al_eth_lm_led_config_data *data);
277
};
278
279
/**
280
* initialize link management context and set configuration
281
*
282
* @param lm_context pointer to link management context
283
* @param params parameters passed from upper layer
284
*
285
* @return 0 in case of success. otherwise on failure.
286
*/
287
int al_eth_lm_init(struct al_eth_lm_context *lm_context,
288
struct al_eth_lm_init_params *params);
289
290
/**
291
* perform link status check. in case link is down perform sfp detection
292
*
293
* @param lm_context pointer to link management context
294
* @param link_fault indicate if the link is down
295
* @param old_mode the last working mode
296
* @param new_mode the new mode detected in this call
297
*
298
* @return 0 in case of success. otherwise on failure.
299
*/
300
int al_eth_lm_link_detection(struct al_eth_lm_context *lm_context,
301
bool *link_fault, enum al_eth_lm_link_mode *old_mode,
302
enum al_eth_lm_link_mode *new_mode);
303
304
/**
305
* run LT, rx equalization and static values override according to configuration
306
* This function MUST be called inside a lock as it using common serdes registers
307
*
308
* @param lm_context pointer to link management context
309
* @param link_up set to true in case link is establish successfully
310
*
311
* @return < 0 in case link was failed to be established
312
*/
313
int al_eth_lm_link_establish(struct al_eth_lm_context *lm_context,
314
bool *link_up);
315
316
/**
317
* override the default static parameters
318
*
319
* @param lm_context pointer to link management context
320
* @param tx_params pointer to new tx params
321
* @param rx_params pointer to new rx params
322
*
323
* @return 0 in case of success. otherwise on failure.
324
**/
325
int al_eth_lm_static_parameters_override(struct al_eth_lm_context *lm_context,
326
struct al_serdes_adv_tx_params *tx_params,
327
struct al_serdes_adv_rx_params *rx_params);
328
329
/**
330
* disable serdes parameters override
331
*
332
* @param lm_context pointer to link management context
333
* @param tx_params set to true to disable override of tx params
334
* @param rx_params set to true to disable override of rx params
335
*
336
* @return 0 in case of success. otherwise on failure.
337
**/
338
int al_eth_lm_static_parameters_override_disable(struct al_eth_lm_context *lm_context,
339
bool tx_params, bool rx_params);
340
341
/**
342
* get the static parameters that are being used
343
* if the parameters was override - return the override values
344
* else return the current values of the parameters
345
*
346
* @param lm_context pointer to link management context
347
* @param tx_params pointer to new tx params
348
* @param rx_params pointer to new rx params
349
*
350
* @return 0 in case of success. otherwise on failure.
351
*/
352
int al_eth_lm_static_parameters_get(struct al_eth_lm_context *lm_context,
353
struct al_serdes_adv_tx_params *tx_params,
354
struct al_serdes_adv_rx_params *rx_params);
355
356
/**
357
* convert link management mode to string
358
*
359
* @param val link management mode
360
*
361
* @return string of the mode
362
*/
363
const char *al_eth_lm_mode_convert_to_str(enum al_eth_lm_link_mode val);
364
365
/**
366
* print all debug messages
367
*
368
* @param lm_context pointer to link management context
369
* @param enable set to true to enable debug mode
370
*/
371
void al_eth_lm_debug_mode_set(struct al_eth_lm_context *lm_context,
372
bool enable);
373
#endif
374
375