feat: implement Table 30 Row-2 evt[2:0] validation — MDIO (8th and last endpoint type) - #162
Merged
Merged
Conversation
…st endpoint type) TC18 §13.5 Table 33 groups 8 RCP endpoint types (ADC, PWM_IN, I2C, LIN, CAN, UART, ISELED, MDIO) into a shared Row-2 evt[2:0] request-side rule. mdio.rs becomes the eighth and last of these to call the shared evtgroup::evt_row2_kind_of predicate, closing out the full Table 30/33 Row-2 evt[2:0] validation rollout (8/8 endpoint types). New pub items (MINOR bump, v5.10.0 -> v5.11.0): - mdio::MdioRequest / mdio::MdioRequest::from_evt_sub_opcode Signature shape: from_evt_sub_opcode takes an already-decoded MdioTransfer (mirroring can::CanRequest/iseled::IseledRequest), not raw byte_msg_payload bytes (unlike i2c/lin/adc/pwm/uart), because MdioTransfer already has its own dedicated decode() entry point. ConfigWrite judgment call: kept the Ok(Self::ConfigWrite) majority precedent (i2c/lin/adc/pwm/uart) rather than following can.rs's/ iseled.rs's Err(RcpError::ConfigWriteNotImplemented) departure. That departure rests on CanDataFrame/IseledFrame making a real structural claim about their bytes that a genuine TC18 §12.7.1 config-write payload cannot honestly satisfy (decode can fail or silently misinterpret unrelated bytes). MdioTransfer::decode is infallible and interprets no structure at all -- every byte slice is a valid MdioTransfer, matching i2c::I2cByteTransfer's own raw pass-through discipline -- so a caller can honestly construct one from a genuine config-write payload with zero misrepresentation. The 'no caller can honestly construct one' pressure that drove CAN's/ISELED's departure does not apply to MDIO. Did not touch: MdioAddressingMode, MdioFunctionalConfig, or any existing MdioTransfer/MdioTransferResult encoding -- this module's own pre-existing 'Divergence note' documents a previously-invented, non-spec-derived Clause 22/45 addressing scheme (the same issue class as ISELED's #71 and cpp-RCP's MDIO #72). This PR is scoped strictly to evt[2:0] classification and does not reinterpret that encoding. Citation drift found (not fixed here, flagged as follow-up): mdio.rs's pre-existing citations for MDIO's own request-format/mdio_mode table cite 'Table 57'/TC18.txt L5676 and 'Figure 42'/TC18.txt L5664; against current TC18.txt these are actually Table 60/L6088 and Figure 43/L6077. Its functional-config citation ('Table 56'/L5639) is actually Table 59/L6061. Same ~400-line/3-number drift class iseled.rs's own v5.10.0 item found. Not corrected here per task scope -- flagged in mdio.rs's own new 'Editorial note: pre-existing §13.7.13 citation drift' section and in CHANGELOG.md. New citations added by this item were independently re-verified against TC18.txt. Also: .fusa-reqs.json REQ-MDIO-007/008, ARCHITECTURE.md Table 30 centralization row update, docs/PUBLIC_API.txt regenerated via cargo +nightly public-api, tests mirroring CAN/ISELED's shape (Reserved 001b-110b rejection, out-of-3-bit-field, never-panics). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: SoundMatt <47545907+SoundMatt@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TC18 §13.5 Table 33 ("EP specific usage of evt-field", TC18.txt L4076-4116) groups 8 RCP endpoint types —
{ADC, PWM_IN, I2C, LIN, CAN, UART, ISELED, MDIO}— into a shared "Row 2"evt[2:0]request-side rule.mdio.rsbecomes the eighth and last of these to call the sharedevtgroup::evt_row2_kind_ofpredicate, closing out the full Table 30/33 Row-2evt[2:0]validation rollout across this crate (8/8 endpoint types), following the pattern established in #155 (I2C pilot), #156 (ADC), #157 (PWM_IN), #158 (LIN), #159 (CAN), #160 (UART), and #161 (ISELED).New
pubitems (MINOR bump,v5.10.0→v5.11.0perdocs/SEMVER.md):mdio::MdioRequest/mdio::MdioRequest::from_evt_sub_opcodeSignature shape
MdioRequest::from_evt_sub_opcodetakes an already-decodedMdioTransfer, not rawbyte_msg_payloadbytes — mirroringcan::CanRequest's/iseled::IseledRequest's own shape rather thani2c::I2cRequest's/lin::LinRequest's/adc::AdcRequest's/pwm::PwmInRequest's/uart::UartRequest's raw-bytes shape.MdioTransferalready has its own dedicated decode entry point (MdioTransfer::decode, pre-existing this item and unchanged by it), so this evt[2:0]-classification entry point does not re-derive that byte-layout logic a second time internally.The ConfigWrite judgment call (this PR's independent decision)
Two precedents exist in this crate:
evt[2:0] == 111b→Ok(Self::ConfigWrite)evt[2:0] == 111b→Err(RcpError::ConfigWriteNotImplemented)— because theirfrom_evt_sub_opcoderequires an already-decoded frame value (CanDataFrame/IseledFrame), and a genuine TC18 §12.7.1 config-write payload cannot be honestly decoded into one:CanDataFrame::decode/IseledFrame::decodeeach make a real structural claim about their bytes (parsedFrameFormat/id/dataorchain_address/command/data), and can fail or silently misinterpret unrelated bytes as if they were a real frame.MDIO's
from_evt_sub_opcodeshares CAN/ISELED's signature shape (already-decoded frame parameter), but I chose to keep theOk(Self::ConfigWrite)precedent, not follow CAN/ISELED's departure. Reasoning:MdioTransfer::decodeis infallible and interprets no structure at all — this module's own pre-existing doc comment already establishes this ("Provenance note: register-access framing is carried opaque"): every byte slice, including an empty one, is a validMdioTransfer, and the type asserts nothing about what itsbytesmean beyond "these are the bytes of this request" — explicitly matchingi2c::I2cByteTransfer's own raw pass-through discipline. A caller can therefore decode a genuine TC18 §12.7.1 config-write payload throughMdioTransfer::decodewith zero information loss and zero misrepresentation, unlike aCanDataFrameorIseledFrame. The "no caller can honestly construct one" pressure that drove CAN's/ISELED's departure simply does not apply to MDIO's own always-valid, opaque-bytes shape. SoMdioRequest::from_evt_sub_opcodefollows the majority precedent:Ok(Self::ConfigWrite), discarding the suppliedMdioTransferfor that arm exactly as I2C discards its raw payload bytes.This is a deliberate, independently-reasoned "third path" — CAN/ISELED's signature, I2C's ConfigWrite semantics — not a mechanical copy of either whole precedent. Full reasoning is in
mdio.rs's own new "Provenance note: evt[2:0] request validation" doc comment section.Every
Reservedsub_opcode value (evt[2:0]in001b..=110b, or any value outside the 3-bit field) is rejected withErr(RcpError::UnsupportedCmd), unchanged from every prior Row-2 endpoint-type module.Confirming the existing MDIO encoding was NOT touched
mdio.rs's own doc comments document a "Divergence note:mdio_modedoes not select Clause 22 vs Clause 45" — a previously-invented, non-spec-derived Clause-22/45-style addressing scheme with no real TC18 basis (the same issue class this crate's own ISELED module documented for issue #71, and MDIO's own cpp-RCP counterpart documented for issue #72). This PR does not touch, "improve", or reinterpretMdioAddressingMode,MdioFunctionalConfig, or any existingMdioTransfer/MdioTransferResultencoding. It is scoped strictly toevt[2:0]request classification — a completely separate concern.Pre-existing citation drift found (flagged, not fixed — separate follow-up)
While independently re-verifying the new TC18.txt citations this item adds, I spot-checked
mdio.rs's existing citations against/Users/matt/Coding/SoundMatt/TC18.txtand found the same class of drift this crate's own ISELED PR (#161) found and flagged (~400 lines, from a stale reference-file version):mdio.rscitesTC18.txtmdio_modefield table)Both the line numbers and the table/figure numbers have drifted (line 5676 in the current
TC18.txtactually falls inside an unrelated ADC/PWM example figure, not MDIO's section at all). I did not correct these pre-existing citations — that is out of scope for this evt[2:0]-classification item, per task instructions — but flagged the drift explicitly inmdio.rs's own new "Editorial note: pre-existing §13.7.13 citation drift" section and inCHANGELOG.md, so it can be tracked as a separate, deliberate follow-up (matching how #161 flagged ISELED's own drift).The two new citations this PR adds (§13.5 Table 33 Row-2, TC18.txt L4085-4092; §13.7.13.3 "MDIO request handling", TC18.txt L6065-6066; Figure 43, TC18.txt L6077) were independently re-verified against
TC18.txtrather than copied from this module's own now-known-stale citations.Verification
cargo build/cargo test: clean, all tests pass (17 new/existingmdio::tests::*including Reserved-range rejection0b001..=0b110, out-of-3-bit-field rejection, and a never-panics sweep over the fullu8range × 3 sample transfers).Reservedarm to returnOk(Self::Plain(MdioTransfer::default()))instead ofErr(RcpError::UnsupportedCmd)—mdio_request_reserved_evt_values_are_rejected_with_unsupported_cmdandmdio_request_values_above_the_3_bit_field_are_also_rejected_with_unsupported_cmdboth failed as expected. Reverted cleanly;cargo testpasses again andgit diffshows no leftover.bash scripts/api-snapshot-check.sh: OK — public API surface matchesdocs/PUBLIC_API.txt(regenerated for real viacargo +nightly public-api --simplified, not hand-patched).rsfusa check --dir .: 0 errors (794 pre-existing warnings/65 infos, unrelated to this change).rsfusa trace --dir .: Total: 628 Traced: 628 Tested: 628 — 100% traced and tested crate-wide, including the two newREQ-MDIO-007/REQ-MDIO-008entries.Not in this PR
Wiring
MdioRequest::from_evt_sub_opcodeintomock::RcServer's actual dispatch —mock::Endpoint's trait signature still does not carry anevtvalue to any implementation at all, the same gap every prior Row-2 endpoint-type module's own item found and left as-is.Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com