staticvoid mm_state_to_cfg(conststruct ethtool_mm_state *state, struct ethtool_mm_cfg *cfg)
{ /* We could also compare state->verify_status against * ETHTOOL_MM_VERIFY_STATUS_DISABLED, but state->verify_enabled * is more like an administrative state which should be seen in * ETHTOOL_MSG_MM_GET replies. For example, a port with verification * disabled might be in the ETHTOOL_MM_VERIFY_STATUS_INITIAL * if it's down.
*/
cfg->verify_enabled = state->verify_enabled;
cfg->verify_time = state->verify_time;
cfg->tx_enabled = state->tx_enabled;
cfg->pmac_enabled = state->pmac_enabled;
cfg->tx_min_frag_size = state->tx_min_frag_size;
}
/* Returns whether a given device supports the MAC merge layer * (has an eMAC and a pMAC). Must be called under rtnl_lock() and * ethnl_ops_begin().
*/ bool __ethtool_dev_mm_supported(struct net_device *dev)
{ conststruct ethtool_ops *ops = dev->ethtool_ops; struct ethtool_mm_state state = {}; int ret = -EOPNOTSUPP;
if (ops && ops->get_mm)
ret = ops->get_mm(dev, &state);
/** * ethtool_mmsv_verify_timer - Timer for MAC Merge verification * @t: timer_list struct containing private info * * Verify the MAC Merge capability in the local TX direction, by * transmitting Verify mPackets up to 3 times. Wait until link * partner responds with a Response mPacket, otherwise fail.
*/ staticvoid ethtool_mmsv_verify_timer(struct timer_list *t)
{ struct ethtool_mmsv *mmsv = timer_container_of(mmsv, t, verify_timer); unsignedlong flags; bool rearm = false;
spin_lock_irqsave(&mmsv->lock, flags);
switch (mmsv->status) { case ETHTOOL_MM_VERIFY_STATUS_INITIAL: case ETHTOOL_MM_VERIFY_STATUS_VERIFYING: if (mmsv->verify_retries != 0) {
ethtool_mmsv_send_mpacket(mmsv, ETHTOOL_MPACKET_VERIFY);
rearm = true;
} else {
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_FAILED;
}
mmsv->verify_retries--; break;
case ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED:
ethtool_mmsv_configure_tx(mmsv, true); break;
default: break;
}
if (rearm) {
mod_timer(&mmsv->verify_timer,
jiffies + msecs_to_jiffies(mmsv->verify_time));
}
staticvoid ethtool_mmsv_apply(struct ethtool_mmsv *mmsv)
{ /* If verification is disabled, configure FPE right away. * Otherwise let the timer code do it.
*/ if (!mmsv->verify_enabled) {
ethtool_mmsv_configure_pmac(mmsv, mmsv->pmac_enabled);
ethtool_mmsv_configure_tx(mmsv, mmsv->tx_enabled);
} else {
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_INITIAL;
mmsv->verify_retries = ETHTOOL_MM_MAX_VERIFY_RETRIES;
if (netif_running(mmsv->dev))
ethtool_mmsv_verify_timer_arm(mmsv);
}
}
/** * ethtool_mmsv_stop() - Stop MAC Merge Software Verification * @mmsv: MAC Merge Software Verification state * * Drivers should call this method in a state where the hardware is * about to lose state, like ndo_stop() or suspend(), and turning off * MAC Merge features would be superfluous. Otherwise, prefer * ethtool_mmsv_link_state_handle() with up=false.
*/ void ethtool_mmsv_stop(struct ethtool_mmsv *mmsv)
{
timer_shutdown_sync(&mmsv->verify_timer);
}
EXPORT_SYMBOL_GPL(ethtool_mmsv_stop);
/** * ethtool_mmsv_link_state_handle() - Inform MAC Merge Software Verification * of link state changes * @mmsv: MAC Merge Software Verification state * @up: True if device carrier is up and able to pass verification packets * * Calling context is expected to be from a task, interrupts enabled.
*/ void ethtool_mmsv_link_state_handle(struct ethtool_mmsv *mmsv, bool up)
{ unsignedlong flags;
ethtool_mmsv_stop(mmsv);
spin_lock_irqsave(&mmsv->lock, flags);
if (up && mmsv->pmac_enabled) { /* VERIFY process requires pMAC enabled when NIC comes up */
ethtool_mmsv_configure_pmac(mmsv, true);
/* New link => maybe new partner => new verification process */
ethtool_mmsv_apply(mmsv);
} else { /* Reset the reported verification state while the link is down */ if (mmsv->verify_enabled)
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_INITIAL;
/* No link or pMAC not enabled */
ethtool_mmsv_configure_pmac(mmsv, false);
ethtool_mmsv_configure_tx(mmsv, false);
}
/** * ethtool_mmsv_event_handle() - Inform MAC Merge Software Verification * of interrupt-based events * @mmsv: MAC Merge Software Verification state * @event: Event which took place (packet transmission or reception) * * Calling context expects to have interrupts disabled.
*/ void ethtool_mmsv_event_handle(struct ethtool_mmsv *mmsv, enum ethtool_mmsv_event event)
{ /* This is interrupt context, just spin_lock() */
spin_lock(&mmsv->lock);
if (!mmsv->pmac_enabled) goto unlock;
switch (event) { case ETHTOOL_MMSV_LP_SENT_VERIFY_MPACKET: /* Link partner has sent verify mPacket */
ethtool_mmsv_send_mpacket(mmsv, ETHTOOL_MPACKET_RESPONSE); break; case ETHTOOL_MMSV_LD_SENT_VERIFY_MPACKET: /* Local device has sent verify mPacket */ if (mmsv->status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED)
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING; break; case ETHTOOL_MMSV_LP_SENT_RESPONSE_MPACKET: /* Link partner has sent response mPacket */ if (mmsv->status == ETHTOOL_MM_VERIFY_STATUS_VERIFYING)
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED; break;
}
staticbool ethtool_mmsv_is_tx_active(struct ethtool_mmsv *mmsv)
{ /* TX is active if administratively enabled, and verification either * succeeded, or was administratively disabled.
*/ return mmsv->tx_enabled &&
(mmsv->status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ||
mmsv->status == ETHTOOL_MM_VERIFY_STATUS_DISABLED);
}
/** * ethtool_mmsv_get_mm() - get_mm() hook for MAC Merge Software Verification * @mmsv: MAC Merge Software Verification state * @state: see struct ethtool_mm_state * * Drivers are expected to call this from their ethtool_ops :: get_mm() * method.
*/ void ethtool_mmsv_get_mm(struct ethtool_mmsv *mmsv, struct ethtool_mm_state *state)
{ unsignedlong flags;
/** * ethtool_mmsv_set_mm() - set_mm() hook for MAC Merge Software Verification * @mmsv: MAC Merge Software Verification state * @cfg: see struct ethtool_mm_cfg * * Drivers are expected to call this from their ethtool_ops :: set_mm() * method.
*/ void ethtool_mmsv_set_mm(struct ethtool_mmsv *mmsv, struct ethtool_mm_cfg *cfg)
{ unsignedlong flags;
/* Wait for the verification that's currently in progress to finish */
ethtool_mmsv_stop(mmsv);
/** * ethtool_mmsv_init() - Initialize MAC Merge Software Verification state * @mmsv: MAC Merge Software Verification state * @dev: Pointer to network interface * @ops: Methods for implementing the generic functionality * * The MAC Merge Software Verification is a timer- and event-based state * machine intended for network interfaces which lack a hardware-based * TX verification process (as per IEEE 802.3 clause 99.4.3). The timer * is managed by the core code, whereas events are supplied by the * driver explicitly calling one of the other API functions.
*/ void ethtool_mmsv_init(struct ethtool_mmsv *mmsv, struct net_device *dev, conststruct ethtool_mmsv_ops *ops)
{
mmsv->ops = ops;
mmsv->dev = dev;
mmsv->verify_retries = ETHTOOL_MM_MAX_VERIFY_RETRIES;
mmsv->verify_time = ETHTOOL_MM_MAX_VERIFY_TIME_MS;
mmsv->status = ETHTOOL_MM_VERIFY_STATUS_DISABLED;
timer_setup(&mmsv->verify_timer, ethtool_mmsv_verify_timer, 0);
spin_lock_init(&mmsv->lock);
}
EXPORT_SYMBOL_GPL(ethtool_mmsv_init);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.