phylink.h 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
#ifndef NETDEV_PCS_H
#define NETDEV_PCS_H

#include <linux/phy.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>

struct device_node;
struct ethtool_cmd;
R
Russell King 已提交
10
struct fwnode_handle;
11 12 13 14 15 16 17 18 19 20 21 22 23
struct net_device;

enum {
	MLO_PAUSE_NONE,
	MLO_PAUSE_ASYM = BIT(0),
	MLO_PAUSE_SYM = BIT(1),
	MLO_PAUSE_RX = BIT(2),
	MLO_PAUSE_TX = BIT(3),
	MLO_PAUSE_TXRX_MASK = MLO_PAUSE_TX | MLO_PAUSE_RX,
	MLO_PAUSE_AN = BIT(4),

	MLO_AN_PHY = 0,	/* Conventional PHY */
	MLO_AN_FIXED,	/* Fixed-link mode */
24
	MLO_AN_INBAND,	/* In-band protocol */
25 26 27 28
};

static inline bool phylink_autoneg_inband(unsigned int mode)
{
29
	return mode == MLO_AN_INBAND;
30 31
}

32 33 34 35 36 37 38 39 40 41 42 43 44
/**
 * struct phylink_link_state - link state structure
 * @advertising: ethtool bitmask containing advertised link modes
 * @lp_advertising: ethtool bitmask containing link partner advertised link
 *   modes
 * @interface: link &typedef phy_interface_t mode
 * @speed: link speed, one of the SPEED_* constants.
 * @duplex: link duplex mode, one of DUPLEX_* constants.
 * @pause: link pause state, described by MLO_PAUSE_* constants.
 * @link: true if the link is up.
 * @an_enabled: true if autonegotiation is enabled/desired.
 * @an_complete: true if autonegotiation has completed.
 */
45 46 47
struct phylink_link_state {
	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
	__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
48
	phy_interface_t interface;
49 50 51 52 53 54 55 56
	int speed;
	int duplex;
	int pause;
	unsigned int link:1;
	unsigned int an_enabled:1;
	unsigned int an_complete:1;
};

57 58 59 60 61 62 63 64 65 66 67
/**
 * struct phylink_mac_ops - MAC operations structure.
 * @validate: Validate and update the link configuration.
 * @mac_link_state: Read the current link state from the hardware.
 * @mac_config: configure the MAC for the selected mode and state.
 * @mac_an_restart: restart 802.3z BaseX autonegotiation.
 * @mac_link_down: take the link down.
 * @mac_link_up: allow the link to come up.
 *
 * The individual methods are described more fully below.
 */
68 69 70
struct phylink_mac_ops {
	void (*validate)(struct net_device *ndev, unsigned long *supported,
			 struct phylink_link_state *state);
71 72
	int (*mac_link_state)(struct net_device *ndev,
			      struct phylink_link_state *state);
73 74 75
	void (*mac_config)(struct net_device *ndev, unsigned int mode,
			   const struct phylink_link_state *state);
	void (*mac_an_restart)(struct net_device *ndev);
76 77 78
	void (*mac_link_down)(struct net_device *ndev, unsigned int mode);
	void (*mac_link_up)(struct net_device *ndev, unsigned int mode,
			    struct phy_device *phy);
79 80
};

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
#if 0 /* For kernel-doc purposes only. */
/**
 * validate - Validate and update the link configuration
 * @ndev: a pointer to a &struct net_device for the MAC.
 * @supported: ethtool bitmask for supported link modes.
 * @state: a pointer to a &struct phylink_link_state.
 *
 * Clear bits in the @supported and @state->advertising masks that
 * are not supportable by the MAC.
 *
 * Note that the PHY may be able to transform from one connection
 * technology to another, so, eg, don't clear 1000BaseX just
 * because the MAC is unable to BaseX mode. This is more about
 * clearing unsupported speeds and duplex settings.
 *
 * If the @state->interface mode is %PHY_INTERFACE_MODE_1000BASEX
 * or %PHY_INTERFACE_MODE_2500BASEX, select the appropriate mode
 * based on @state->advertising and/or @state->speed and update
 * @state->interface accordingly.
 */
void validate(struct net_device *ndev, unsigned long *supported,
	      struct phylink_link_state *state);

/**
 * mac_link_state() - Read the current link state from the hardware
 * @ndev: a pointer to a &struct net_device for the MAC.
 * @state: a pointer to a &struct phylink_link_state.
 *
 * Read the current link state from the MAC, reporting the current
 * speed in @state->speed, duplex mode in @state->duplex, pause mode
 * in @state->pause using the %MLO_PAUSE_RX and %MLO_PAUSE_TX bits,
 * negotiation completion state in @state->an_complete, and link
 * up state in @state->link.
 */
