milan-avb: mrp: do not apply RX_LVA to own attributes when transmitting LeaveAll

This commit is contained in:
hackerman-kl 2026-05-27 09:55:22 +00:00 committed by Wim Taymans
parent 1f969b51a8
commit 7c4fc7027b

View file

@ -108,11 +108,19 @@ static void mrp_periodic(void *data, uint64_t now)
if (now > mrp->lva_timer.leave_all_timeout) { if (now > mrp->lva_timer.leave_all_timeout) {
/* 802.1Q-2014 Table 10-5 */ /* IEEE 802.1Q-2018 §10.7.5.20: when our LeaveAll timer fires, we
* become the TRANSMITTER of LeaveAll. Mark lva_tx_pending so the
* next TX cycle includes the LVA PDU. We must NOT apply RX_LVA to
* our own attributes per Table 10-4 the registrar transitions
* INLV only on RECEIVED LV/LVA, not on our own transmission.
* The old global_event(RX_LVA) here flipped our own SR-class
* Domain registrars to LV for a full 1 s leave_timeout window,
* during which the talker reads our Domain as "leaving" and
* reports MSRP TalkerFailed (failure_code 13). That broke the
* stream every 1015 s. */
mrp->lva_timer.state = FSM_LVA_ACTIVE; mrp->lva_timer.state = FSM_LVA_ACTIVE;
if (mrp->lva_timer.leave_all_timeout > 0) { if (mrp->lva_timer.leave_all_timeout > 0) {
mrp->lva_tx_pending = true; mrp->lva_tx_pending = true;
global_event(mrp, now, AVB_MRP_EVENT_RX_LVA);
leave_all = true; leave_all = true;
} }
} }
@ -435,7 +443,6 @@ void avb_mrp_attribute_update_state(struct avb_mrp_attribute *attr, uint64_t now
break; break;
case AVB_MRP_EVENT_RX_LV: case AVB_MRP_EVENT_RX_LV:
case AVB_MRP_EVENT_RX_LVA: case AVB_MRP_EVENT_RX_LVA:
case AVB_MRP_EVENT_TX_LVA:
case AVB_MRP_EVENT_REDECLARE: case AVB_MRP_EVENT_REDECLARE:
switch (state) { switch (state) {
case AVB_MRP_IN: case AVB_MRP_IN:
@ -444,6 +451,13 @@ void avb_mrp_attribute_update_state(struct avb_mrp_attribute *attr, uint64_t now
break; break;
} }
break; break;
case AVB_MRP_EVENT_TX_LVA:
/* IEEE 802.1Q-2018 Table 10-4: TX events do NOT trigger
* registrar transitions. The previous code lumped TX_LVA with
* RX_LVA and so transitioned our own registrar INLV for the
* full 1 s leave_timeout, briefly hiding the peer's attribute
* from upper layers. Leave the registrar untouched on TX_LVA. */
break;
case AVB_MRP_EVENT_FLUSH: case AVB_MRP_EVENT_FLUSH:
switch (state) { switch (state) {
case AVB_MRP_LV: case AVB_MRP_LV: