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