All pastes #1430198 Raw Edit

Proposed new MII/GMII API

public c v1 · immutable
#1430198 ·published 2009-05-21 19:15 UTC
rendered paste body
/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END *//* * Copyright 2009 Sun Microsystems, Inc.  All rights reserved. * Use is subject to license terms. *//* * mii.h * Generic MII/PHY Support for MAC drivers. */#ifndef _SYS_MII_H#define	_SYS_MII_H#include <sys/mac_provider.h>#include <sys/netlb.h>#ifdef	__cplusplusextern "C" {#endif/* * NOTES * * The device driver is required to protect its own registers.  The * MII common code will call MII entry points asynchronously, from a * taskq, and holds an internal lock across such calls (except the * notify entry point).  Therefore, device drivers MUST NOT hold any * locks across calls into the MII framework. * * If a device must be suspended (e.g. due to DDI_SUSPEND) the MII * layer can be suspended by calling mii_stop().  After this point, * the monitoring task will be suspended and the driver can be assured * that MII will not interfere until restarted with mac_start(). * * Note that monitoring is not started until mac_start() is called.  * The mac_start() function may be called multiple times.  It performs * an implicit reset of the MII bus and PHY. * * Once started, if not already done, a probe of the MII bus is done to * find a suitable PHY.  If no PHY is found, then you won't have any * link!  Once a suitable PHY is selected, any other PHYs are isolated and * powered down.  The device driver can cause MII to re-probe the bus for * changes to the available PHYs by calling mii_probe().  Note that this * will also cause a full reset of all PHYs. * * The device driver can supply either regular access routines * (mii_read and mii_write) or low level bit bang operations * (mii_read_bit and mii_write_bit), but should not supply both. * The MII layer will tristate the bus by performing an implied read. * * The mii_reset entry point, which is optional, is used to notify the * driver when the MII layer has reset the device.  This can allow * certain drivers the opportunity to "fix up" things after reset. * Note however, that when possible, it is better if the logic is * encoded into a vendor specific PHY module. */#ifdef	_KERNELtypedef struct mii_handle mii_handle_t;typedef struct mii_ops mii_ops_t;struct mii_ops {	uint16_t	(*mii_read)(void *, uint8_t, uint8_t);	void		(*mii_write)(void *, uint8_t, uint8_t, uint16_t);	void		(*mii_notify)(void *, link_state_t);	void		(*mii_reset)(void *);};/* * Support routines. *//* * mii_alloc  * * 	Allocate an MII handle.  Called during driver's attach(9e) handling, *	this routine is valid in kernel context only. * * Arguments * * 	private		A private state structure, provided back to *			entry points. *	dip		The dev_info node for the MAC driver. *	ops		Entry points into the MAC driver. * * Returns *	Handle to MII bus on success, NULL on failure. */mii_handle_t *mii_alloc(void *private, dev_info_t*dip, mii_ops_t *ops);/* * mii_free * *	Free an MII handle and associated resources.  Call from detach(9e) *	handling, this routine is valid in kernel context only. */void mii_free(mii_handle_t *mii);/* * mii_set_instance * *	Sets the instance (PPA) of the MAC associated with the MII. *	Optional, but if called, must be done after mii_alloc(), and *	before the first time mii_start() is called.  If not called, a *	default instance using ddi_get_instance() from the dev_info *	node was supplied to mii_alloc will be used.  (This function *	is only needed for drivers that override the value of *	m_instance in the mac_register structure.) * * Arguments * * 	mii		MII handle. *	instance	Instance number. */void mii_set_instance(mii_handle_t *mii, uint_t instance);/* * mii_set_pauseable * *	Lets the MII know if the MAC layer can support pause or *	asymetric pause capabilities.  The MII layer will use this to *	determine what capabilities should be negotiated for (along *	with user preferences, of course.)  If not called, the MII *	will assume the device has no support for flow control. * * Arguments * * 	mii		MII handle. *	cap		B_TRUE if the device supports symmetric of pause. *	asym		B_TRUE if the device supports asymmetric pause. */void mii_set_pauseable(mii_handle_t *mii, boolean_t cap, boolean_t asym);/* * mii_start * *	Starts monitoring of the MII bus.  Normally this is called as *	a result of a driver's mac_start() entry point, but it may also *	be called when a PHY needs to be reset or during handling of *	DDI_RESUME.   This function may be called in any context except *	high level interrupt context, but *	must be called without any locks held. */void mii_start(mii_handle_t *mii);/* * mii_stop * *	Stops monitoring of the MII bus.  Normally this is called as a *	result of a driver's mac_stop() entry point, but may also be *	called during DDI_SUSPEND handling.  As a side effect, also *	isolates and powers down any active PHY.  On return, the MII *	layer is guaranteed not to be executing any code in the MII *	entry points.  This function may be called in any context *	except high level interrupt context, but must be called *	without any locks held. */void mii_stop(mii_handle_t *mii);/* * mii_probe * *	Used to reset the entire MII bus and probe for PHYs.  This *	routine should be called if the driver has reason to believe that *	PHYs have changed.  This is implicitly executed the first time *	monitoring is started on the MII bus, and normally need not be *	explicitly called. This function may be called in any context *	except high level interrupt context, but must be called *	without any locks held. */void mii_probe(mii_handle_t *mii);/* * mii_check * *	Used to alert the MII layer that it should check for changes. *	This can be called by drivers in response to link status *	interrupts, for example, giving a quicker response to link *	status changes without waiting for the MII timer to expire. *	This function may be called in any context except high level *	interrupt context, but must be called without any locks held. */void mii_check(mii_handle_t *mii);/* * mii_get_addr * *	Used to get the PHY address that is currently active for the MII *	bus.  This function may be called in any context *	except high level interrupt context, but must be called *	without any locks held. * * Returns * *	The PHY address (0-31) if a PHY is active on the MII bus.  If *	no PHY is active, -1 is returned. */int mii_get_addr(mii_handle_t *mii);/* * mii_get_id * *	Used to get the identifier of the active PHY.  This function *	may be called in any context except high level interrupt *	context, but must be called without any locks held. * * Returns * *	The PHY identifier register contents, encoded with the high * 	order (PHYIDH) bits in the upper word and the low order bits * 	in the lower word.  If no PHY is active, the value -1 will be * 	returned. */uint32_t mii_get_id(mii_handle_t *mii);/* * mii_get_speed * *	Used to get the speed of the active PHY.  This function may be *	called in any context except high level interrupt context, but *	must be called without any locks held. * * Returns * *	The speed, in Mbps, if the active PHY has link (10, 100, or 1000), *	otherwise 0. */int mii_get_speed(mii_handle_t *mii);/* * mii_get_duplex * *	Used to get the duplex of the active PHY.  This function may *	be called in any context except high level interrupt context, *	but must be called without any locks held. * * Returns * *	The duplex, if the active PHY has link (LINK_DUPLEX_FULL or *	LINK_DUPLEX_HALF), otherwise LINK_DUPLEX_UNKNOWN. */link_duplex_t mii_get_duplex(mii_handle_t *mii);/* * mii_get_state * *	Used to get the state of the link on the active PHY.  This *	function may be called in any context except high level *	interrupt context, but must be called without any locks held. * * Returns * *	The link state (LINK_STATE_UP or LINK_STATE_DOWN), if known, *	otherwise LINK_STATE_UNKNOWN. */link_state_t mii_get_state(mii_handle_t *mii);/* * mii_get_flowctrl * *	Used to get the state of the negotiated flow control on the *	active PHY.  This function may be called in any context except *	high level interrupt context, but must be called without any *	locks held. * * Returns * *	The flowctrl state (LINK_FLOWCTRL_NONE, LINK_FLOWCTRL_RX, *	LINK_FLOWCTRL_TX, or LINK_FLOWCTRL_BI. */link_flowctrl_t mii_get_flowctrl(mii_handle_t *mii);/* * mii_get_loopmodes * *	This function is used to support the LB_GET_INFO_SIZE and *	LB_GET_INFO ioctls.  It probably should not be used outside of *	that context.  The modes supplied are supported by the MII/PHY. *	Drivers may wish to add modes for MAC internal loopbacks as well. *	See <sys/netlb.h> for more information. * *	Note that the first item in the modes array will always be the *	mode to disable the MII/PHY loopback, and will have the value *	MII_LOOPBACK_NONE. * * Arguments * * 	mii		MII handle. *	modes		Location to receive an array of loopback modes. *			Drivers should ensure that enough room is available. *			There will never be more than MII_LOOPBACK_MAX modes *			returned.  May be NULL, in which case no data will *			be returned to the caller. * * Returns * *	Count of number of modes available, in no case larger than *	MII_LOOPBACK_MAX. */int mii_get_loopmodes(mii_handle_t *mii, lb_property_t *modes);#define	MII_LOOPBACK_MAX	16#define	MII_LOOPBACK_NONE	0/* * mii_set_loopback * *	Sets the loopback mode, intended for use in support of the *	LB_SET_MODE ioctl.  The mode value will be one of the values *	returned in the modes array (see mii_get_loopmodes), or the *	special value MII_LOOPBACK_NONE to return to normal operation. * * Arguments * * 	mii		MII handle. *	mode		New loopback mode number; MII_LOOPBACK_NONE indicates *			a return to normal operation. * * Returns * *	Zero on success, or EINVAL if the mode is invalid or unsupported. */int mii_set_loopback(mii_handle_t *mii, uint32_t mode);/* * mii_get_loopback * *	Queries the loopback mode, intended for use in support of the *	LB_GET_MODE ioctl, but may be useful in programming device *	settings that are sensitive to loopback setting. * * Returns * *	The current mode number (one of the reported by *	mii_get_loopmodes), or the special value MII_LOOPBACK_NONE *	indicating that loopback is not in use. */uint32_t mii_get_loopback(mii_handle_t *mii);/* * mii_m_getprop * *	Used to support the driver's mc_getprop() mac callback, *	and only to be called from that function (and without any *	locks held).  This routine will process all of the properties *	that are relevant to MII on behalf of the driver. * * Arguments * * 	mii		MII handle. *	name		Property name. *	id		Property ID. *	flags		Property flags (MAC_PROP_DEFAULT). *	sz		Size of property in bytes. *	val		Location to receive property value. *	perm		Location to receive property permissions (either *			MAC_PROP_PERM_READ or MAC_PROP_PERM_RW). * * Returns * *	0 on successful handling of property. *	EINVAL if invalid arguments (e.g. a bad size) are supplied. *	ENOTSUP	if the prooperty is not supported by MII or the PHY. */int mii_m_getprop(mii_handle_t *mii, const char *name, mac_prop_id_t id,    uint_t flags, uint_t sz, void *val, uint_t *perm);/* * mii_m_setprop * *	Used to support the driver's mc_setprop() mac callback, *	and only to be called from that function (and without any *	locks held).  This routine will process all of the properties *	that are relevant to MII on behalf of the driver.  This will *	often result in the PHY being reset. * * Arguments * * 	mii		MII handle. *	name		Property name. *	id		Property ID. *	sz		Size of property in bytes. *	val		Location of property value. * * Returns * *	0 on successful handling of property. *	EINVAL if invalid arguments (e.g. a bad size) are supplied. *	ENOTSUP	if the prooperty is not supported by MII or the PHY, *	or if the property is read-only. */int mii_m_setprop(mii_handle_t *mii, const char *name, mac_prop_id_t id,    uint_t sz, const void *val);/* * mii_m_getstat * *	Used to support the driver's mc_getstat() mac callback for *	statistic collection, and only to be called from that function *	(without any locks held).  This routine will process all of *	the statistics that are relevant to MII on behalf of the *	driver. * * Arguments * * 	mii		MII handle. *	stat		Statistic number. *	val		Location to receive statistic value. * * Returns * *	0 on successful handling of statistic. *	ENOTSUP	if the statistic is not supported by MII. */int mii_m_getstat(mii_handle_t *mii, uint_t stat, uint64_t *val);#endif	/* _KERNEL */#ifdef	__cplusplus}#endif#endif /* _SYS_MII_H */