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