net: ps2: PlayStation 2 SMAP Ethernet driver - #95
Closed
hubix94 wants to merge 5 commits into
Closed
Conversation
iop_rpc_write() sends its { addr, type, data } argument with rpo_get_addr
(3) instead of rpo_set_addr (2). LOADFILE therefore performs a read at
addr, discards data, and returns the current value, which iop_rpc_write()
passes on as a non-negative "status". Every caller that tests for err < 0
sees success while nothing has been written.
Measured on an SCPH-30004 (ROM 0150) by replaying the exp_dev_init()
sequence from iop-dev9.c through iop_writel()/iop_writew() and reading the
registers back over the SIF: with rpo_get_addr all writes "succeed" and
the SSBUS registers 0x1418/0x141c/0x1420 keep their reset values
000000ff/001a1055/000510ff and DEV9 power stays 0000; with rpo_set_addr
the same sequence reads back e01a3043/ef1a3043/00051011 and DEV9 power
becomes 0005, the expansion bay powers up and the SPEED chip answers.
Nothing in the tree besides the dead code in iop_dev9_init() calls the
write helpers yet, which is why this went unnoticed.
Fixes: 2e3a838 ("FIXME: iop_read[bwl] and iop_write[bwl]")
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Hubert Wyrzykiewicz <h.wyrzyk@gmail.com>
iop_dev9_init() returns right after iop_module_request("dev9", ...),
leaving exp_dev_init() -- the SSBUS setup, bay power-up and reset -- as
dead code. The expansion bay therefore stays unpowered and the SPEED chip
(ATA and SMAP Ethernet) is unreachable: a read of its registers from the
EE at 0xb4000000 raises a data bus error.
Remove the early return so the module does what it was written to do.
Together with the iop_rpc_write() fix this brings the bay up at module
load. Measured on an SCPH-30004 (ROM 0150): DEV9 power register 0000 ->
0005, SPEED rev1 0011 rev3 0003 rev8 0002, EMAC3 soft reset completes,
PHY DP83846 rev 3 answers on MII address 1 and reports link up at 100 Mbit
full duplex with a cable plugged in and link down without, the MAC
address reads from the serial EEPROM with a matching checksum, and the
EE can read the SPEED registers directly once the bay is powered.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Hubert Wyrzykiewicz <h.wyrzyk@gmail.com>
The SMAP part of the SPEED chip in the PlayStation 2 expansion bay is an IBM EMAC3 MAC with a National DP83846 PHY on MII address 1, a 4 KiB TX FIFO, a 16 KiB RX FIFO and two rings of 64 buffer descriptors, all memory-mapped at physical 0x14000000 on the EE side. The window answers once the DEV9 expansion bay is powered; the driver checks that through the IOP before it touches the window, because an unpowered bay turns every EE access into a data bus error. The register layout, the FIFO and buffer-descriptor protocol, the EMAC3 defaults and the EEPROM bit-bang sequence come from Sony's driver in the PlayStation 2 Linux kit, linux-2.4.17/drivers/ps2/smap.c, GPL v2. The driver structure is new for 5.4: net_device_ops, NAPI, and phylib with its own MDIO bus instead of the original link-check thread. Data moves by programmed I/O, 32-bit accesses through a bounce buffer because skb data is only 2-byte aligned. The IOP-side DMA of the original driver is not ported. Measured on an SCPH-30004 over TCP with SSH on top: 2.4 MB/s transmit and 1.4 MB/s receive, sustained over 300 MB. The three SPEED interrupts reach the EE through the IOP interrupt relay. Because the SPEED interrupt mask register belongs to the IOP, the driver never touches it and acknowledges its sources through SMAP_INTR_CLR, as the original did. It also clears TXDNV and RXDNV, which the IOP side does not acknowledge; left standing they keep the interrupt line asserted and the interface stops receiving interrupts under load. A poll parameter selects interrupt mode with a polling fallback (default), interrupts only, or polling only. The fallback exists because the interrupt relay for a bay device had never been exercised, and an interrupt-only driver that stays silent says nothing about whether the data path works. Signed-off-by: Hubert Wyrzykiewicz <h.wyrzyk@gmail.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add the platform device the SMAP driver binds to: the 16 KiB SPEED register window at physical 0x14000000, which holds the registers, both FIFO data ports and the two buffer descriptor rings, and the three interrupts relayed from the IOP, named rx, tx and emac3 so the driver does not depend on their order. Enable the driver as a module in ps2_defconfig. Signed-off-by: Hubert Wyrzykiewicz <h.wyrzyk@gmail.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Restarting the machine resets the I/O processor, and with it the DEV9 expansion bay: the SPEED register window stops answering and every access from the EE raises a data bus error. The driver's watchdog timer walks into that half a second later, in interrupt context: reboot: Restarting system Data bus error, epc == c0024020, ra == c0024398 epc : readw+0x8/0x18 [ps2_smap] ra : smap_timer_fn+0x44/0x1bc [ps2_smap] Kernel panic - not syncing: Fatal exception in interrupt Add a shutdown callback that closes the interface while the hardware is still there to be closed, the way ohci-ps2 has always done through usb_hcd_platform_shutdown(). device_shutdown() runs it before the machine is restarted, so the timer is stopped, the interrupts are released and the MACs are disabled before anything touches the bay. Signed-off-by: Hubert Wyrzykiewicz <h.wyrzyk@gmail.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
|
Closed in favour of #96. The commits needed their authorship metadata corrected, and that changes every commit ID, so opening a fresh pull request was cleaner than force-pushing under this one. Same code and same measurements - the only difference is a dropped copyright line, since the driver is a port of Sony's. Sorry for the noise. |
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.
Follow-up to #94, as agreed there. The two DEV9 fixes come back as part of the
work they were written for, with the network driver on top.
What this is
An EE-side port of Sony's
linux-2.4.17/drivers/ps2/smap.c(GPL v2, taken fromthe BlackRhino kit, cross-checked against the 2.2.1 driver on the PlayStation 2
Linux DISC2) onto 5.4. Sony's are the register layout, the FIFO and
buffer-descriptor protocol, the EMAC3 default values and the EEPROM bit-bang
sequence. New for 5.4 is the structure:
net_device_ops, NAPI, phylib with itsown MDIO bus instead of the original link-check thread, and
netdev_alloc_skb_ip_align().Five commits:
MIPS: PS2: IOP: Fix iop_write{b,w,l}() issuing the LOADFILE read RPCMIPS: PS2: IOP: Actually initialise the DEV9 expansion bayexp_dev_init()as dead codenet: ps2: Add PlayStation 2 SMAP Ethernet driverdrivers/net/ethernet/ps2/, own Kconfig and MakefileMIPS: PS2: Register the SMAP Ethernet deviceCONFIG_PS2_SMAP=minps2_defconfignet: ps2: Close the interface on machine shutdown.shutdown; without it, resetting the IOP panics the kernel in the driver's timerThe chip window is shared with the ATA registers, so the platform device
declares the two ranges SMAP actually uses rather than the whole window.
Claiming all of it collides with the ATA device registered a few lines earlier,
and the SMAP device then never registers at all. On hardware:
Measured on hardware
SCPH-30004 (PAL, ROM 0150), Network Adaptor in the expansion bay, over TCP with
SSH on top, so the figures include encryption on the same CPU:
rx_errors 0 tx_errors 0, and on close:29115 rx, 26504 tx, 41402 interrupts, 30539 dnv cleared, ran on interruptsrmmod+insmodworks without rebooting the consolemodprobe pata_ps2with the network upata1: PATA max UDMA/66 irq 110, network untouched, 2.23 MB/s against 2.32 without itThe transmit, receive, reload and interrupt figures above were re-measured on
exactly the commits in this branch. The 367 MB run and the
pata_ps2test arefrom a build a day older whose driver differs only in comment wrapping.
Two details from that testing that may be worth knowing regardless of this
driver's fate:
ata.irxfinds the bay already powered byiop-dev9(power is already on)and skips its own sequence, and the interrupts are disjoint - 110 for ATA
against 114/115/116 for SMAP. That is why the two coexist.
poweroff -fstill works with the bay powered on, at least on this model.reboot / halt / shutdown support #67 suggested it might not.
On your comments in #94
An IOP counterpart: agreed, and not written yet. This is the EE-only
prototype you called a good starting point, and everything it does over the SIF
is a candidate to move to the IOP later - DEV9 initialisation the way
ata.cdoes it, interrupt handling, and eventually DMA, which is what the throughput
figures above are really costing.
Retiring
drivers/ps2/iop-dev9.c: yes, once the IOP module exists. Thedriver needs the bay powered before it touches the register window; today
iop-dev9is the only thing in the tree that does it at boot. Asmap.irxwithits own
dev9_init()would take that over and the file could go. Until then thesecond commit here keeps it working rather than deepening the dependency - it
deletes a
return 0;, nothing more.The interrupt relay. Understood, and it matches what the driver ran into:
with no
irq_mask/irq_unmaskiniop-irq.cthe driver cannot mask its ownsource for the duration of a NAPI poll, so it acknowledges through
SMAP_INTR_CLRand relies on the IOP re-arming. It works, and one thing thatsurprised me is worth recording: the IOP clears only
STAT & MASK, so theTXDNV/RXDNVbits - which are not in its mask - stay set and hold the linehigh. Clearing them from the EE is what took this driver from dying under load
to surviving 367 MB. Over that run they were set 258323 times.
Known gaps
SmapDmaWrite/SmapDmaReadon theIOP side; this one does 32-bit PIO from the EE through a bounce buffer,
because skb data is only 2-byte aligned.
MDIO address 1 and the register map is the adapter's. SCPH-700xx is untested.
Probe does refuse cleanly on unexpected hardware - it bails out if SPEED
rev1reads0000/ffff, or ifrev3lacks the SMAP capability bit.all-multicast, as the original did.
rx_droppedis not zero, and it rises only wherenetdev_alloc_skb_ip_align()fails, so it is memory pressure on a 32 MBmachine rather than a data-path fault. Under traffic it is small - 60 frames
out of 28529 received, 0.2% - but it is much worse during boot, 101 out of the
first 226 frames, when the machine is down to 9 MB free. A receive path that
recycled buffers instead of allocating one per frame would not care.
pollmoduleparameter. It was written when the relay had never delivered a SPEED interrupt
to the EE and an interrupt-only driver would have said nothing about whether
the data path worked. Since the
TXDNVfix it has not been needed. Happy toremove it if you would rather not carry it.
checkpatch
0 errors and nothing about line length. What is left is 32 of "networking block
comments don't use an empty /* line" - the rest of this tree,
drivers/ps2/iop-dev9.canddrivers/ata/pata_ps2.cincluded, uses theordinary kernel comment style, so I matched the tree rather than the netdev
rule. Say which you would prefer and I will convert them. Sixteen lines still
run past 80 columns, all of them log messages that
Documentation/process/coding-style.rstsays not to break.Provenance
Sony's code is GPL v2 and the file records where each part came from, with the
2.4.17 line numbers for the parts that are ports rather than rewrites.
MODULE_AUTHORcredits Sony alongside me. As in #94, the commits carryCo-Authored-Byfor the AI assistance I use, and the caveat from my firstmessage stands: treat the measurements as solid and anything I say about causes
as a suggestion that may be wrong.
🤖 Generated with Claude Code