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