int mac_link_state(struct net_device *ndev,
		   struct phylink_link_state *state);

/**
 * mac_config() - configure the MAC for the selected mode and state
 * @ndev: a pointer to a &struct net_device for the MAC.
 * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
 * @state: a pointer to a &struct phylink_link_state.
 *
 * The action performed depends on the currently selected mode:
 *
 * %MLO_AN_FIXED, %MLO_AN_PHY:
 *   Configure the specified @state->speed, @state->duplex and
 *   @state->pause (%MLO_PAUSE_TX / %MLO_PAUSE_RX) mode.
 *
 * %MLO_AN_INBAND:
 *   place the link in an inband negotiation mode (such as 802.3z
 *   1000base-X or Cisco SGMII mode depending on the @state->interface
 *   mode). In both cases, link state management (whether the link
 *   is up or not) is performed by the MAC, and reported via the
 *   mac_link_state() callback. Changes in link state must be made
 *   by calling phylink_mac_change().
 *
 *   If in 802.3z mode, the link speed is fixed, dependent on the
 *   @state->interface. Duplex is negotiated, and pause is advertised
 *   according to @state->an_enabled, @state->pause and
 *   @state->advertising flags. Beware of MACs which only support full
 *   duplex at gigabit and higher speeds.
 *
 *   If in Cisco SGMII mode, the link speed and duplex mode are passed
 *   in the serial bitstream 16-bit configuration word, and the MAC
 *   should be configured to read these bits and acknowledge the
 *   configuration word. Nothing is advertised by the MAC. The MAC is
 *   responsible for reading the configuration word and configuring
 *   itself accordingly.
 */
void mac_config(struct net_device *ndev, unsigned int mode,
		const struct phylink_link_state *state);

/**
 * mac_an_restart() - restart 802.3z BaseX autonegotiation
 * @ndev: a pointer to a &struct net_device for the MAC.
 */
void mac_an_restart(struct net_device *ndev);

/**
 * mac_link_down() - take the link down
 * @ndev: a pointer to a &struct net_device for the MAC.
 * @mode: link autonegotiation mode
 *
 * If @mode is not an in-band negotiation mode (as defined by
 * phylink_autoneg_inband()), force the link down and disable any
 * Energy Efficient Ethernet MAC configuration.
 */
void mac_link_down(struct net_device *ndev, unsigned int mode);

/**
 * mac_link_up() - allow the link to come up
 * @ndev: a pointer to a &struct net_device for the MAC.
 * @mode: link autonegotiation mode
 * @phy: any attached phy
 *
 * If @mode is not an in-band negotiation mode (as defined by
 * phylink_autoneg_inband()), allow the link to come up. If @phy
 * is non-%NULL, configure Energy Efficient Ethernet by calling
 * phy_init_eee() and perform appropriate MAC configuration for EEE.
 */
void mac_link_up(struct net_device *ndev, unsigned int mode,
		 struct phy_device *phy);
#endif

R
Russell King 已提交
186
struct phylink *phylink_create(struct net_device *, struct fwnode_handle *,
187 188 189 190
	phy_interface_t iface, const struct phylink_mac_ops *ops);
void phylink_destroy(struct phylink *);

int phylink_connect_phy(struct phylink *, struct phy_device *);
191
int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
void phylink_disconnect_phy(struct phylink *);

void phylink_mac_change(struct phylink *, bool up);

void phylink_start(struct phylink *);
void phylink_stop(struct phylink *);

void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *);
int phylink_ethtool_set_wol(struct phylink *, struct ethtool_wolinfo *);

int phylink_ethtool_ksettings_get(struct phylink *,
				  struct ethtool_link_ksettings *);
int phylink_ethtool_ksettings_set(struct phylink *,
				  const struct ethtool_link_ksettings *);
int phylink_ethtool_nway_reset(struct phylink *);
void phylink_ethtool_get_pauseparam(struct phylink *,
				    struct ethtool_pauseparam *);
int phylink_ethtool_set_pauseparam(struct phylink *,
				   struct ethtool_pauseparam *);
211 212 213
int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *);
int phylink_ethtool_get_module_eeprom(struct phylink *,
				      struct ethtool_eeprom *, u8 *);
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
int phylink_get_eee_err(struct phylink *);
int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *);
int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *);
int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);

#define phylink_zero(bm) \
	bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
#define __phylink_do_bit(op, bm, mode) \
	op(ETHTOOL_LINK_MODE_ ## mode ## _BIT, bm)

#define phylink_set(bm, mode)	__phylink_do_bit(__set_bit, bm, mode)
#define phylink_clear(bm, mode)	__phylink_do_bit(__clear_bit, bm, mode)
#define phylink_test(bm, mode)	__phylink_do_bit(test_bit, bm, mode)

void phylink_set_port_modes(unsigned long *bits);

#endif