1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /**************************************************************************** |
3 | * Driver for Solarflare network controllers and boards |
4 | * Copyright 2006-2011 Solarflare Communications Inc. |
5 | */ |
6 | |
7 | #ifndef EF4_MDIO_10G_H |
8 | #define EF4_MDIO_10G_H |
9 | |
10 | #include <linux/mdio.h> |
11 | |
12 | /* |
13 | * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45. |
14 | */ |
15 | |
16 | #include "efx.h" |
17 | |
18 | static inline unsigned ef4_mdio_id_rev(u32 id) { return id & 0xf; } |
19 | static inline unsigned ef4_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } |
20 | unsigned ef4_mdio_id_oui(u32 id); |
21 | |
22 | static inline int ef4_mdio_read(struct ef4_nic *efx, int devad, int addr) |
23 | { |
24 | return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr); |
25 | } |
26 | |
27 | static inline void |
28 | ef4_mdio_write(struct ef4_nic *efx, int devad, int addr, int value) |
29 | { |
30 | efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value); |
31 | } |
32 | |
33 | static inline u32 ef4_mdio_read_id(struct ef4_nic *efx, int mmd) |
34 | { |
35 | u16 id_low = ef4_mdio_read(efx, devad: mmd, MDIO_DEVID2); |
36 | u16 id_hi = ef4_mdio_read(efx, devad: mmd, MDIO_DEVID1); |
37 | return (id_hi << 16) | (id_low); |
38 | } |
39 | |
40 | static inline bool ef4_mdio_phyxgxs_lane_sync(struct ef4_nic *efx) |
41 | { |
42 | int i, lane_status; |
43 | bool sync; |
44 | |
45 | for (i = 0; i < 2; ++i) |
46 | lane_status = ef4_mdio_read(efx, MDIO_MMD_PHYXS, |
47 | MDIO_PHYXS_LNSTAT); |
48 | |
49 | sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN); |
50 | if (!sync) |
51 | netif_dbg(efx, hw, efx->net_dev, "XGXS lane status: %x\n" , |
52 | lane_status); |
53 | return sync; |
54 | } |
55 | |
56 | const char *ef4_mdio_mmd_name(int mmd); |
57 | |
58 | /* |
59 | * Reset a specific MMD and wait for reset to clear. |
60 | * Return number of spins left (>0) on success, -%ETIMEDOUT on failure. |
61 | * |
62 | * This function will sleep |
63 | */ |
64 | int ef4_mdio_reset_mmd(struct ef4_nic *efx, int mmd, int spins, int spintime); |
65 | |
66 | /* As ef4_mdio_check_mmd but for multiple MMDs */ |
67 | int ef4_mdio_check_mmds(struct ef4_nic *efx, unsigned int mmd_mask); |
68 | |
69 | /* Check the link status of specified mmds in bit mask */ |
70 | bool ef4_mdio_links_ok(struct ef4_nic *efx, unsigned int mmd_mask); |
71 | |
72 | /* Generic transmit disable support though PMAPMD */ |
73 | void ef4_mdio_transmit_disable(struct ef4_nic *efx); |
74 | |
75 | /* Generic part of reconfigure: set/clear loopback bits */ |
76 | void ef4_mdio_phy_reconfigure(struct ef4_nic *efx); |
77 | |
78 | /* Set the power state of the specified MMDs */ |
79 | void ef4_mdio_set_mmds_lpower(struct ef4_nic *efx, int low_power, |
80 | unsigned int mmd_mask); |
81 | |
82 | /* Set (some of) the PHY settings over MDIO */ |
83 | int ef4_mdio_set_link_ksettings(struct ef4_nic *efx, |
84 | const struct ethtool_link_ksettings *cmd); |
85 | |
86 | /* Push advertising flags and restart autonegotiation */ |
87 | void ef4_mdio_an_reconfigure(struct ef4_nic *efx); |
88 | |
89 | /* Get pause parameters from AN if available (otherwise return |
90 | * requested pause parameters) |
91 | */ |
92 | u8 ef4_mdio_get_pause(struct ef4_nic *efx); |
93 | |
94 | /* Wait for specified MMDs to exit reset within a timeout */ |
95 | int ef4_mdio_wait_reset_mmds(struct ef4_nic *efx, unsigned int mmd_mask); |
96 | |
97 | /* Set or clear flag, debouncing */ |
98 | static inline void |
99 | ef4_mdio_set_flag(struct ef4_nic *efx, int devad, int addr, |
100 | int mask, bool state) |
101 | { |
102 | mdio_set_flag(mdio: &efx->mdio, prtad: efx->mdio.prtad, devad, addr, mask, sense: state); |
103 | } |
104 | |
105 | /* Liveness self-test for MDIO PHYs */ |
106 | int ef4_mdio_test_alive(struct ef4_nic *efx); |
107 | |
108 | #endif /* EF4_MDIO_10G_H */ |
109 | |