1294838Szbb/*-
2294838Szbb*******************************************************************************
3294838SzbbCopyright (C) 2015 Annapurna Labs Ltd.
4294838Szbb
5294838SzbbThis file may be licensed under the terms of the Annapurna Labs Commercial
6294838SzbbLicense Agreement.
7294838Szbb
8294838SzbbAlternatively, this file can be distributed under the terms of the GNU General
9294838SzbbPublic License V2 as published by the Free Software Foundation and can be
10294838Szbbfound at http://www.gnu.org/licenses/gpl-2.0.html
11294838Szbb
12294838SzbbAlternatively, redistribution and use in source and binary forms, with or
13294838Szbbwithout modification, are permitted provided that the following conditions are
14294838Szbbmet:
15294838Szbb
16294838Szbb    *     Redistributions of source code must retain the above copyright notice,
17294838Szbbthis list of conditions and the following disclaimer.
18294838Szbb
19294838Szbb    *     Redistributions in binary form must reproduce the above copyright
20294838Szbbnotice, this list of conditions and the following disclaimer in
21294838Szbbthe documentation and/or other materials provided with the
22294838Szbbdistribution.
23294838Szbb
24294838SzbbTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25294838SzbbANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26294838SzbbWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27294838SzbbDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28294838SzbbANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29294838Szbb(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30294838SzbbLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31294838SzbbANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32294838Szbb(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33294838SzbbSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34294838Szbb
35294838Szbb*******************************************************************************/
36294838Szbb/**
37294838Szbb * @defgroup group_eth_kr_api API
38294838Szbb * Ethernet KR auto-neg and link-training driver API
39294838Szbb * @ingroup group_eth
40294838Szbb * @{
41294838Szbb * @file   al_hal_eth_kr.h
42294838Szbb *
43294838Szbb * @brief Header file for KR driver
44294838Szbb *
45294838Szbb *
46294838Szbb */
47294838Szbb
48294838Szbb#ifndef __AL_HAL_ETH_KR_H__
49294838Szbb#define __AL_HAL_ETH_KR_H__
50294838Szbb
51294838Szbb#include "al_hal_eth.h"
52294838Szbb
53294838Szbb/* *INDENT-OFF* */
54294838Szbb#ifdef __cplusplus
55294838Szbbextern "C" {
56294838Szbb#endif
57294838Szbb/* *INDENT-ON* */
58294838Szbb
59294838Szbb/* AN (Auto-negotiation) Advertisement Registers */
60294838Szbbstruct al_eth_an_adv {
61294838Szbb	/* constant value defining 802.3ap support.
62294838Szbb	 * The suggested value is 0x01.*/
63294838Szbb	uint8_t   selector_field;
64294838Szbb	/* Contains arbitrary data. */
65294838Szbb	uint8_t   echoed_nonce;
66294838Szbb	/* pause capability. */
67294838Szbb	uint8_t   capability;
68294838Szbb	/* Set to 1 to indicate a Remote Fault condition.
69294838Szbb	 * Set to 0 to indicate normal operation.*/
70294838Szbb	uint8_t   remote_fault;
71294838Szbb	/* Should always be set to 0. */
72294838Szbb	uint8_t   acknowledge;
73294838Szbb	/* Set to 1 to indicate that the device has next pages to send.
74294838Szbb	 * Set to 0 to indicate that that device has no next pages to send. */
75294838Szbb	uint8_t   next_page;
76294838Szbb	/* Must be set to an arbitrary value.
77294838Szbb	 * Two devices must have a different nonce for autonegotiation to
78294838Szbb	 * operate (a loopback will not allow autonegotiation to complete). */
79294838Szbb	uint8_t   transmitted_nonce;
80294838Szbb	uint32_t  technology;
81294838Szbb#define AL_ETH_AN_TECH_1000BASE_KX  AL_BIT(0)
82294838Szbb#define AL_ETH_AN_TECH_10GBASE_KX4  AL_BIT(1)
83294838Szbb#define AL_ETH_AN_TECH_10GBASE_KR   AL_BIT(2)
84294838Szbb#define AL_ETH_AN_TECH_40GBASE_KR4  AL_BIT(3)
85294838Szbb#define AL_ETH_AN_TECH_40GBASE_CR4  AL_BIT(4)
86294838Szbb#define AL_ETH_AN_TECH_100GBASE_CR  AL_BIT(5)
87294838Szbb	uint8_t   fec_capability;
88294838Szbb};
89294838Szbb
90294838Szbb/* AN next page fields */
91294838Szbbstruct al_eth_an_np {
92294838Szbb	/* These bits can be used as message code field or unformatted code field.
93294838Szbb	 * When msg_page is true, these bits represent message code field.
94294838Szbb	 * Predefined message code field Code Field should be used as specified in the standard
95294838Szbb	 * 802.3ap.
96294838Szbb	 * For the null message code the value is 0x01.
97294838Szbb	 */
98294838Szbb	uint16_t	unformatted_code_field;
99294838Szbb	/* Flag to keep track of the state of the local device's Toggle bit.
100294838Szbb	 * Initial value is taken from base page. Set to 0.
101294838Szbb	 */
102294838Szbb	al_bool		toggle;
103294838Szbb	/* Acknowledge 2 is used to indicate that the receiver is able to act on the information
104294838Szbb	 * (or perform the task) defined in the message.
105294838Szbb	 */
106294838Szbb	al_bool		ack2;
107294838Szbb	al_bool		msg_page;
108294838Szbb	/* If the device does not have any more Next Pages to send, set to AL_FALSE */
109294838Szbb	al_bool		next_page;
110294838Szbb	uint16_t	unformatted_code_field1;
111294838Szbb	uint16_t	unformatted_code_field2;
112294838Szbb};
113294838Szbb
114294838Szbbenum al_eth_kr_cl72_cstate {
115294838Szbb	C72_CSTATE_NOT_UPDATED = 0,
116294838Szbb	C72_CSTATE_UPDATED = 1,
117294838Szbb	C72_CSTATE_MIN = 2,
118294838Szbb	C72_CSTATE_MAX = 3,
119294838Szbb};
120294838Szbb
121294838Szbbenum al_eth_kr_cl72_coef_op {
122294838Szbb	AL_PHY_KR_COEF_UP_HOLD = 0,
123294838Szbb	AL_PHY_KR_COEF_UP_INC = 1,
124294838Szbb	AL_PHY_KR_COEF_UP_DEC = 2,
125294838Szbb	AL_PHY_KR_COEF_UP_RESERVED = 3
126294838Szbb};
127294838Szbb
128294838Szbbstruct al_eth_kr_coef_up_data {
129294838Szbb	enum al_eth_kr_cl72_coef_op c_zero;
130294838Szbb	enum al_eth_kr_cl72_coef_op c_plus;
131294838Szbb	enum al_eth_kr_cl72_coef_op c_minus;
132294838Szbb	al_bool preset;
133294838Szbb	al_bool initialize;
134294838Szbb};
135294838Szbb
136294838Szbbstruct al_eth_kr_status_report_data {
137294838Szbb	enum al_eth_kr_cl72_cstate c_zero;
138294838Szbb	enum al_eth_kr_cl72_cstate c_plus;
139294838Szbb	enum al_eth_kr_cl72_cstate c_minus;
140294838Szbb	al_bool receiver_ready;
141294838Szbb};
142294838Szbb
143294838Szbbenum al_eth_an_lt_lane {
144294838Szbb	AL_ETH_AN__LT_LANE_0,
145294838Szbb	AL_ETH_AN__LT_LANE_1,
146294838Szbb	AL_ETH_AN__LT_LANE_2,
147294838Szbb	AL_ETH_AN__LT_LANE_3,
148294838Szbb};
149294838Szbb
150294838Szbb/**
151294838Szbb * get the last received coefficient update message from the link partner
152294838Szbb *
153294838Szbb * @param adapter pointer to the private structure
154294838Szbb * @param lane lane number
155294838Szbb * @param lpcoeff coeff update received
156294838Szbb *
157294838Szbb */
158294838Szbbvoid al_eth_lp_coeff_up_get(
159294838Szbb			struct al_hal_eth_adapter *adapter,
160294838Szbb			enum al_eth_an_lt_lane lane,
161294838Szbb			struct al_eth_kr_coef_up_data *lpcoeff);
162294838Szbb
163294838Szbb/**
164294838Szbb * get the last received status report message from the link partner
165294838Szbb *
166294838Szbb * @param adapter pointer to the private structure
167294838Szbb * @param lane lane number
168294838Szbb * @param status status report received
169294838Szbb *
170294838Szbb */
171294838Szbbvoid al_eth_lp_status_report_get(
172294838Szbb			struct al_hal_eth_adapter *adapter,
173294838Szbb			enum al_eth_an_lt_lane lane,
174294838Szbb			struct al_eth_kr_status_report_data *status);
175294838Szbb
176294838Szbb/**
177294838Szbb * set the coefficient data for the next message that will be sent to lp
178294838Szbb *
179294838Szbb * @param adapter pointer to the private structure
180294838Szbb * @param lane lane number
181294838Szbb * @param ldcoeff coeff update to send
182294838Szbb *
183294838Szbb */
184294838Szbbvoid al_eth_ld_coeff_up_set(
185294838Szbb			struct al_hal_eth_adapter *adapter,
186294838Szbb			enum al_eth_an_lt_lane lane,
187294838Szbb			struct al_eth_kr_coef_up_data *ldcoeff);
188294838Szbb
189294838Szbb/**
190294838Szbb * set the status report message for the next message that will be sent to lp
191294838Szbb *
192294838Szbb * @param adapter pointer to the private structure
193294838Szbb * @param lane lane number
194294838Szbb * @param status status report to send
195294838Szbb *
196294838Szbb */
197294838Szbbvoid al_eth_ld_status_report_set(
198294838Szbb			struct al_hal_eth_adapter *adapter,
199294838Szbb			enum al_eth_an_lt_lane lane,
200294838Szbb			struct al_eth_kr_status_report_data *status);
201294838Szbb
202294838Szbb/**
203294838Szbb * get the receiver frame lock status
204294838Szbb *
205294838Szbb * @param adapter pointer to the private structure
206294838Szbb * @param lane lane number
207294838Szbb *
208294838Szbb * @return true if Training frame delineation is detected, otherwise false.
209294838Szbb */
210294838Szbbal_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter,
211294838Szbb					  enum al_eth_an_lt_lane lane);
212294838Szbb
213294838Szbb/**
214294838Szbb * get the start up protocol progress status
215294838Szbb *
216294838Szbb * @param adapter pointer to the private structure
217294838Szbb * @param lane lane number
218294838Szbb *
219294838Szbb * @return true if the startup protocol is in progress.
220294838Szbb */
221294838Szbbal_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter,
222294838Szbb					 enum al_eth_an_lt_lane lane);
223294838Szbb
224294838Szbb/**
225294838Szbb * indicate the receiver is ready (the link training is completed)
226294838Szbb *
227294838Szbb * @param adapter pointer to the private structure
228294838Szbb * @param lane lane number
229294838Szbb *
230294838Szbb */
231294838Szbbvoid al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter,
232294838Szbb			       enum al_eth_an_lt_lane lane);
233294838Szbb
234294838Szbb/**
235294838Szbb * read Training failure status.
236294838Szbb *
237294838Szbb * @param adapter pointer to the private structure
238294838Szbb * @param lane lane number
239294838Szbb *
240294838Szbb *@return true if Training failure has been detected.
241294838Szbb */
242294838Szbbal_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter,
243294838Szbb					   enum al_eth_an_lt_lane lane);
244294838Szbb
245294838Szbb/****************************** auto negotiation *******************************/
246294838Szbb/**
247294838Szbb * Initialize Auto-negotiation
248294838Szbb * - Program Ability Registers (Advertisement Registers)
249294838Szbb * - Clear Status latches
250294838Szbb * @param adapter pointer to the private structure
251294838Szbb * @param an_adv pointer to the AN Advertisement Registers structure
252294838Szbb *        when NULL, the registers will not be updated.
253294838Szbb *
254294838Szbb * @return 0 on success. otherwise on failure.
255294838Szbb */
256294838Szbbint al_eth_kr_an_init(struct al_hal_eth_adapter *adapter,
257294838Szbb		      struct al_eth_an_adv *an_adv);
258294838Szbb
259294838Szbb/**
260294838Szbb * Enable/Restart Auto-negotiation
261294838Szbb *
262294838Szbb * @param adapter pointer to the private structure
263294838Szbb * @param lane lane number
264294838Szbb * @param lt_enable initialize link training as well
265294838Szbb *
266294838Szbb * @return 0 on success. otherwise on failure.
267294838Szbb */
268294838Szbbint al_eth_kr_an_start(struct al_hal_eth_adapter *adapter,
269294838Szbb		       enum al_eth_an_lt_lane lane,
270294838Szbb		       al_bool next_page_enable,
271294838Szbb		       al_bool lt_enable);
272294838Szbb
273294838Szbb
274294838Szbbint al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter,
275294838Szbb			      struct al_eth_an_np *np);
276294838Szbb
277294838Szbbint al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter,
278294838Szbb			     struct al_eth_an_np *np);
279294838Szbb
280294838Szbb/**
281294838Szbb * Stop Auto-negotiation
282294838Szbb *
283294838Szbb * Stopping the auto-negotiation will prevent the mac from sending the last page
284294838Szbb * to the link partner in case it start the AN again. It must be called after
285294838Szbb * link training is completed or the software will lose sync with the HW state
286294838Szbb * machine
287294838Szbb *
288294838Szbb * @param adapter pointer to the private structure
289294838Szbb *
290294838Szbb */
291294838Szbbvoid al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter);
292294838Szbb
293294838Szbb/**
294294838Szbb *  Check Auto-negotiation event done
295294838Szbb *
296294838Szbb * @param adapter pointer to the private structure
297294838Szbb * @param page_received	Set to true if the AN page received indication is set.
298294838Szbb *			Set to false otherwise.
299294838Szbb * @param an_completed	Set to true of the AN completed indication is set.
300294838Szbb *			Set to false otherwise.
301294838Szbb * @param error	Set to true if any error encountered
302294838Szbb *
303294838Szbb */
304294838Szbbvoid al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter,
305294838Szbb			      al_bool *page_received,
306294838Szbb			      al_bool *an_completed,
307294838Szbb			      al_bool *error);
308294838Szbb
309294838Szbb/**
310294838Szbb *  Read the remote auto-negotiation advertising.
311294838Szbb *  This function is safe to called after al_eth_kr_an_status_check returned
312294838Szbb *  with page_received set.
313294838Szbb *
314294838Szbb * @param adapter pointer to the private structure
315294838Szbb * @param an_adv pointer to the AN Advertisement Registers structure
316294838Szbb *
317294838Szbb */
318294838Szbbvoid al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter,
319294838Szbb			   struct al_eth_an_adv *an_adv);
320294838Szbb
321294838Szbb/****************************** link training **********************************/
322294838Szbb/**
323294838Szbb *  Initialize Link-training.
324294838Szbb *  Clear the status register and set the local coefficient update and status
325294838Szbb *  to zero.
326294838Szbb *
327294838Szbb * @param adapter pointer to the private structure
328294838Szbb * @param lane lane number
329294838Szbb *
330294838Szbb */
331294838Szbbvoid al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter,
332294838Szbb			     enum al_eth_an_lt_lane lane);
333294838Szbb
334294838Szbb/**
335294838Szbb * Wait for frame lock.
336294838Szbb *
337294838Szbb * @param adapter pointer to the private structure
338294838Szbb * @param lane lane number
339294838Szbb * @param timeout timeout in usec.
340294838Szbb *
341294838Szbb * @return true if frame lock received. false otherwise.
342294838Szbb */
343294838Szbbal_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter,
344294838Szbb				     enum al_eth_an_lt_lane lane,
345294838Szbb				     uint32_t timeout);
346294838Szbb
347294838Szbb/**
348294838Szbb * reset the 10GBase- KR startup protocol and begin its operation
349294838Szbb *
350294838Szbb * @param adapter pointer to the private structure
351294838Szbb * @param lane lane number
352294838Szbb *
353294838Szbb */
354294838Szbbvoid al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter,
355294838Szbb			  enum al_eth_an_lt_lane lane);
356294838Szbb
357294838Szbb/**
358294838Szbb * reset the 10GBase- KR startup protocol and end its operation
359294838Szbb *
360294838Szbb * @param adapter pointer to the private structure
361294838Szbb * @param lane lane number
362294838Szbb *
363294838Szbb */
364294838Szbbvoid al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter,
365294838Szbb		       enum al_eth_an_lt_lane lane);
366294838Szbb
367294838Szbb#ifdef __cplusplus
368294838Szbb}
369294838Szbb#endif
370294838Szbb/* *INDENT-ON* */
371294838Szbb#endif /*__AL_HAL_ETH_KR_H__*/
372294838Szbb/** @} end of Ethernet kr group */
373