11993af01f
Base: fix P6-driver-new-modules.patch (ed format -> unified diff) for new driver modules (ncq, itr, phy). P6-driver-main-fixes.patch now applies with offset on current upstream source. Relibc: remove stale P5-named-semaphores (upstream has stubs), add P10-stack-size-8mb and P11-getrlimit-getrusage (per-process rlimit table, sysconf integration, getdtablesize fix, null-pointer safety). Kernel: consolidate 29 individual patches into single redbear-consolidated.patch. Userutils: P5-redbear-branding replaces P4-login-rate-limit. Recipe.toml changes now committed so they survive source resets.
194 lines
7.3 KiB
Diff
194 lines
7.3 KiB
Diff
diff --git a/drivers/net/e1000d/src/itr.rs b/drivers/net/e1000d/src/itr.rs
|
|
new file mode 100644
|
|
index 00000000..a0d79a5f
|
|
--- /dev/null
|
|
+++ b/drivers/net/e1000d/src/itr.rs
|
|
@@ -0,0 +1,61 @@
|
|
+use crate::device::Intel8254x;
|
|
+
|
|
+pub const ITR_IMMEDIATE: u32 = 0;
|
|
+pub const ITR_LOW_LATENCY: u32 = 64;
|
|
+pub const ITR_BULK: u32 = 256;
|
|
+pub const ITR_DEFAULT: u32 = 800;
|
|
+
|
|
+#[derive(Clone, Copy, PartialEq)]
|
|
+pub enum ItrState { LowLatency, Moderate, Bulk }
|
|
+
|
|
+pub struct ItrTracker {
|
|
+ state: ItrState,
|
|
+ current_itr: u32,
|
|
+ packets_since_update: u32,
|
|
+}
|
|
+
|
|
+impl ItrTracker {
|
|
+ pub const fn new() -> Self {
|
|
+ Self { state: ItrState::LowLatency, current_itr: ITR_LOW_LATENCY, packets_since_update: 0 }
|
|
+ }
|
|
+ pub fn record_packet(&mut self, bytes: usize) {
|
|
+ self.packets_since_update += 1;
|
|
+ let _ = bytes;
|
|
+ }
|
|
+ pub fn update(&mut self) -> u32 {
|
|
+ let new_state = if self.packets_since_update < 8 { ItrState::LowLatency }
|
|
+ else if self.packets_since_update < 64 { ItrState::Moderate }
|
|
+ else { ItrState::Bulk };
|
|
+ if new_state != self.state {
|
|
+ self.state = new_state;
|
|
+ self.current_itr = match self.state {
|
|
+ ItrState::LowLatency => ITR_LOW_LATENCY,
|
|
+ ItrState::Moderate => ITR_DEFAULT,
|
|
+ ItrState::Bulk => ITR_BULK,
|
|
+ };
|
|
+ }
|
|
+ self.packets_since_update = 0;
|
|
+ self.current_itr
|
|
+ }
|
|
+ pub fn current_itr(&self) -> u32 { self.current_itr }
|
|
+}
|
|
+
|
|
+const E1000_ITR: u32 = 0x00C4;
|
|
+
|
|
+pub fn set_itr(device: &Intel8254x, itr_value: u32) {
|
|
+ unsafe { device.write_reg(E1000_ITR, itr_value); }
|
|
+}
|
|
+
|
|
+pub fn configure_default_itr(device: &Intel8254x) {
|
|
+ set_itr(device, ITR_DEFAULT);
|
|
+}
|
|
+
|
|
+pub fn configure_checksum_offload(device: &Intel8254x) {
|
|
+ let rctl = unsafe { device.read_reg(0x0100) };
|
|
+ unsafe { device.write_reg(0x0100, rctl | (1 << 4)) };
|
|
+}
|
|
+
|
|
+pub fn enable_tso(device: &Intel8254x) {
|
|
+ let tctl = unsafe { device.read_reg(0x0400) };
|
|
+ unsafe { device.write_reg(0x0400, tctl | (1 << 11)) };
|
|
+}
|
|
diff --git a/drivers/net/rtl8168d/src/phy.rs b/drivers/net/rtl8168d/src/phy.rs
|
|
new file mode 100644
|
|
index 00000000..4f9def80
|
|
--- /dev/null
|
|
+++ b/drivers/net/rtl8168d/src/phy.rs
|
|
@@ -0,0 +1,42 @@
|
|
+#[derive(Clone, Copy, PartialEq, Debug)]
|
|
+pub enum ChipVersion { Rtl8168b, Rtl8168c, Rtl8168cp, Rtl8168d, Rtl8168dp, Rtl8168e, Rtl8168evl, Rtl8168f, Rtl8168g, Rtl8168h, Rtl8168ep, Unknown }
|
|
+
|
|
+pub fn identify_chip(rev: u8, mac0: u32, _m1: u32, _m2: u32, _m3: u32, _m4: u32) -> ChipVersion {
|
|
+ match ((mac0 >> 20) & 0x7, rev) {
|
|
+ (0, _) => ChipVersion::Rtl8168b, (1, 0x00..=0x01) => ChipVersion::Rtl8168c, (1, 0x02) => ChipVersion::Rtl8168cp,
|
|
+ (2, _) => ChipVersion::Rtl8168d, (3, r) if r <= 0x02 => ChipVersion::Rtl8168e, (3, _) => ChipVersion::Rtl8168evl,
|
|
+ (4, _) => ChipVersion::Rtl8168f, (5, _) => ChipVersion::Rtl8168g, (6, _) => ChipVersion::Rtl8168h,
|
|
+ (7, _) => ChipVersion::Rtl8168ep, _ => ChipVersion::Unknown,
|
|
+ }
|
|
+}
|
|
+
|
|
+pub mod phy_regs {
|
|
+ pub const BMCR: u32 = 0x00; pub const BMSR: u32 = 0x01; pub const PHYID1: u32 = 0x02; pub const PHYID2: u32 = 0x03;
|
|
+ pub const ANAR: u32 = 0x04; pub const ANLPAR: u32 = 0x05;
|
|
+ pub const BMCR_RESET: u16 = 1 << 15; pub const BMCR_LOOPBACK: u16 = 1 << 14;
|
|
+ pub const BMCR_SPEED_1000: u16 = 1 << 6; pub const BMCR_AUTONEG_ENABLE: u16 = 1 << 12;
|
|
+ pub const BMCR_AUTONEG_RESTART: u16 = 1 << 9; pub const BMCR_DUPLEX: u16 = 1 << 8;
|
|
+ pub const BMSR_AUTONEG_COMPLETE: u16 = 1 << 5; pub const BMSR_LINK_STATUS: u16 = 1 << 2;
|
|
+}
|
|
+
|
|
+pub fn phy_link_up(read: &dyn Fn(u32) -> u16) -> bool { read(phy_regs::BMSR) & phy_regs::BMSR_LINK_STATUS != 0 }
|
|
+
|
|
+pub fn phy_reset(write: &dyn Fn(u32, u16), read: &dyn Fn(u32) -> u16) -> bool {
|
|
+ write(phy_regs::BMCR, phy_regs::BMCR_RESET);
|
|
+ for _ in 0..500 { if read(phy_regs::BMCR) & phy_regs::BMCR_RESET == 0 { return true; } }
|
|
+ false
|
|
+}
|
|
+
|
|
+pub fn phy_init_for_chip(chip: ChipVersion, write: &dyn Fn(u32, u16), _read: &dyn Fn(u32) -> u16) {
|
|
+ match chip {
|
|
+ ChipVersion::Rtl8168g | ChipVersion::Rtl8168h | ChipVersion::Rtl8168ep => {
|
|
+ write(phy_regs::BMCR, phy_regs::BMCR_AUTONEG_ENABLE | phy_regs::BMCR_AUTONEG_RESTART | phy_regs::BMCR_SPEED_1000 | phy_regs::BMCR_DUPLEX);
|
|
+ }
|
|
+ _ => {
|
|
+ write(phy_regs::BMCR, phy_regs::BMCR_AUTONEG_ENABLE | phy_regs::BMCR_AUTONEG_RESTART);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+pub fn set_jumbo_mtu(_write_phy: &dyn Fn(u32, u16), _mtu: u16) {
|
|
+}
|
|
diff --git a/drivers/storage/ahcid/src/ahci/ncq.rs b/drivers/storage/ahcid/src/ahci/ncq.rs
|
|
new file mode 100644
|
|
index 00000000..e08818f0
|
|
--- /dev/null
|
|
+++ b/drivers/storage/ahcid/src/ahci/ncq.rs
|
|
@@ -0,0 +1,72 @@
|
|
+use core::sync::atomic::{AtomicU32, Ordering};
|
|
+
|
|
+pub const NCQ_MAX_DEPTH: usize = 32;
|
|
+
|
|
+pub struct NcqState {
|
|
+ pub sactive: AtomicU32,
|
|
+ pub pending: AtomicU32,
|
|
+}
|
|
+
|
|
+impl NcqState {
|
|
+ pub const fn new() -> Self {
|
|
+ Self { sactive: AtomicU32::new(0), pending: AtomicU32::new(0) }
|
|
+ }
|
|
+ pub fn allocate_tag(&self) -> Option<u32> {
|
|
+ let active = self.pending.load(Ordering::Acquire);
|
|
+ let free = !active;
|
|
+ if free == 0 { return None; }
|
|
+ let tag = free.trailing_zeros();
|
|
+ let mask = 1u32 << tag;
|
|
+ self.pending.fetch_or(mask, Ordering::AcqRel);
|
|
+ self.sactive.fetch_or(mask, Ordering::AcqRel);
|
|
+ Some(tag)
|
|
+ }
|
|
+ pub fn complete_tag(&self, tag: u32) {
|
|
+ let mask = 1u32 << tag;
|
|
+ self.sactive.fetch_and(!mask, Ordering::AcqRel);
|
|
+ self.pending.fetch_and(!mask, Ordering::AcqRel);
|
|
+ }
|
|
+ pub fn has_pending(&self) -> bool { self.pending.load(Ordering::Acquire) != 0 }
|
|
+}
|
|
+
|
|
+pub fn build_ncq_read_fis(tag: u32, lba: u64, count: u16) -> [u32; 5] {
|
|
+ let mut f = [0u32; 5];
|
|
+ f[0] = 0x0000_8027;
|
|
+ f[1] = 0x0060 | ((count as u32 & 0xFF) << 24);
|
|
+ f[2] = (lba as u32 & 0xFF) | (((lba >> 8) as u32 & 0xFF) << 8);
|
|
+ let mid = ((lba >> 16) as u32 & 0xFF) | ((tag & 0x1F) << 3);
|
|
+ f[3] = mid | (((lba >> 24) as u32 & 0xFF) << 8) | (((lba >> 32) as u32 & 0xFF) << 16) | (((lba >> 40) as u32 & 0xFF) << 24);
|
|
+ f[4] = (((count >> 8) as u32 & 0xFF) << 16) | (((count >> 8) as u32 & 0xFF) << 24);
|
|
+ f
|
|
+}
|
|
+
|
|
+pub fn build_ncq_write_fis(tag: u32, lba: u64, count: u16) -> [u32; 5] {
|
|
+ let mut f = build_ncq_read_fis(tag, lba, count);
|
|
+ f[1] = (f[1] & !0xFF00) | 0x6100;
|
|
+ f
|
|
+}
|
|
+
|
|
+pub fn process_ncq_completions(old_sa: u32, new_sa: u32, ncq: &NcqState, completed: &mut [u32; NCQ_MAX_DEPTH]) -> usize {
|
|
+ let mask = old_sa & !new_sa;
|
|
+ if mask == 0 { return 0; }
|
|
+ let mut count = 0;
|
|
+ let mut m = mask;
|
|
+ while m != 0 { let t = m.trailing_zeros(); ncq.complete_tag(t); completed[count] = t; count += 1; m &= m - 1; }
|
|
+ count
|
|
+}
|
|
+
|
|
+pub fn drive_supports_ncq(id: &[u16; 256]) -> bool { id.get(76).map_or(false, |w| w & (1 << 8) != 0) }
|
|
+pub fn ncq_queue_depth(id: &[u16; 256]) -> u32 {
|
|
+ id.get(75).map_or(1, |w| { let d = (w & 0x1F) as u32; if d > 0 { (d + 1).min(NCQ_MAX_DEPTH as u32) } else { 1 } })
|
|
+}
|
|
+
|
|
+pub fn enable_ncq(hba_mem: &crate::ahci::hba::HbaMem, port_idx: usize) {
|
|
+ let port = &hba_mem.ports[port_idx];
|
|
+ let cmd = port.cmd.read();
|
|
+ port.cmd.write(cmd | 1 << 1);
|
|
+}
|
|
+
|
|
+pub fn issue_ncq_command(port: &crate::ahci::hba::HbaPort, tag: u32) {
|
|
+ let ci = port.ci.read();
|
|
+ port.ci.write(ci | (1u32 << tag));
|
|
+}
|