162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/**************************************************************************** 362306a36Sopenharmony_ci * Driver for Solarflare network controllers and boards 462306a36Sopenharmony_ci * Copyright 2006-2011 Solarflare Communications Inc. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef EF4_MDIO_10G_H 862306a36Sopenharmony_ci#define EF4_MDIO_10G_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/mdio.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "efx.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistatic inline unsigned ef4_mdio_id_rev(u32 id) { return id & 0xf; } 1962306a36Sopenharmony_cistatic inline unsigned ef4_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } 2062306a36Sopenharmony_ciunsigned ef4_mdio_id_oui(u32 id); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic inline int ef4_mdio_read(struct ef4_nic *efx, int devad, int addr) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr); 2562306a36Sopenharmony_ci} 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic inline void 2862306a36Sopenharmony_cief4_mdio_write(struct ef4_nic *efx, int devad, int addr, int value) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value); 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic inline u32 ef4_mdio_read_id(struct ef4_nic *efx, int mmd) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci u16 id_low = ef4_mdio_read(efx, mmd, MDIO_DEVID2); 3662306a36Sopenharmony_ci u16 id_hi = ef4_mdio_read(efx, mmd, MDIO_DEVID1); 3762306a36Sopenharmony_ci return (id_hi << 16) | (id_low); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline bool ef4_mdio_phyxgxs_lane_sync(struct ef4_nic *efx) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci int i, lane_status; 4362306a36Sopenharmony_ci bool sync; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci for (i = 0; i < 2; ++i) 4662306a36Sopenharmony_ci lane_status = ef4_mdio_read(efx, MDIO_MMD_PHYXS, 4762306a36Sopenharmony_ci MDIO_PHYXS_LNSTAT); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN); 5062306a36Sopenharmony_ci if (!sync) 5162306a36Sopenharmony_ci netif_dbg(efx, hw, efx->net_dev, "XGXS lane status: %x\n", 5262306a36Sopenharmony_ci lane_status); 5362306a36Sopenharmony_ci return sync; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciconst char *ef4_mdio_mmd_name(int mmd); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* 5962306a36Sopenharmony_ci * Reset a specific MMD and wait for reset to clear. 6062306a36Sopenharmony_ci * Return number of spins left (>0) on success, -%ETIMEDOUT on failure. 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * This function will sleep 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ciint ef4_mdio_reset_mmd(struct ef4_nic *efx, int mmd, int spins, int spintime); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* As ef4_mdio_check_mmd but for multiple MMDs */ 6762306a36Sopenharmony_ciint ef4_mdio_check_mmds(struct ef4_nic *efx, unsigned int mmd_mask); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* Check the link status of specified mmds in bit mask */ 7062306a36Sopenharmony_cibool ef4_mdio_links_ok(struct ef4_nic *efx, unsigned int mmd_mask); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* Generic transmit disable support though PMAPMD */ 7362306a36Sopenharmony_civoid ef4_mdio_transmit_disable(struct ef4_nic *efx); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* Generic part of reconfigure: set/clear loopback bits */ 7662306a36Sopenharmony_civoid ef4_mdio_phy_reconfigure(struct ef4_nic *efx); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/* Set the power state of the specified MMDs */ 7962306a36Sopenharmony_civoid ef4_mdio_set_mmds_lpower(struct ef4_nic *efx, int low_power, 8062306a36Sopenharmony_ci unsigned int mmd_mask); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* Set (some of) the PHY settings over MDIO */ 8362306a36Sopenharmony_ciint ef4_mdio_set_link_ksettings(struct ef4_nic *efx, 8462306a36Sopenharmony_ci const struct ethtool_link_ksettings *cmd); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* Push advertising flags and restart autonegotiation */ 8762306a36Sopenharmony_civoid ef4_mdio_an_reconfigure(struct ef4_nic *efx); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* Get pause parameters from AN if available (otherwise return 9062306a36Sopenharmony_ci * requested pause parameters) 9162306a36Sopenharmony_ci */ 9262306a36Sopenharmony_ciu8 ef4_mdio_get_pause(struct ef4_nic *efx); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* Wait for specified MMDs to exit reset within a timeout */ 9562306a36Sopenharmony_ciint ef4_mdio_wait_reset_mmds(struct ef4_nic *efx, unsigned int mmd_mask); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* Set or clear flag, debouncing */ 9862306a36Sopenharmony_cistatic inline void 9962306a36Sopenharmony_cief4_mdio_set_flag(struct ef4_nic *efx, int devad, int addr, 10062306a36Sopenharmony_ci int mask, bool state) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* Liveness self-test for MDIO PHYs */ 10662306a36Sopenharmony_ciint ef4_mdio_test_alive(struct ef4_nic *efx); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#endif /* EF4_MDIO_10G_H */ 109